asp.net解决高并发的方案

 那啥,最近见了一人叨叨叨的神侃如何处理高并发。竟然聊到服务器矩阵。我当时还没回过神,事后细想,服务器矩阵我也知道口里说说,可是中小企业能玩得起?做为一个程序员不少时候只能用手头资源来制定优化方案。(人生哲理:要警戒夸夸其谈者)html

我收集了下网上提供的处理方式列在这里。虽然我不会无聊到背下来去唬新人,但加深下映象,有个纲目仍是好的。前端

两大点:linux

经过服务器处理高并发nginx

 调整服务器应用程序池中的最大链接数。程序员

1. 调整IIS 7应用程序池队列长度web

由原来的默认1000改成65535。redis

IIS Manager > ApplicationPools > Advanced Settings数据库

Queue Length : 65535windows

2.  调整IIS 7的appConcurrentRequestLimit设置缓存

由原来的默认5000改成100000。

appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000

在%systemroot%/System32/inetsrv/config/applicationHost.config中能够查看到该设置。

3. 调整machine.config中的processModel>requestQueueLimit的设置

由原来的默认5000改成100000。

<configuration>
<system.web>
<processModel requestQueueLimit="100000"/>

4. 修改注册表,调整IIS 7支持的同时TCPIP链接数

由原来的默认5000改成100000。

reg add HKLM/System/CurrentControlSet/Services/HTTP/Parameters /v MaxConnections /t REG_DWORD /d 1000000 

完成上述4个设置,就能够支持10万个同时请求

参见http://www.cnblogs.com/dudu/archive/2009/11/10/1600062.html

  对于DB服务器一样也能够调整最大链接数来作优化。

      在调整优化好最大链接数以后,就只有软硬件负载均衡了。硬件负载均衡可以直接经过智能交换机实现,处理能力强,并且与系统无关,可是价格贵,配置困难,不 能区分实习系统与应用的状态。因此硬件负载均衡适用于一大堆设备,大访问量,简单应用。软件负载均衡是基于系统与应用的,能过更好地根据系统与应用的情况 来分配负载。性价比高。PCL负载均衡软件,Linux下的LVS软件。

程序级别的并发控制:

当两个用户同时访问一个页面,一个用户可能更新的事另外一个用户已经删除的记录。或者,在一个用户加载页面跟他点击删除按钮之间的时间里,另外一个用户修改了这条记录的内容。

ADO.NET 和 Visual Studio .NET 中的并发控制

由于数据结构基于断开的数据,因此 ADO.NET 和 Visual Studio .NET 使用开放式并发。所以,您须要添加业务逻辑,以利用开放式并发解决问题。

若是您选择使用开放式并发,则能够经过两种常规的方法来肯定是否已发生更改:版本方法(实际版本号或日期时间戳)和保存全部值方法。

版本号方法

在版本号方法中,要更新的记录必须具备一个包含日期时间戳或版本号的列。当读取该记录时,日期时间戳或版本号将保存在客户端。而后,将对该值进行部分更新。

处理并发的一种方法是仅当 WHERE 子句中的值与记录上的值匹配时才进行更新。该方法的 SQL 表示形式为:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2
WHERE DateTimeStamp = @origDateTimeStamp

或者,可使用版本号进行比较:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2
WHERE RowVersion = @origRowVersionValue

若是日期时间戳或版本号匹配,则代表数据存储区中的记录未被更改,而且能够安全地使用数据集中的新值对该记录进行更新。若是不匹配,则将返回错误。 您能够编写代码,在 Visual Studio .NET 中实现这种形式的并发检查。您还必须编写代码来响应任何更新冲突。为了确保日期时间戳或版本号的准确性,您须要在表上设置触发器,以便在发生对行的更改 时,对日期时间戳或版本号进行更新。

保存全部值方法

使用日期时间戳或版本号的替代方法是在读取记录时获取全部字段的副本。ADO.NET 中的 DataSet 对象维护每一个修改记录的两个版本:初始版本(最初从数据源中读取的版本)和修改版本(表示用户更新)。当试图将记录写回数据源时,数据行中的初始值将与数 据源中的记录进行比较。若是它们匹配,则代表数据库记录在被读取后还没有通过更改。在这种状况下,数据集中已更改的值将成功地写入数据库。

对于数据适配器的四个命令(DELETE、INSERT、SELECT 和 UPDATE)来讲,每一个命令都有一个参数集合。每一个命令都有用于初始值和当前值(或修改值)的参数。

注意    因为不存在初始记录,添加新记录(INSERT 命令)只须要当前值;移除记录(DELETE 命令)只须要使用初始值来定位要删除的记录。

如下示例显示一个数据集命令的命令文本,该命令更新一个典型的客户表。该命令是为动态 SQL 和开放式并发而指定的。

UPDATE Customers SET CustomerID = @currCustomerID, CompanyName = @currCompanyName, ContactName = @currContactName,
ContactTitle = currContactTitle, Address = @currAddress, City = @currCity,
PostalCode = @currPostalCode, Phone = @currPhone, Fax = @currFax
WHERE (CustomerID = @origCustomerID) AND (Address = @origAddress OR @origAddress IS NULL AND Address IS NULL) AND (City = @origCity OR @origCity IS NULL AND City IS NULL)
AND (CompanyName = @origCompanyName OR @origCompanyName IS NULL AND CompanyName IS NULL) AND (ContactName = @origContactName OR @origContactName IS NULL AND ContactName IS NULL) AND (ContactTitle = @origContactTitle OR @origContactTitle IS NULL AND ContactTitle IS NULL)
AND (Fax = @origFax OR @origFax IS NULL AND Fax IS NULL) AND (Phone = @origPhone OR @origPhone IS NULL AND Phone IS NULL) AND (PostalCode = @origPostalCode OR @origPostalCode IS NULL AND PostalCode IS NULL);
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City,
PostalCode, Phone, Fax
FROM Customers WHERE (CustomerID = @currCustomerID)

