現在物價雖然高得離譜,但是內存條都白菜價格了,需要調整程序架構的思維“與時俱進” --- 改進系列之一


   寫程序超過10年的企業內部管理系統今年開始總算是徹底走向web網絡編程,但是由於以前的一些老的思想還沒徹底拋棄,導致寫程序的思維有時候還有一些老舊。下面從一些思維的轉變開始談起。

   

   實際情況:

     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<BaseModuleEntity> ModuleList

           protected List<BasePermissionItemEntity> 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  ///   <remarks>
 13  ///  BasePage
 14  ///  基礎網頁類
 15  ///  
 16  ///  修改紀錄
 17  ///  
 18  ///     版本:1.0 2012.11.10    JiRiGaLa    整理代碼。
 19  ///     
 20  ///  版本:1.0
 21  ///   <author>   
 22  ///          <name> JiRiGaLa </name>
 23  ///          <date> 2012.11.10 </date>
 24  ///   </author>  
 25  ///   </remarks>
 26  public  partial  class BasePage : System.Web.UI.Page
 27 {
 28      ///   <summary>
 29       ///  用戶鎖
 30       ///   </summary>
 31      public  static  readonly  object UserLock =  new  object();
 32 
 33      #region 常用操作權限項定義
 34 
 35      ///   <summary>
 36       ///  訪問權限
 37       ///   </summary>
 38      protected  bool permissionAccess =  true;
 39 
 40      ///   <summary>
 41       ///  新增權限
 42       ///   </summary>
 43      protected  bool permissionAdd =  true;
 44 
 45      ///   <summary>
 46       ///  編輯權限
 47       ///   </summary>
 48      protected  bool permissionEdit =  true;
 49 
 50      ///   <summary>
 51       ///  刪除權限
 52       ///   </summary>
 53      protected  bool permissionDelete =  true;
 54 
 55      ///   <summary>
 56       ///  查詢權限
 57       ///   </summary>
 58      protected  bool permissionSearch =  true;
 59 
 60      ///   <summary>
 61       ///  管理權限
 62       ///   </summary>
 63      protected  bool permissionAdmin =  false;
 64 
 65      ///   <summary>
 66       ///  導出權限
 67       ///   </summary>
 68      protected  bool permissionExport =  true;
 69 
 70      ///   <summary>
 71       ///  導入權限
 72       ///   </summary>
 73      protected  bool permissionImport =  true;
 74 
 75      ///   <summary>
 76       ///  打印權限
 77       ///   </summary>
 78      protected  bool permissionPrint =  true;
 79 
 80      #endregion
 81     
 82      //  用戶是否在某個角色里(按編號,按名稱的)
 83 
 84      #region public bool UserIsInRole(string roleCode)
 85      ///   <summary>
 86       ///  用戶是否在某個角色里
 87       ///   </summary>
 88       ///   <param name="roleCode"> 角色編號 </param>
 89       ///   <returns> 是否在某個角色里 </returns>
 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      ///   <summary>
101       ///  是否有相應權限,同時若沒權限會重新定位到某個頁面
102       ///   </summary>
103       ///   <param name="permissionItemCode"> 權限編號 </param>
104       ///   <param name="accessDenyUrl"> 訪問被阻止的url </param>
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      ///   <summary>
124       ///  是否有相應的權限
125       ///   </summary>
126       ///   <param name="permissionItemCode"> 權限編號 </param>
127       ///   <returns> 是否有權限 </returns>
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      ///   <summary>
151       ///  獲用戶擁有的操作權限列表
152       ///   </summary>
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<BasePermissionItemEntity> PermissionItemList 獲用戶擁有的操作權限列表
170      ///   <summary>
171       ///  獲用戶擁有的操作權限列表
172       ///   </summary>
173      protected List<BasePermissionItemEntity> 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<BasePermissionItemEntity>;
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      ///   <summary>
197       ///  是否有相應的模塊權限,同時若沒權限會重新定位到某個頁面
198       ///   </summary>
199       ///   <param name="moduleCode"> 模塊編號 </param>
200       ///   <param name="accessDenyUrl"> 訪問被阻止的url </param>
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      ///   <summary>
220       ///  是否有相應的模塊權限
221       ///   </summary>
222       ///   <param name="moduleCode"> 模塊編號 </param>
223       ///   <returns> 是否有權限 </returns>
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      ///   <summary>
238       ///  獲用戶有訪問權限的模塊列表
239       ///   </summary>
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<BaseModuleEntity> ModuleList 獲用戶有訪問權限的模塊列表
257      ///   <summary>
258       ///  獲用戶有訪問權限的模塊列表
259       ///   </summary>
260      protected List<BaseModuleEntity> 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<BaseModuleEntity>;
271              return Cache[cacheKey]  as List<BaseModuleEntity>;
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 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM