工具箱

缓存、 对象的对象的映射、 博客和更多

Scott Mitchell

改进了分布式缓存的 Web 应用程序性能

对于大多数数据驱动的 Web 应用程序,每个页面将显示不同的数据库中的信息。渚嬪的方式  一个典型的网页,Amazon.com 在将显示一个产品有关的详细信息,并包括用户评论、 相关的产品、 购物者和等等的信息。因此,每当请求 Web 页时,应用程序必须发出一个级联的查询数据库以检索信息页上显示。此"吵闹"Web 应用程序与浅的通信正常行为,但是它不很好地缩放。

缓存是减少负载并改进可伸缩性 dominated 读取-、 数据驱动的 Web 应用程序中,最有效工具。ASP.NET 包括一个内置的缓存 API,使用的内存中的备份存储包含基于时间的 expiries 和文件系统和数据库的依赖项等功能。在企业库可用于 ASP.NET 应用程序,并提供更大灵活性方面的缓存数据存储方式和位置之外的还有缓存应用程序块。但是,缓存应用程序块和 ASP.NET 缓存其缓存数据存储在本地。这将导致在 Web 场环境中的不理想的统计性能因为数据缓存在一台服务器不是服务器场中的其他服务器可以访问。一个选项是将一个服务器场中的指定为集中式的高速缓存服务器,它存储缓存的唯一副本,并在其他共享。但是,此方法引入一个故障是潜在瓶颈的点。

分布式缓存克服了该缺陷的多个本地化的缓存,或借助一个,集中存储缓存。在一个简单地说分布式的缓存复制或者分区在多个更有效地缓存中提供策略 Web 群环境的服务器之间的高速缓存存储区。

各种分布式缓存的工具不可用。最常用的是 memcached (版本 1.2.8),一个免费、 开源的选项创建 Danga 交互式的并使用 LiveJournal、 Wikipedia,和 SourceForge 高配置站点上。Memcached 灯堆栈 (Linux、 Apache,MySQL,PHP) 中具有其根但有社区创建 Windows 端口和.NET 库一起使用 ASP.NET 的会话状态与集成的开放源代码的自定义提供程序类可用。Microsoft 正在自己分布式缓存库,code-named 的"速度,使用在撰写本文时它是一个社区技术预览可用。还有还商业分布式缓存,这样的工具 ScaleOut 会话ScaleOut 软件中的ScaleOut SessionServerNCacheAlachisoft。(NCache 已经过检查在 2007 年 10 月:msdn.microsoft.com/en-us/magazine/cc163343.aspx

若要开始使用分布式缓存工具,您必须首先定义分布式的缓存的拓扑。通过 memcached,您只需启动 memcached 服务或应用程序将存储缓存的数据的那些计算机上指定参数,如鍛戒护琛屽紑鍏冲通过缓存大小。速度和大多数商业产品 Moreprovide 图形用户界面创建和管理拓扑结构和命令行访问。

用于读取和写入分布式缓存模式是与使用 ASP.NET 的内置缓存 API 不不同的。两种类型的缓存可作为一个巨大涓 € 哈希表的缓存中的每个项由一个唯一的字符串引用。在的图 1 中,伪代码显示如何从高速缓存读取数据。当"Get"执行语句时,分布式的缓存库确定,缓存的项存在拓扑中检索数据。请注意,客户端应用程序不能假设数据存在缓存中,因为它可能已过期,已由用户代码或因依赖项,或者被退出因内存限制。而是,客户端应用程序必须始终检查数据是否已从缓存返回。如果没有找到该项目,则它必须是 re-retrieved 然后重新添加到缓存。

图 1 典型的"Get"请求

