新聞中心
實(shí)際情況:

創(chuàng)新互聯(lián)于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元濟(jì)陽做網(wǎng)站,已為上家服務(wù),為濟(jì)陽各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792
1:當(dāng)公司的網(wǎng)站訪問量達(dá)到每天幾十萬IP時(shí),網(wǎng)站服務(wù)器的壓力就非常大,一個(gè)非常簡(jiǎn)單的程序,相鄰的2個(gè)sql語句,在服務(wù)器繁忙時(shí),可能會(huì)過3-5分鐘才能運(yùn)行完畢,甚至更長(zhǎng)時(shí)間。服務(wù)器的硬件配置也已經(jīng)足夠高了,這時(shí)候幾乎無法靠平常的數(shù)據(jù)庫的讀寫,數(shù)據(jù)庫的優(yōu)化來提高程序的性能的。
2:硬盤的轉(zhuǎn)速是有限的,當(dāng)數(shù)據(jù)庫量已經(jīng)很大時(shí),數(shù)據(jù)庫讀取數(shù)據(jù)也耗費(fèi)很多時(shí)間。而且加硬盤相對(duì)比加內(nèi)存條更復(fù)雜一些。
3:當(dāng)數(shù)據(jù)庫的索引優(yōu)化,分區(qū)優(yōu)化都已經(jīng)用完了,數(shù)據(jù)庫的結(jié)構(gòu)也不能隨便修改時(shí),靠數(shù)據(jù)庫優(yōu)化的就遇到了瓶頸了。
4:現(xiàn)在內(nèi)存都比較便宜,服務(wù)器上把能插內(nèi)存條的地方都可以插滿了,但是系統(tǒng)往往不會(huì)用掉所有的內(nèi)存,內(nèi)存空間還是可以有富足。
5:雖然也可以用很多第3方組件來達(dá)到優(yōu)化的目的,但是需要有學(xué)習(xí)成本,有采購成本,再有后期的維護(hù)成本,服務(wù)器的性能同樣也是增加壓力。
6:目前服務(wù)器的壓力已經(jīng)快崩潰了,也比較難提升性能時(shí),再有比較復(fù)雜的權(quán)限計(jì)算,每刷新一個(gè)頁面時(shí),還判斷10次8次以上操作權(quán)限項(xiàng)目,需要更多的I/O時(shí),很可能系統(tǒng)就真的徹底崩潰了。
7:當(dāng)然我們可以在另外購買服務(wù)器,把程序的壓力進(jìn)行分擔(dān),但是我們假設(shè)不購買硬件了,數(shù)據(jù)庫也必須需要用同一個(gè),從同一個(gè)服務(wù)器上的數(shù)據(jù)庫需要讀取數(shù)據(jù)。
在上面的程序環(huán)境下,就是老頑固也需要轉(zhuǎn)變思維了。
1:老頑固都比較難轉(zhuǎn)變思想:
因?yàn)槭聦?shí)擺在眼前,就是老頑固也必須接納緩存的做法了,雖然緩存有時(shí)候很折磨人,但是不靠緩存已經(jīng)很難解決問題了。雖然以前有很多人給我過這樣的建議,都沒放在心上。
2:程序的及時(shí)性思維的轉(zhuǎn)變:
以前寫程序都強(qiáng)調(diào),數(shù)據(jù)設(shè)置發(fā)生了變化程序能馬上顯示出來效果,例如修改了某個(gè)人的權(quán)限設(shè)置后,馬上就生效了。其實(shí)有時(shí)候沒必要那么馬上生效。有必要時(shí)刷新一下緩存,若沒必要用戶下次登錄時(shí)就生效了,頂多若有問題用戶再登錄一次就可以了,權(quán)限設(shè)置又不是每時(shí)每刻都在設(shè)置的,很多時(shí)候設(shè)置好了,半年一年都不用設(shè)置,沒必要過分強(qiáng)調(diào)實(shí)時(shí)性。
其實(shí)程序員都有過度設(shè)計(jì)的問題,用戶權(quán)限方面,我也的確是想的有些過度了,其實(shí)稍微放寬一下,也能滿足正常的日常使用的,頂多加個(gè)刷新緩存的功能,若有必要馬上見效就馬上刷洗一下緩存就可以了。
3:在不提高,就倍很多年輕人徹底超越了:
奔35了,體力腦力都明顯大幅下降,明顯感覺到身邊的年輕人又聰明又能干,這時(shí)候自己再不提高,很容易就徹底走下坡路了。雖然難起領(lǐng)頭羊的作用,但是至少不要被大家徹底甩在后面去了。
4:馬上動(dòng)手改進(jìn)程序:
有了想法了就需要馬上動(dòng)手,架構(gòu)良好的程序都經(jīng)得起重構(gòu)才對(duì),所以一直認(rèn)為自己的程序架構(gòu)是非常良好的,那就應(yīng)該能經(jīng)得起修改才對(duì),架構(gòu)好的程序應(yīng)該不是全盤推倒從來,而是小修改幾個(gè)函數(shù)就應(yīng)該能達(dá)到內(nèi)存緩存的目的。
5:新系統(tǒng)要上線要靠譜的測(cè)試確認(rèn):
程序更新上去后,前后至少要測(cè)試1周,各種功能都穩(wěn)定,數(shù)據(jù)都正確才能正式投入實(shí)際實(shí)用。
接著就是程序修改的部分:
其實(shí)總共就寫了300行不到的代碼,系統(tǒng)的本質(zhì)的改造就完成了。
1:用戶能訪問的模塊菜單,用戶擁有的操作權(quán)限項(xiàng),改進(jìn)為泛型。
protected List
protected List
2:當(dāng)用戶需要判斷權(quán)限時(shí),一次性把權(quán)限讀取到Cache緩存中。
3:權(quán)限判斷函數(shù)改進(jìn)為從內(nèi)存Cache緩存進(jìn)行判斷。
4:用戶退出時(shí),把相應(yīng)的內(nèi)存緩存清除掉,減輕內(nèi)存的壓力。
5:寫個(gè)刷新緩存的功能,有需要時(shí),對(duì)所有的緩存進(jìn)行實(shí)時(shí)的刷新。
有時(shí)候代碼也就300行不到還有一大堆是注釋,有一大堆是沒用的,還有一大堆是重復(fù)的,真正有價(jià)值的代碼可能不超過50行,但是里面有蠻多故事,有故事的代碼更有生命力,有故事的代碼就更有賣點(diǎn),有故事的代碼經(jīng)常更經(jīng)得起考驗(yàn),歡迎大家拍磚,大家一起學(xué)習(xí)提高,在交流中不斷修正代碼,不斷提高自己,不斷改進(jìn)錯(cuò)誤,一天比一天強(qiáng)大。
- //-----------------------------------------------------------------
- // All Rights Reserved , Copyright (C) 2012 , Hairihan TECH, Ltd .
- //-----------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using DotNet.Business;
- ///
- /// BasePage
- /// 基礎(chǔ)網(wǎng)頁類
- ///
- /// 修改紀(jì)錄
- ///
- /// 版本:1.0 2012.11.10 JiRiGaLa 整理代碼。
- ///
- /// 版本:1.0
- ///
- ///
JiRiGaLa - ///
2012.11.10 - ///
- ///
- public partial class BasePage : System.Web.UI.Page
- {
- ///
- /// 用戶鎖
- ///
- public static readonly object UserLock = new object();
- #region 常用操作權(quán)限項(xiàng)定義
- ///
- /// 訪問權(quán)限
- ///
- protected bool permissionAccess = true;
- ///
- /// 新增權(quán)限
- ///
- protected bool permissionAdd = true;
- ///
- /// 編輯權(quán)限
- ///
- protected bool permissionEdit = true;
- ///
- /// 刪除權(quán)限
- ///
- protected bool permissionDelete = true;
- ///
- /// 查詢權(quán)限
- ///
- protected bool permissionSearch = true;
- ///
- /// 管理權(quán)限
- ///
- protected bool permissionAdmin = false;
- ///
- /// 導(dǎo)出權(quán)限
- ///
- protected bool permissionExport = true;
- ///
- /// 導(dǎo)入權(quán)限
- ///
- protected bool permissionImport = true;
- ///
- /// 打印權(quán)限
- ///
- protected bool permissionPrint = true;
- #endregion
- // 用戶是否在某個(gè)角色里(按編號(hào),按名稱的)
- #region public bool UserIsInRole(string roleCode)
- ///
- /// 用戶是否在某個(gè)角色里
- ///
- /// 角色編號(hào)
- ///
是否在某個(gè)角色里 - public bool UserIsInRole(string roleCode)
- {
- BaseUserManager userManager = new BaseUserManager(this.UserCenterDbHelper, userInfo);
- return userManager.IsInRoleByCode(this.UserInfo.Id, roleCode);
- }
- #endregion
- // 用戶操作權(quán)限常用判斷函數(shù)
- #region public void Authorized(string permissionItemCode, string accessDenyUrl = null) 是否有相應(yīng)權(quán)限,同時(shí)若沒權(quán)限會(huì)重新定位到某個(gè)頁面
- ///
- /// 是否有相應(yīng)權(quán)限,同時(shí)若沒權(quán)限會(huì)重新定位到某個(gè)頁面
- ///
- /// 權(quán)限編號(hào)
- /// 訪問被阻止的url
- public void Authorized(string permissionItemCode, string accessDenyUrl = null)
- {
- // 若沒有相應(yīng)的權(quán)限,那就跳轉(zhuǎn)到?jīng)]有權(quán)限的頁面里
- if (!Utilities.UserIsLogOn() || !IsAuthorized(permissionItemCode))
- {
- if (!string.IsNullOrEmpty(accessDenyUrl))
- {
- HttpContext.Current.Response.Redirect(accessDenyUrl);
- }
- else
- {
- HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage + "?PermissionItemCode=" + permissionItemCode);
- }
- }
- }
- #endregion
- #region public bool IsAuthorized(string permissionItemCode, string permissionItemName = null) 是否有相應(yīng)的權(quán)限
- ///
- /// 是否有相應(yīng)的權(quán)限
- ///
- /// 權(quán)限編號(hào)
- ///
是否有權(quán)限 - public bool IsAuthorized(string permissionItemCode, string permissionItemName = null)
- {
- return IsAuthorized(this.UserInfo.Id, permissionItemCode, permissionItemName);
- }
- public bool IsAuthorized(string userId, string permissionItemCode, string permissionItemName = null)
- {
- // 是否從服務(wù)器緩存讀取用戶權(quán)限
- bool fromCache = true;
- if (fromCache)
- {
- // 這里也可以優(yōu)化一下,沒必要遍歷所有的操作權(quán)限列表
- int count = this.PermissionItemList.Count(entity => !string.IsNullOrEmpty(entity.Code) && entity.Code.Equals(permissionItemCode, StringComparison.OrdinalIgnoreCase));
- return count > 0;
- }
- // 實(shí)時(shí)從數(shù)據(jù)庫讀取操作權(quán)限的設(shè)置方法
- DotNetService dotNetService = new DotNetService();
- return dotNetService.PermissionService.IsAuthorizedByUser(this.UserInfo, userId, permissionItemCode, permissionItemName);
- }
- #endregion
- #region protected void GetPermissionItemList() 獲用戶擁有的操作權(quán)限列表
- ///
- /// 獲用戶擁有的操作權(quán)限列表
- ///
- protected void GetPermissionItemList()
- {
- // 這里是控制用戶并發(fā)的,減少框架等重復(fù)讀取數(shù)據(jù)庫的效率問題
- lock (BasePage.UserLock)
- {
- string cacheKey = "P" + this.UserInfo.Id;
- if (HttpContext.Current.Session == null || Cache[cacheKey] == null)
- {
- // 這個(gè)是默認(rèn)的系統(tǒng)表名稱
- DotNetService dotNetService = new DotNetService();
- PermissionItemList = dotNetService.PermissionService.GetPermissionItemListByUser(this.UserInfo, this.UserInfo.Id);
- }
- }
- }
- #endregion
- #region protected List
PermissionItemList 獲用戶擁有的操作權(quán)限列表 - ///
- /// 獲用戶擁有的操作權(quán)限列表
- ///
- protected List
PermissionItemList - {
- get
- {
- lock (BasePage.UserLock)
- {
- // 這里進(jìn)行了操作權(quán)限優(yōu)化,出錯(cuò)問題
- this.GetPermissionItemList();
- }
- string cacheKey = "P" + this.UserInfo.Id;
- return Cache[cacheKey] as List
; - }
- set
- {
- string cacheKey = "P" + this.UserInfo.Id;
- Cache[cacheKey] = value;
- }
- }
- #endregion
- // 用戶模塊菜單權(quán)限判斷常用函數(shù)
- #region public void ModuleAuthorized(string moduleCode, string accessDenyUrl = null) 是否有相應(yīng)的模塊權(quán)限,同時(shí)若沒權(quán)限會(huì)重新定位到某個(gè)頁面
- ///
- /// 是否有相應(yīng)的模塊權(quán)限,同時(shí)若沒權(quán)限會(huì)重新定位到某個(gè)頁面
- ///
- /// 模塊編號(hào)
- /// 訪問被阻止的url
- public void ModuleAuthorized(string moduleCode, string accessDenyUrl = null)
- {
- // 若沒有相應(yīng)的權(quán)限,那就跳轉(zhuǎn)到?jīng)]有權(quán)限的頁面里
- if (!Utilities.UserIsLogOn() || !IsModuleAuthorized(moduleCode))
- {
- if (!string.IsNullOrEmpty(accessDenyUrl))
- {
- HttpContext.Current.Response.Redirect(accessDenyUrl);
- }
- else
- {
- HttpContext.Current.Response.Redirect(Utilities.AccessDenyPage + "?ModuleCode=" + moduleCode);
- }
- }
- }
- #endregion
- #region public bool IsModuleAuthorized(string moduleCode) 是否有相應(yīng)的模塊權(quán)限
- ///
- /// 是否有相應(yīng)的模塊權(quán)限
- ///
- /// 模塊編號(hào)
- ///
是否有權(quán)限 - public bool IsModuleAuthorized(string moduleCode)
- {
- if (this.UserInfo.IsAdministrator)
- {
- return true;
- }
- // 這里也可以優(yōu)化一下,沒必要遍歷所有的模塊列表
- int count = this.ModuleList.Count(entity => !string.IsNullOrEmpty(entity.Code) && entity.Code.Equals(moduleCode, StringComparison.OrdinalIgnoreCase));
- return count > 0;
- }
- #endregion
- #region protected void GetModuleList() 獲用戶有訪問權(quán)限的模塊列表
- ///
- /// 獲用戶有訪問權(quán)限的模塊列表
- ///
- protected void GetModuleList()
- {
- // 這里是控制用戶并發(fā)的,減少框架等重復(fù)讀取數(shù)據(jù)庫的效率問題
- lock (BasePage.UserLock)
- {
- string cacheKey = "M" + this.UserInfo.Id;
- if (HttpContext.Current.Session == null || Cache[cacheKey] == null)
- {
- // 這個(gè)是默認(rèn)的系統(tǒng)表名稱
- DotNetService dotNetService = new DotNetService();
- ModuleList = dotNetService.PermissionService.GetModuleListByUser(this.UserInfo, this.UserInfo.Id);
- }
- }
- }
- #endregion
- #region protected List
ModuleList 獲用戶有訪問權(quán)限的模塊列表 - ///
- /// 獲用戶有訪問權(quán)限的模塊列表
- ///
- protected List
ModuleList - {
- get
- {
- lock (BasePage.UserLock)
- {
- // 這里進(jìn)行了菜單優(yōu)化,出錯(cuò)問題
- this.GetModuleList();
- }
- string cacheKey = "M" + this.UserInfo.Id;
- // return Utilities.GetFromSession("UserModuleList") as List
; - return Cache[cacheKey] as List
; - }
- set
- {
- string cacheKey = "M" + this.UserInfo.Id;
- Cache[cacheKey] = value;
- // Utilities.AddSession("UserModuleList", value);
- }
- }
- #endregion
- }
新聞名稱:調(diào)整程序架構(gòu)的思維記改進(jìn)程序緩存的經(jīng)歷
本文URL:http://fisionsoft.com.cn/article/dhepeho.html


咨詢
建站咨詢