请注意,九个 SET 语句参数表示将写入数据库的当前值,而九个 WHERE 语句参数则表示用于定位初始记录的初始值。

前九个 SET 语句参数对应于参数集合中的前九个参数。这些参数会将其 SourceVersion 属性设置为 Current

接着的九个 WHERE 语句参数用于开放式并发。这些占位符对应于参数集合中接着的九个参数,这些参数的每个都将其 SourceVersion 属性设置为 Original

SELECT 语句用于在发生更新后刷新数据集。它是您在“高级 SQL 生成选项”对话框中设置“刷新数据集”选项时生成的。

注意    上面的 SQL 使用命名参数,而 OleDbDataAdapter 命令则使用问号 (?) 做为参数占位符。

默认状况下,若是您在“数据适配器配置向导”中选择“开放式并发”选项,Visual Studio 将为您建立这些参数。此时将由您根据本身的业务要求来添加错误处理代码。ADO.NET 提供了一个 DBConcurrencyException 对象,它返回违反并发规则的行。有关更多信息,请参见处理并发错误

 

经过程序处理高并发

第一,缓存。

System.Web.Caching.Cache缓存  http://www.cnblogs.com/daizhj/archive/2007/08/15/855163.html

Memcached分布式缓存 http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html

缓存分层(本地缓存+Memcached) http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html

Redis架构设计 http://www.cnblogs.com/daizhj/archive/2011/02/21/1959511.html

LLServer架构设计 http://www.cnblogs.com/daizhj/archive/2011/08/26/discuznt_llserver_arch.html

跨站缓存同步 http://www.cnblogs.com/daizhj/archive/2010/06/18/discuznt_memcache_syncdata.html

 

小贴士

Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减小数据库负载,提高性能。具体的介绍能够参考:

Memcached深度分析
http://www.cnblogs.com/luluping/archive/2009/01/14/1375456.html

Redis
redis是一个key-value存储系统。和Memcached相似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。在此基础上,redis支持各类不一样方式的排序。与memcached同样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了master-slave(主从)同步。

http://doc.redisfans.com/

http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html

 

第二,静态文件分开布置

1.将用户上传的附件经过FTP方式传送到另一台服务器上。http://www.cnblogs.com/daizhj/archive/2008/07/28/1254648.html

2.经过SQUID将静态文件缓存分布
使用SQUID作静态前端,将论坛中的大部分静态文件布署或外链到一个新的HTTP连接上,从而给Web服务器减压,提高性能。

http://www.cnblogs.com/daizhj/archive/2010/06/10/1692758.html

 

第三,负载均衡

 

经过以上的方案,Web服务器压力小了,性能也提高了,可是若是遇到更高的并发访问量,单台Web服务器仍是不能知足需求,能够采起负载均衡的方案。

使用了LVS+KEEPALIVED、NGINX等。相关文章以下:

 

 

 

    Discuz!NT负载均衡解决方案(HA)之---LVS(Linux Virtual Server)
    http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html

 

 

 

    Discuz!NT负载均衡解决方案(HA)之---LVS(Linux Virtual Server)

 

    http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html

 

 

 

    Discuz!NT负载均衡方案

 

    http://www.cnblogs.com/daizhj/archive/2010/06/24/1667422.html

 

 

 

    使用的是nginx,使用nginx做为前端负载均衡,这个确实颇有吸引力,有时间能试用下就好。

 

第四,缓解数据库压力

           Discuz!NT数据库读写分离方案

    http://www.cnblogs.com/daizhj/archive/2010/06/21/dbsnap_master_slave_database.html

    全文搜索方案:

    Discuz!NT企业版之Sphinx全文搜索(上)

    http://www.cnblogs.com/daizhj/archive/2010/06/28/discuznt_entlib_sphinx_one.html

 

     Discuz!NT企业版之Sphinx全文搜索(下)

    http://www.cnblogs.com/daizhj/archive/2010/06/30/discuznt_entlib_sphinx_two.html

 

    处理大数据量:

    Discuz!NT千万级数据量上的两驾马车--TokyoCabinet,MongoDB

    http://www.cnblogs.com/daizhj/archive/2010/07/22/1781140.html

 

 

须要掌握的知识

Memcached、Redis、LLServer、SQUID、NGINX、LVS、Sphinx

有windows版本的,也有linux版本。

 

 

 

没有前后,程序员应该根据须要和当下条件选用。

 

 

 

本地测试高并发的工具

测试方法:
本地模拟测试网站高访问高并发采用的测试工具是大名鼎鼎的Loadrunner,这个工具作测试的通常都知道。在代震军的博客中,有如下几篇介绍了经过Loadrunner进行压力并发测试。

当DiscuzNT赶上了Loadrunner(上)
http://www.cnblogs.com/daizhj/archive/2009/09/25/1573926.html

当DiscuzNT赶上了Loadrunner(中) 
http://www.cnblogs.com/daizhj/archive/2009/09/27/1574897.html

当DiscuzNT赶上了Loadrunner(下) 
http://www.cnblogs.com/daizhj/archive/2009/09/27/1575091.html

相关文章
相关标签/搜索