实际情况:1:当公司网站访问量达到每天几十万IP时,网站服务器压力非常大。对于一个非常简单的程序,相邻的两条SQL语句在服务器繁忙时可能需要3-5分钟才能运行完,甚至更长。服务器的硬件配置也足够高。这时候,通过读写普通数据库,优化数据库,几乎不可能提高程序的性能。2:硬盘的速度是有限的。当数据库已经很大时,从数据库中读取数据会花费很多时间。而且加硬盘相对加内存条要复杂一些。3:当数据库的索引优化和分区优化已经用完,不能随便修改数据库的结构时,依赖数据库优化就会遇到瓶颈。4:现在内存比较便宜,服务器上能插内存条的地方都能填满,但是系统往往内存没有用完,内存空间还是很充裕的。5:虽然可以使用很多第三方组件来达到优化的目的,但是有学习成本、采购成本、后期维护成本。服务器的性能也增加了压力。6:目前服务器压力快要崩溃,性能难以提升的时候,权限计算比较复杂。每刷新一个页面,判断10个以上的操作权限项需要8次以上,需要更多的I/O,很可能系统真的会彻底崩溃。7:当然我们可以再买一台服务器来分担程序的压力,但是如果不买硬件的话,数据库也必须用同一台,需要从同一台服务器上的数据库读取数据.在上面的程序环境下,即使是老顽固也需要转变思路。1:老顽固难以回心转意:因为事实摆在面前,即使是老顽固也必须采取缓存的做法。虽然缓存有时候很折磨人,但是没有缓存已经很难解决问题了。虽然之前有很多人给我这样的建议,但我并没有放在心上。2:对程序时效性思维的转变:以前写程序的时候,强调的是当数据设置发生变化时,程序能立即显示出效果。比如修改某个人的权限设置后,会立即生效。事实上,有时并不需要立即生效。必要时刷新缓存。如果不需要的话,会在用户下次登录时生效,顶多出现问题,用户可以重新登录。权限设置不是每时每刻都设置的,很多时候都是设置的,没必要设置半年、一年,也没必要过分强调实时性。其实程序员都有过度设计的问题。在用户权限方面,我确实想多了。其实稍微放松一下也能满足正常的日常使用。顶多加个刷新缓存的功能。如有必要,立即如果有效,则立即刷新缓存。3:不进步,你将完全超越很多年轻人:到了35岁,你的体力和精神力会明显下降,你会明显感觉到身边的年轻人聪明能干。如果此时不提升自己,很容易走下坡路。虽然很难起到领导的作用,但至少不要被大家完全甩在后面。4:立即改进方案:当你有想法时,需要立即着手。一个结构良好的程序是经得起重构的,所以我一直认为自己的程序结构很好,应该是经得起修改的。是的,一个结构良好的程序不应该被完全推翻,但是稍微修改几个函数应该可以达到内存缓存的目的。5:新系统上线需要可靠的测试确认:程序更新后,前后至少要进行1周的测试。各项功能稳定,数据无误,方可正式投入实际使用。然后是程序修改部分:其实一共写了不到300行代码,就完成了系统本质的改造。1:用户可访问的模块菜单,用户拥有的操作权限项,改进为通用。protectedListModuleListprotectedListPermissionItemList2:当用户需要判断权限时,一次性将权限读入Cache。3:改进权限判断功能,从内存缓存中判断。4:当用户退出时,清除相应的内存缓存,减少内存压力。5:写一个刷新缓存的函数,需要的时候实时刷新所有缓存。有时候代码不到300行,注释很多,没用的很多,重复的也很多。真正有价值的代码可能不会超过50行,但是里面的故事还是蛮多的。有故事的代码更有生命力,有故事的代码更有卖点,有故事的代码往往更容易测试,欢迎大家一起拍砖,一起学习提高,在交流中不断修正代码,不断完善自己,和不断改进bug,每天都变得更强大。//----------------------------------------------------------//AllRightsReserved,Copyright(C)2012,HairihanTECH,Ltd.//--------------------------------------------------------------使用系统;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;usingDotNet.Business;///<备注>///BasePage///基础网页类//////修改记录//////版本:1.02012.11.10JiRiGaLa整理了代码。//////版本:1.0//////JiRiGaLa///2012.11.10//////publicpartialclassBasePage:System.Web.UI.Page{//////用户锁///publicstaticreadonlyobjectUserLock=newobject();#region公共操作权限项定义//////访问权限///protectedboolpermissionAccess=true;//////添加权限///protectedboolpermissionAdd=true;//////编辑权限///protectedboolpermissionEdit=true;//////删除权限///protectedboolpermissionDelete=true;//////查询权限///protectedboolpermissionSearch=true;//////管理权限///protectedboolpermissionAdmin=false;//////导出权限///protectedboolpermissionExport=true;//////导入权限///protectedboolpermissionImport=true;//////打印权限//////用户是否处于某个角色//////角色编号///是否在某个角色publicboolUserIsInRole(stringroleCode){BaseUserManageruserManager=newBaseUserManager(this.UserCenterDbHelper,userInfo);returnuserManager.IsInRoleByCode(this.UserInfo.Id,roleCode);}#endregion//常用的用户操作权限判断函数#regionpublicvoidAuthorized(stringpermissionItemCode,stringaccessDenyUrl=null)有对应的权限,如果没有权限,会被迁移到某个页面//////是否有对应的权限,没有权限会被迁移到某个页面//////权限号///访问被阻止urlpublicvoidAuthorized(stringpermissionItemCode,stringaccessDenyUrl=null){//如果没有对应的权限,则跳转到无权限页面if(!Utilities.UserIsLogOn()||!IsAuthorized(permissionItemCode)){if(!string.IsNullOrEmpty(accessDenyUrl)){HttpContext.Current.Response.Redirect(accessDenyUrl);}else{HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage+"?PermissionItemCode="+permissionItemCode);}}}#endregion#regionpublicboolINamesItemsItemAuthorized(stringpermissionItemCodeAuthorizednull)是否是否有相应的权限//////是否有相应的权限//////权限号///是否有permission?publicboolIsAuthorized(stringpermissionItemCode,stringpermissionItemName=null){returnIsAuthorized(this.UserInfo.Id,permissionItemCode,permissionItemName);}publicboolIsAuthorized(stringuserId,stringpermissionItemCode,stringpermissionItemName=从服务器读取/缓存)PermissionsboolfromCache=true;if(fromCache){//这里也可以优化,不需要遍历所有的操作权限列表intcount=this.PermissionItemList.Count(entity=>!string.IsNullOrEmpty(entity.Code)&&entity.Code.Equals(每missionItemCode,StringComparison.OrdinalIgnoreCase));returncount>0;}//实时从数据库中读取操作权限的设置方法DotNetServicedotNetService=newDotNetService();returndotNetService.PermissionService.IsAuthorizedByUser(this.UserInfo,userId,permissionItemCode,permissionItemName);}#endregion#regionprotectedvoidGetPermissionItemList()获取用户拥有的操作权限列表//////获取拥有的操作权限列表bytheuser///protectedvoidGetPermissionItemList(){//这是为了控制用户的并发度,降低框架对数据库重复读取的效率lock(BasePage.UserLock){stringcacheKey="P"+this.UserInfo.Id;if(HttpContext.Current.Session==null||Cache[cacheKey]==null){//这是默认的系统表名DotNetServicedotNetService=newDotNetService();PermissionItemList=dotNetService.PermissionService.GetPermissionItemListByUser(this.UserInfo,this.UserInfo.Id);}}}#endregion#regionprotectedListPermissionItemList获取用户拥有的操作权限列表//////获取方式theuserOperationpermissionlist///protectedListPermissionItemList{get{lock(BasePage.UserLock){//这里优化了操作权限,报错问题this.GetPermissionItemList();}stringcacheKey="P"+this.UserInfo.Id;returnCache[cacheKey]asList;}set{stringcacheKey="P"+this.UserInfo.Id;Cache[cacheKey]=value;}}#endregion//用户模块菜单权限判断常用函数#regionpublicvoidModuleAuthorized(stringmoduleCode,stringaccessDenyUrl=null)是否有对应的模块权限,没有权限则重定位到某个页面//////是否有是对应的模块权限,同时如果没有权限,会重新定位到某个页面//////模块号///访问被屏蔽的urlpublicvoidModuleAuthorized(stringmoduleCode,stringaccessDenyUrl=null){//如果没有相应权限,则跳转到无权限页面if(!Utilities.UserIsLogOn()||!IsModuleAuthorized(moduleCode)){if(!string.IsNullOrEmpty(accessDenyUrl)){HttpContext.Current.Response.Redirect(accessDenyUrl);}else{HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage+"?ModuleCode="+moduleCode);}}}#endregion#regionpublicboolIsModuleAuthorized(string)是否有对应的模块权限//////是否有相应的模块权限//////模块编号///是否有权限publicboolIsModuleAuthorized(stringmoduleCode){if(this.UserInfo.IsAdministrator){returntrue;}//这里也可以优化,不需要遍历所有模块列表intcount=this.ModuleList.Count(entity=>!string.IsNullOrEmpty(entity.Code)&&entity.Code.Equals(moduleCode,StringComparison.OrdinalIgnoreCase));returncount>0;}#endregion#regionprotectedvoidGetModuleList()获取用户可以访问的模块列表//////获取用户可以访问的模块列表to///protectedvoidGetModuleList(){//这是为了控制用户并发,降低框架重复读数据库的效率lock(BasePage.UserLock){stringcacheKey="M"+this.UserInfo.Id;if(HttpContext.Current.Session==null||Cache[cacheKey]==null){//这是默认的系统表名DotNetServicedotNetService=newDotNetService();ModuleList=dotNetService.PermissionService.GetModuleListByUser(this.UserInfo,this.UserInfo.Id);}}}#endregion#regionprotectedListModuleList获取用户有权访问的模块列表//////获取用户可以访问的模块列表///protectedListModuleList{get{lock(BasePage.UserLock){//这里优化了菜单,问题isthis.GetModuleList();}stringcacheKey="M"+this.UserInfo.Id;//returnUtilities.GetFromSession("UserModuleList")asList;returnCache[cacheKey]asList;}set{stringcacheKey="M"+this.UserInfo.Id;Cache[cacheKey]=value;//Utilities.AddSession("UserModuleList",value);}}#endregion}原文链接:http://www.cnblogs.com/jirigala/archive/2012/11/12/2766952.html[编者推荐]图片存储架构学习:缓存,架构师的美女情妇浅谈squid在图片存储架构中的应用企业应用架构模式工作单位模式浅谈大数据的算法与架构网站(2)绝对要知道的八个网页设计趋势