Function GetUserProfile(UserID)
UserProfile = Cache.Get(
“UserProfile" + UserID)
If UserProfile = NULL Then
UserProfile = _
Database.GetUserProfile(UserID)
Cache.Add("UserProfile" +
UserID, UserProfile)
End If
Return UserProfile
End Function

数据更新时对缓存中的数据的任何引用变得过时。 若要防止显示陈旧数据,必须删除或更新所有缓存的引用。 图 2 包含访问站点的用户更新其配置文件时,将运行的伪代码。 此方法不只更新数据库中的为每个实例中,但也会用新数据更新关联的缓存项目。 用于维护在缓存中的新数据的其他方法包括 expiries 和缓存依赖项。

图 2 典型更新"请求

Function UpdateUserProfile(UserProfile)
Database.UpdateserProfile(UserProfile)
Cache.Update("UserProfile" +
UserProfile.UserID, UserProfile)
End Function

缓存是基本组件中构建一个可伸缩的、 由数据驱动的 Web 应用程序。为大型、 严重堵塞网站的使用网络场,请考虑使用分布式的缓存最大限度地提高性能。提供一个易于使用的 API 使用缓存的 (如 memcached、 速度和其他人的工具和封装维护、 更新和访问分布式的缓存的底层详细信息。

memcached: danga.com/memcached
速度: msdn.microsoft.com/en-us/data/cc655792.aspx

重要博客

大多数的订阅将精力集中在日常的基础使用该技术在该技术博客包括 ASP.NET,AJAX、 Web 设计等。但我还使查找并读取在其他字段中的专家网络日志的一个点。我,方面的专家是一个具有丰富的知识的人员和,更重要的是,现实世界的经验并且可以共享此观点清除和开发人员不是技术 well-versed meaningful―even 的方式。


Udi Dahan 已经博客:udidahan.com/?blog=true

Udi Dahan 调整此说明。Dahan 演讲者培训师,软件体系结构和设计分布式系统的顾问,曾为企业的很多大型的、 面向服务的应用程序上。他在联机资源站点在和中 (请参阅 msdn.microsoft.com/en-us/magazine/dd569749.aspxmsdn.microsoft.com/en-us/magazine/cc663023.aspx) 的 MSDN Magazine其网络日志上共享自己的见解。

如果您没有访问过 Dahan 的网络日志之前,开头,"第一个时间此处?"您将发现那里他最受欢迎的文章、 博客张贴内容、 面试和面向服务的体系结构 (SOA)、 域模型和智能客户端应用程序上的网络广播页 (udidahan.com/first-time-here),。此外签出项目一节 udidahan.com/articles,其中包含指向 Dahan 的发布内容。然后当您准备将实现一个 SOA,检查出 nServiceBus,Dahan 的免费、 开源的消息框架.NET 应用程序。

nServiceBus: nservicebus.com
Udi Dahan 已经博客: udidahan.com/?blog=true

映射对象的对象的一个很有帮助的实用程序

面向对象的应用程序体系结构模型通过对象的使用和面向对象 (如继承、 模块化和封装的原则通过实际的问题域。一个销售点应用程序需要 (如雇员、 客户、 OrderItem 和产品的类。的图 3 显示了如何这些类可能由组成模型一个销售。

图 3 的部件所销售的对象的

public class Sale {
public Employee SalesPerson { get; set; }
public Customer Customer { get; set; }
public IEnumerable<OrderItem> Items {
get; set; }
}
public class OrderItem {
public Product Product { get; set; }
public int Quantity { get; set; }
public decimal Discount { get; set; }
}

此模型的工作应用程序域中也时, 可能会移动域之外的数据的一个较低的比理想模型。 渚嬪的方式  假设我们的应用程序包括公开向商业合作伙伴的销售数据的 Windows Communication Foundation (WCF) 服务。 服务可能返回对象的集合销售对象,这些对象可能包含多我们负责公开的数据。 将员工对象或销售对象中的客户对象可能包含如社会保险号或付款详细信息的敏感信息。 产品构成,OrderItems 可能包含不必要地增大传输负载的大小,并不重要的详细信息。

一种解决这些问题的常用技术是定义数据传输对象 (DTO),如 SalesDTO EmployeeDTO、 CustomerDTO,依此类推。 精确的共享的属性集,则包含这些 DTO。 服务的代码将在内部使用域 models―Sale,雇员并且因此返回数据前的 forth―but,将创建相应的 DTO 它们填充域对象从相应的属性。

域对象写入 DTO 映射代码是非常枯燥。 如果您发现经常编写这样的对象--映射代码,签出版本 0.3.1 AutoMapper。 AutoMapper 是一个免费、 开源的实用程序可以自动映射到另一点达两行代码的一个对象。

启动、 调用 Mapper.CreateMap 方法和指定源和目标类型如下所示:Mapper.CreateMap < SourceType、 DestinationType > ()。 此创建 MappingExpression 对象定义了两个对象类型之间映射。 如果有嵌套的类型 (如中有的图 3),您将在每个类型需要映射一次调用 CreateMap。

创建映射后, 调用 Mapper.Map,并将其传递源对象:Mapper.Map < SourceType、 DestinationType >(sourceObject)。 映射方法返回分配给源中的相应成员及其属性的目标对象的实例。

数字 4 和 5 的 阐释了一个端到端的示例。 图 4 在此示例中定义两个对象:产品和 ProductDTO。 的图 5 显示了从我们的 WCF 服务的代码。 此处我们有一个映射到一个 ProductDTO 对象,以返回到客户端,我们需要的产品对象。 请注意,此映射由 AutoMapper 的映射类,只需两行代码的执行方式。

图 5 AutoMapper Mapper.Map 方法创建一个新的 ProductDTO 对象基于指定的产品

public ProductDTO GetProduct(Guid productId) {
Product product = Product.Load(productId);
// Map Product onto a ProductDTO object
Mapper.CreateMap<Product, ProductDTO>();
ProductDTO productDto =
Mapper.Map<Product, ProductDTO>(product);
return productDto;
}

AutoMapper 还可以映射到另如 ProductDTO 对象的数组中映射一个列表的产品对象的一个类型的集合。

在实际,它始终是不可能有属性的名称或属性类型整齐地行最多源和目标对象类型之间但 AutoMapper 没有问题。用一个代码行,您可以源类型到目标类型以不同的方式命名属性中的项目属性 (或属性)。如果映射的属性类型执行不对齐,AutoMapper 可以自动将在源属性类型转换为目标属性类型如果.NET Framework Framework中有合适的类型转换器。如果没有这样的类型转换器存在,您可以创建自定义的类型转换器。

价格:可用、 打开源

codeplex.com/AutoMapper

Scott Mitchell 作者的大量书籍和 founder 的 4GuysFromRolla.com,是一个用户已被使用 Microsoft Web 技术自 1998 MVP。Mitchell 是独立的顾问、 培训师和编写器。达到他不 Mitchell@4guysfromrolla.com 或通过在 ScottOnWriting.net 他的博客。