调整程序架构的思维记改进程序缓存的经历

实际情况:

创新互联于2013年开始,是专业互联网技术服务公司,拥有项目网站设计、成都网站设计网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元济阳做网站,已为上家服务,为济阳各地企业和个人服务,联系电话:13518219792

1:当公司的网站访问量达到每天几十万IP时,网站服务器的压力就非常大,一个非常简单的程序,相邻的2个sql语句,在服务器繁忙时,可能会过3-5分钟才能运行完毕,甚至更长时间。服务器的硬件配置也已经足够高了,这时候几乎无法靠平常的数据库的读写,数据库的优化来提高程序的性能的。

2:硬盘的转速是有限的,当数据库量已经很大时,数据库读取数据也耗费很多时间。而且加硬盘相对比加内存条更复杂一些。

3:当数据库的索引优化,分区优化都已经用完了,数据库的结构也不能随便修改时,靠数据库优化的就遇到了瓶颈了。

4:现在内存都比较便宜,服务器上把能插内存条的地方都可以插满了,但是系统往往不会用掉所有的内存,内存空间还是可以有富足。

5:虽然也可以用很多第3方组件来达到优化的目的,但是需要有学习成本,有采购成本,再有后期的维护成本,服务器的性能同样也是增加压力。

6:目前服务器的压力已经快崩溃了,也比较难提升性能时,再有比较复杂的权限计算,每刷新一个页面时,还判断10次8次以上操作权限项目,需要更多的I/O时,很可能系统就真的彻底崩溃了。

7:当然我们可以在另外购买服务器,把程序的压力进行分担,但是我们假设不购买硬件了,数据库也必须需要用同一个,从同一个服务器上的数据库需要读取数据。

在上面的程序环境下,就是老顽固也需要转变思维了。

1:老顽固都比较难转变思想:

因为事实摆在眼前,就是老顽固也必须接纳缓存的做法了,虽然缓存有时候很折磨人,但是不靠缓存已经很难解决问题了。虽然以前有很多人给我过这样的建议,都没放在心上。

2:程序的及时性思维的转变:

以前写程序都强调,数据设置发生了变化程序能马上显示出来效果,例如修改了某个人的权限设置后,马上就生效了。其实有时候没必要那么马上生效。有必要时刷新一下缓存,若没必要用户下次登录时就生效了,顶多若有问题用户再登录一次就可以了,权限设置又不是每时每刻都在设置的,很多时候设置好了,半年一年都不用设置,没必要过分强调实时性。

其实程序员都有过度设计的问题,用户权限方面,我也的确是想的有些过度了,其实稍微放宽一下,也能满足正常的日常使用的,顶多加个刷新缓存的功能,若有必要马上见效就马上刷洗一下缓存就可以了。

3:在不提高,就倍很多年轻人彻底超越了:

奔35了,体力脑力都明显大幅下降,明显感觉到身边的年轻人又聪明又能干,这时候自己再不提高,很容易就彻底走下坡路了。虽然难起领头羊的作用,但是至少不要被大家彻底甩在后面去了。

4:马上动手改进程序:

有了想法了就需要马上动手,架构良好的程序都经得起重构才对,所以一直认为自己的程序架构是非常良好的,那就应该能经得起修改才对,架构好的程序应该不是全盘推倒从来,而是小修改几个函数就应该能达到内存缓存的目的。

5:新系统要上线要靠谱的测试确认:

程序更新上去后,前后至少要测试1周,各种功能都稳定,数据都正确才能正式投入实际实用。 

     

接着就是程序修改的部分:

其实总共就写了300行不到的代码,系统的本质的改造就完成了。

1:用户能访问的模块菜单,用户拥有的操作权限项,改进为泛型。

           protected List ModuleList

           protected List PermissionItemList

2:当用户需要判断权限时,一次性把权限读取到Cache缓存中。

3:权限判断函数改进为从内存Cache缓存进行判断。

4:用户退出时,把相应的内存缓存清除掉,减轻内存的压力。

5:写个刷新缓存的功能,有需要时,对所有的缓存进行实时的刷新。

有时候代码也就300行不到还有一大堆是注释,有一大堆是没用的,还有一大堆是重复的,真正有价值的代码可能不超过50行,但是里面有蛮多故事,有故事的代码更有生命力,有故事的代码就更有卖点,有故事的代码经常更经得起考验,欢迎大家拍砖,大家一起学习提高,在交流中不断修正代码,不断提高自己,不断改进错误,一天比一天强大。

 
 
 
 
  1. //----------------------------------------------------------------- 
  2.  // All Rights Reserved , Copyright (C) 2012 , Hairihan TECH, Ltd . 
  3.  //----------------------------------------------------------------- 
  4.   
  5.  using System; 
  6.  using System.Collections.Generic; 
  7.  using System.Linq; 
  8.  using System.Web; 
  9.   
  10.  using DotNet.Business; 
  11.   
  12.  ///  
  13.  /// BasePage 
  14.  /// 基础网页类 
  15.  ///  
  16.  /// 修改纪录 
  17.  ///  
  18.  ///    版本:1.0 2012.11.10    JiRiGaLa    整理代码。 
  19.  ///     
  20.  /// 版本:1.0 
  21.  ///    
  22.  ///        JiRiGaLa 
  23.  ///        2012.11.10 
  24.  ///   
  25.  ///  
  26.  public partial class BasePage : System.Web.UI.Page 
  27.  { 
  28.      ///  
  29.      /// 用户锁 
  30.      ///  
  31.      public static readonly object UserLock = new object(); 
  32.   
  33.      #region 常用操作权限项定义 
  34.   
  35.      ///  
  36.      /// 访问权限 
  37.      ///  
  38.      protected bool permissionAccess = true; 
  39.   
  40.      ///  
  41.      /// 新增权限 
  42.      ///  
  43.      protected bool permissionAdd = true; 
  44.   
  45.      ///  
  46.      /// 编辑权限 
  47.      ///  
  48.      protected bool permissionEdit = true; 
  49.   
  50.      ///  
  51.      /// 删除权限 
  52.      ///  
  53.      protected bool permissionDelete = true; 
  54.   
  55.      ///  
  56.      /// 查询权限 
  57.      ///  
  58.      protected bool permissionSearch = true; 
  59.   
  60.      ///  
  61.      /// 管理权限 
  62.      ///  
  63.      protected bool permissionAdmin = false; 
  64.   
  65.      ///  
  66.      /// 导出权限 
  67.      ///  
  68.      protected bool permissionExport = true; 
  69.   
  70.      ///  
  71.      /// 导入权限 
  72.      ///  
  73.      protected bool permissionImport = true; 
  74.   
  75.      ///  
  76.      /// 打印权限 
  77.      ///  
  78.      protected bool permissionPrint = true; 
  79.   
  80.      #endregion 
  81.       
  82.      // 用户是否在某个角色里(按编号,按名称的) 
  83.   
  84.      #region public bool UserIsInRole(string roleCode) 
  85.      ///  
  86.      /// 用户是否在某个角色里 
  87.      ///  
  88.      /// 角色编号 
  89.      /// 是否在某个角色里 
  90.      public bool UserIsInRole(string roleCode) 
  91.      { 
  92.          BaseUserManager userManager = new BaseUserManager(this.UserCenterDbHelper, userInfo); 
  93.          return userManager.IsInRoleByCode(this.UserInfo.Id, roleCode); 
  94.      } 
  95.      #endregion 
  96.       
  97.      // 用户操作权限常用判断函数 
  98.   
  99.      #region public void Authorized(string permissionItemCode, string accessDenyUrl = null) 是否有相应权限,同时若没权限会重新定位到某个页面 
  100.      ///  
  101.      /// 是否有相应权限,同时若没权限会重新定位到某个页面 
  102.      ///  
  103.      /// 权限编号 
  104.      /// 访问被阻止的url 
  105.      public void Authorized(string permissionItemCode, string accessDenyUrl = null) 
  106.      { 
  107.          // 若没有相应的权限,那就跳转到没有权限的页面里 
  108.          if (!Utilities.UserIsLogOn() || !IsAuthorized(permissionItemCode)) 
  109.          { 
  110.              if (!string.IsNullOrEmpty(accessDenyUrl)) 
  111.              { 
  112.                  HttpContext.Current.Response.Redirect(accessDenyUrl); 
  113.              } 
  114.              else 
  115.              { 
  116.                  HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage + "?PermissionItemCode=" + permissionItemCode); 
  117.              } 
  118.          } 
  119.      } 
  120.      #endregion 
  121.   
  122.      #region public bool IsAuthorized(string permissionItemCode, string permissionItemName = null) 是否有相应的权限 
  123.      ///  
  124.      /// 是否有相应的权限 
  125.      ///  
  126.      /// 权限编号 
  127.      /// 是否有权限 
  128.      public bool IsAuthorized(string permissionItemCode, string permissionItemName = null) 
  129.      { 
  130.          return IsAuthorized(this.UserInfo.Id, permissionItemCode, permissionItemName); 
  131.      } 
  132.   
  133.      public bool IsAuthorized(string userId, string permissionItemCode, string permissionItemName = null) 
  134.      { 
  135.          // 是否从服务器缓存读取用户权限 
  136.          bool fromCache = true; 
  137.          if (fromCache) 
  138.          { 
  139.              // 这里也可以优化一下,没必要遍历所有的操作权限列表 
  140.              int count = this.PermissionItemList.Count(entity => !string.IsNullOrEmpty(entity.Code) && entity.Code.Equals(permissionItemCode, StringComparison.OrdinalIgnoreCase)); 
  141.              return count > 0; 
  142.          } 
  143.          // 实时从数据库读取操作权限的设置方法 
  144.          DotNetService dotNetService = new DotNetService(); 
  145.          return dotNetService.PermissionService.IsAuthorizedByUser(this.UserInfo, userId, permissionItemCode, permissionItemName); 
  146.      } 
  147.      #endregion 
  148.   
  149.      #region protected void GetPermissionItemList() 获用户拥有的操作权限列表 
  150.      ///  
  151.      /// 获用户拥有的操作权限列表 
  152.      ///  
  153.      protected void GetPermissionItemList() 
  154.      { 
  155.          // 这里是控制用户并发的,减少框架等重复读取数据库的效率问题 
  156.          lock (BasePage.UserLock) 
  157.          { 
  158.              string cacheKey = "P" + this.UserInfo.Id; 
  159.              if (HttpContext.Current.Session == null || Cache[cacheKey] == null) 
  160.              { 
  161.                  // 这个是默认的系统表名称 
  162.                  DotNetService dotNetService = new DotNetService(); 
  163.                  PermissionItemList = dotNetService.PermissionService.GetPermissionItemListByUser(this.UserInfo, this.UserInfo.Id); 
  164.              } 
  165.          } 
  166.      } 
  167.      #endregion 
  168.   
  169.      #region protected List PermissionItemList 获用户拥有的操作权限列表 
  170.      ///  
  171.      /// 获用户拥有的操作权限列表 
  172.      ///  
  173.      protected List PermissionItemList 
  174.      { 
  175.          get 
  176.          { 
  177.              lock (BasePage.UserLock) 
  178.              { 
  179.                  // 这里进行了操作权限优化,出错问题 
  180.                  this.GetPermissionItemList(); 
  181.              } 
  182.              string cacheKey = "P" + this.UserInfo.Id; 
  183.              return Cache[cacheKey] as List
  184.          } 
  185.          set 
  186.          { 
  187.              string cacheKey = "P" + this.UserInfo.Id; 
  188.              Cache[cacheKey] = value; 
  189.          } 
  190.      } 
  191.      #endregion 
  192.       
  193.      // 用户模块菜单权限判断常用函数 
  194.   
  195.      #region public void ModuleAuthorized(string moduleCode, string accessDenyUrl = null) 是否有相应的模块权限,同时若没权限会重新定位到某个页面 
  196.      ///  
  197.      /// 是否有相应的模块权限,同时若没权限会重新定位到某个页面 
  198.      ///  
  199.      /// 模块编号 
  200.      /// 访问被阻止的url 
  201.      public void ModuleAuthorized(string moduleCode, string accessDenyUrl = null) 
  202.      { 
  203.          // 若没有相应的权限,那就跳转到没有权限的页面里 
  204.          if (!Utilities.UserIsLogOn() || !IsModuleAuthorized(moduleCode)) 
  205.          { 
  206.              if (!string.IsNullOrEmpty(accessDenyUrl)) 
  207.              { 
  208.                  HttpContext.Current.Response.Redirect(accessDenyUrl); 
  209.              } 
  210.              else 
  211.              { 
  212.                  HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage + "?ModuleCode=" + moduleCode); 
  213.              } 
  214.          } 
  215.      } 
  216.      #endregion 
  217.   
  218.      #region public bool IsModuleAuthorized(string moduleCode) 是否有相应的模块权限 
  219.      ///  
  220.      /// 是否有相应的模块权限 
  221.      ///  
  222.      /// 模块编号 
  223.      /// 是否有权限 
  224.      public bool IsModuleAuthorized(string moduleCode) 
  225.      { 
  226.          if (this.UserInfo.IsAdministrator) 
  227.          { 
  228.              return true; 
  229.          } 
  230.          // 这里也可以优化一下,没必要遍历所有的模块列表 
  231.          int count = this.ModuleList.Count(entity => !string.IsNullOrEmpty(entity.Code) && entity.Code.Equals(moduleCode, StringComparison.OrdinalIgnoreCase)); 
  232.          return count > 0; 
  233.      } 
  234.      #endregion 
  235.   
  236.      #region protected void GetModuleList() 获用户有访问权限的模块列表 
  237.      ///  
  238.      /// 获用户有访问权限的模块列表 
  239.      ///  
  240.      protected void GetModuleList() 
  241.      { 
  242.          // 这里是控制用户并发的,减少框架等重复读取数据库的效率问题 
  243.          lock (BasePage.UserLock) 
  244.          { 
  245.              string cacheKey = "M" + this.UserInfo.Id;  
  246.              if (HttpContext.Current.Session == null || Cache[cacheKey] == null) 
  247.              { 
  248.                  // 这个是默认的系统表名称 
  249.                  DotNetService dotNetService = new DotNetService(); 
  250.                  ModuleList = dotNetService.PermissionService.GetModuleListByUser(this.UserInfo, this.UserInfo.Id); 
  251.              } 
  252.          } 
  253.      } 
  254.      #endregion 
  255.   
  256.      #region protected List ModuleList 获用户有访问权限的模块列表 
  257.      ///  
  258.      /// 获用户有访问权限的模块列表 
  259.      ///  
  260.      protected List ModuleList 
  261.      { 
  262.          get 
  263.          { 
  264.              lock (BasePage.UserLock) 
  265.              { 
  266.                  // 这里进行了菜单优化,出错问题 
  267.                  this.GetModuleList(); 
  268.              } 
  269.              string cacheKey = "M" + this.UserInfo.Id;  
  270.              // return Utilities.GetFromSession("UserModuleList") as List
  271.              return Cache[cacheKey] as List
  272.          } 
  273.          set 
  274.          { 
  275.              string cacheKey = "M" + this.UserInfo.Id; 
  276.              Cache[cacheKey] = value; 
  277.              // Utilities.AddSession("UserModuleList", value); 
  278.          } 
  279.      } 
  280.      #endregion 
  281.  } 

新闻名称:调整程序架构的思维记改进程序缓存的经历
文章URL:http://www.36103.cn/qtweb/news49/21949.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联