解決 Memcached Provider 不支援中文 Cache Key 的問題

前陣子使用 Memcached 當成我們某個 ASP.NET 網站的後端,但只要遇到採用 Non-ASCII 的文字當成快取的鍵值(Key)就會自動消失,經過一番研究後確認是 Memcached Provider 的 DefaultKeyTransformer 在處理所有 memcached 通訊協定時所有的 Key 都是以 Encoding.ASCII 做為文字編碼,以致於所有中文字都無法讀取而自動被忽略,而也在編譯時與執行時期都不會出現任何錯誤,因此必須特別小心。

舉個簡單例子,假設我們有兩個 Cache Key 分別為:

  1. Poll_投票結果
  2. Poll_題目資料

而實際儲存到 memcached 中的 Cache Key 將會是 Poll_ 而已,由於遇到轉型失敗的快取物件都會預設為 null,因此可能會讓你在執行時期也不會發生問題,只是快取機制無法運作導致效能減低而已。

最後,我用以下兩種方式解決:

1. 修改 Memcached Provider 的原始碼,讓 DefaultKeyTransformer.cs 能夠正確處理 UTF8 文字

    修改過的原始碼已經放上 CodePlex,有興趣的人可以去下載並重新編譯。

    但請注意我上傳了兩個版本:

  • 針對目前線上可下載的 Memcached Providers 1.2 在原始碼那邊的 Changeset 是 13951,你應該要先取出 Changeset 13951 的原始碼,再套用 Patch ID = 5104 的修補檔才能編譯出跟 Memcached Providers 1.2 相容的組件!
  • 另一個 Patch ID = 5099 就是原始碼最新版 (Changeset 29520) 的修補檔。

 

2. 選用其他 KeyTransformer 即可正確處理 Cache Key 文字無法轉換的問題

    切換不同的 KeyTransformer 可以參考以下設定,只要修改 web.config 即可:

<enyim.com> 
<memcached
keyTransformer="Enyim.Caching.Memcached.SHA1KeyTransformer, Enyim.Caching">
<servers>
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100"
connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>

相關連結

  

此文章由 will 發表於 2010/3/7 上午 12:34:03

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: ASP.NET | .Net

標籤: , ,

收藏:

透過 logman 指令有效率的操作效能監視器

這個星期都忙碌於一個大型網站的效能調校,而效能調校首重數據分析,透過數據分析進一步瞭解應用程式所遇到的效能瓶頸,最常使用的工具不外乎就是 效能監視器 ( Performance Monitor ),但由於有多台主機,每壹台都要重新選取一次這些 效能計數器 (Performance Counter) 實在很麻煩,所以若能透過指令列工具建立效能監視集合就會十分方便。

備註: 在 Windows Server 2008 的名稱為 可靠性和效能監視器

透過指令列取得所有系統中可用的效能計數器,並另存於文字檔中

typeperf -q -o PerfMon_Counters_All.txt

取得的 PerfMon_Counters.txt 共有數千筆效能計數器物件,如何挑選適當的計數器就是門大學問了,我這裡僅列出與 ASP.NET 相關的計數器如下:

\System\*
\Memory\*
\PhysicalDisk(*)\*
\Process(*)\*
\Processor(*)\*
\Thread(*)\*
\.NET CLR Data(*)\*
\.NET CLR Networking(*)\*
\.NET CLR Memory(*)\*
\.NET CLR Interop(*)\*
\.NET CLR Exceptions(*)\*
\.NET CLR Loading(*)\*
\.NET CLR LocksAndThreads(*)\*
\.NET CLR Jit(*)\*
\.NET CLR Remoting(*)\*
\.NET CLR Security(*)\*
\ASP.NET\*
\ASP.NET Applications(*)\*
\ASP.NET v2.0.50727\*
\ASP.NET Apps v2.0.50727(*)\*
\ASP.NET State Service\*
\Web Service(*)\*

你也可以將以上計數器清單另存成一個文字檔,方便後續載入。

注意: 載入的效能計數器越多對系統的衝擊越大,因此請千萬小心,不要載入過多的效能計數器。

透過指令列建立資料收集器集合工具的使用者定義集合

logman create counter ASP.NET_PerfMon -cf PerfMon_Counters.txt

執行過以上指令後,就會自動在 效能監視器 的 [效能] / [資料收集器集合工具] / [使用者定義] 下方新增一個新的資料即可,如下圖示:

若要修改預設 15 秒的抽樣間隔,可以在建立時多加上 -si 的參數,如下指令為每 60 秒收錄一次效能數據

logman create counter ASP.NET_PerfMon2 -cf PerfMon_Counters.txt -si 60

這個步驟是我覺得最繁瑣的地方,透過指令自動化就會很方便,相較之下其他的指令列參數的用法就變的不那麼重要,可以直接透過 效能監視器 的視窗介面操作比較簡易且直覺,如果有興趣研究其他參數可以執行 logman /? 查詢。

透過指令列啟動剛剛建立的資料收集器

logman start ASP.NET_PerfMon

啟動之後你可以從 效能監視器 的視窗看見該資料集合已經啟動,並開始收集效能數據,如下圖示:

透過指令列停止剛剛建立的資料收集器

logman stop ASP.NET_PerfMon

透過效能監視器查看效能數據報表

由於我收錄的 ASP.NET 相關計數器非常之多,因此你會看到畫面密密麻麻的線條(如下圖點圖可放大)

你也可以考慮將還沒分析到的計數器暫時隱藏 ( 註: 按下 Ctrl + A 可全選 )

也可以點選 選定項目 將選取到的效能計數器特別高亮度顯示

也可以利用不同的檢視查看這些效能數據

 

相關連結

  

此文章由 will 發表於 2010/3/6 下午 07:13:12

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: 介紹好用工具 | ASP.NET

標籤: , , , , , ,

收藏:

將 ASP.NET 網站部署在 UNC 路徑上最重要的步驟

如果要將 ASP.NET 網站安裝在遠端的 UNC 路徑上,在設定 IIS 時除了一般檔案的存取權限外,最重要的就是 ASP.NET 的執行權限是否有正確設定,由於所有置於 UNC 路徑上的 .NET 應用程式都會預設套用 LocalIntranet 群組,所以你無法將 ASP.NET 佈署在 UNC 路徑上,除非自行新增 .NET 安全性原則。

在沒設定 .NET 安全性群組之前,不管你怎麼設定都會出現以下安全性例外狀況的錯誤訊息:

安全性例外狀況 :: 例外詳細資訊: System.Security.SecurityException: 型別 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 的使用權限要求失敗。

SecurityException: Request for the permission of type ‘System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed

 

解決此問題的步驟如下:

1. [開始] / [執行] / 輸入 cmd 並按下 Enter

2. 進入 .Net Framework 的安裝目錄(注意:x86 架構與 x64 架構的目錄並不相同)

    如果是 x64 架構請進入 C:\Windows\Microsoft.NET\Framework64\v2.0.50727

    如果是 x86 架構請進入 C:\Windows\Microsoft.NET\Framework\v2.0.50727

    注意: 如果進入錯誤的路徑,怎麼設定還是無法使用,這取決於你的 .NET 應用程式是跑什麼架構!

3. 執行 CASPOL.exe 工具授權特定 UNC 路徑為「完全信任」,請參考以下指令

caspol -m -ag 1. -url "file://\\server\share\*" FullTrust -exclusive on

  接著畫面會問你是否確認要執行這個動作,它會要你輸入 yes 或 no,但你只能輸入 yn 喔!( 按 y )

  

  我們可以透過 caspol -listgroups 指令驗證此安全性原則是否設定成功:

 

4. 最後去設定 IIS ( IIS6 或 IIS 7 ),如果先前已經設定好請務必記得「回收應用程式集區」才能讓生效!

 

其他補充說明:

1. 如果你不小心新增了兩個重複的 UNC 路徑到 .NET 安全性原則中會造成 ASP.NET 無法執行

   錯誤訊息是: 不允許一個以上的獨佔群組。More than one exclusive group is not allowed.

   System.Security.Policy.PolicyException: 不允許一個以上的獨佔群組。

2. 如果 CASPOL.exe 本身在執行的時候會引發例外(Exception),那可能要重新開機才能解決此問題!

3. 若要移除先前設定的安全性原則,可以參考以下指令:

caspol -rg 1.6

注意:所有 .NET 安全性原則都有個編號,記得先用 caspol -listgroups 列出所有群組,並找出你之前新增的安全性原則編號,然後才能帶入指令中。

 

相關連結

  

此文章由 will 發表於 2010/2/28 下午 12:13:20

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: IIS | ASP.NET | 系統管理

標籤: , , , , , ,

收藏:

解決在 Visual Studio 中因為權限不足而無法建置網站的問題

前陣子遇到一個很怪的問題,在正常的安裝下竟然有個專案從 SVN 版本庫簽出後無法正確安裝至我本機的 IIS7 中執行,甚至於無法在 Visual Studio 執行建置(Build),而且錯誤的狀況都是跟權限有關,但我花了好一段時間才將這個問題解決,原來就是卡在一個很小的地方沒注意到。

這次發生的錯誤訊息如下:

Access to the path 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\Project1\265814f7\8b06370e\App_Code.compiled' is denied.

這代表在 ASP.NET 動態編譯時期就無法完成,因為動態編譯的過程中無法存取動態產生的檔案,以致於無法正確編譯網站程式,所以發生錯誤。

以前我也曾經遇過這個問題,這通常與應用程式集區的執行身份識別有關(請見 IIS應用程式集區自訂身份識別後如何讓 ASP.NET 正常執行 一文),但這次狀況更奇怪,通常在 IIS 下無法執行的狀況只要把自訂身份識別的帳戶加入 IIS_WPG 群組 (IIS6) 或加入 IIS_IUSRS 群組 (IIS7) 即可,而且通常在 Visual Studio 編譯時用的是登入者的身份 (Administrator),怎麼可能會有無法編譯且沒有權限的情勢發生呢?

以下是在 Visual Studio 編譯時所發生的錯誤訊息:

------ Build started: Project: D:\...\WebSite1\, Configuration: Debug Any CPU ------
Validating Web Site
Building directory '/WebSite1/App_Code/'.
(0): Build (web): Could not load file or assembly 'AntiXssLibrary, Version=3.1.3524.16873, Culture=neutral, PublicKeyToken=d127efab8a9c114f' or one of its dependencies. Access is denied.

Validation Complete
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

所以是在 Validating Web Site (驗證網站) 時發生「存取被拒(Access is denied)」的情況,但這代表我 (Administrator) 無法驗證網站嗎?

最後查到原因是因為在 web.config 定義了以下這段

<identity impersonate="true" userName="UserA" password="Passw0rd" />

因為在 web.config 已經定義了 變身 (Impersonation) 的設定,所以在 Visual Studio 中建置時,雖然可以正確編譯網站,部署到公司內的測試機也可以執行,但在編譯時的驗證網站這一段會以該 UserA 使用者的身份執行,而該使用者在我本機剛好也不隸屬於任何群組,所以也沒有任何權限,導致建置時無法在 ASP.NET 的暫存目錄 (C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files) 寫入檔案,以致於無法 建置(Build)成功!

最後我將該使用者 UserA 加入到 IIS_IUSRS 群組,所有問題自然迎刃而解,如下圖示:

這問題一開始並沒那麼直覺,只是覺得納悶說為什麼會有 存取被拒(Access is denied) 的情況,經過一個小時的盤查才查出結果。

  

此文章由 will 發表於 2010/2/10 上午 11:46:27

永久連結 | 評論 (1) | 此文章的RSSRSS comment feed |

分類: ASP.NET | IIS | Visual Studio

標籤: , , , , ,

收藏:

在 ASP.NET 環境下使用 Memcached 快速上手指南

之前一直想研究 Memcached,這幾天花了些時間研究 Memcached Providers 好讓我現有的 ASP.NET 專案能解決多台主機間快取不同步的狀況, 想不到花沒多少時間就上手了,也因此做了一些記錄。

安裝 Memcached (ver 1.4.4) for Win32

1. 下載 memcached 1.4.4 Windows 32-bit binarymemcached Windows 64-bit pre-release

2. 在 C:\Program Files 建立一個 memcached 目錄

3. 將下載的壓縮檔解壓縮至 C:\Program Files\memcached 目錄

4. 開啟命令提示字元

5. 將 memcached 註冊進 Windows 服務

"C:\Program Files\memcached\memcached.exe" -d install

6. 啟動 memcached 服務

"C:\Program Files\memcached\memcached.exe" -d start

 

移除 Memcached (ver 1.4.4) for Win32

1. 開啟命令提示字元

2. 停止 memcached 服務

"C:\Program Files\memcached\memcached.exe" -d stop

3. 將 memcached 服務從 Windows 服務中移除

"C:\Program Files\memcached\memcached.exe" -d uninstall

4. 移除 C:\Program Files\memcached 目錄

 

測試 memcached 是否正常運作

1. 透過 telnet 指令連接到 localhost 的 11211 port, 其中 Port 11211 為 memcached 預設的 Listen Port,如果有開啟防火牆記得要設定才能讓遠端連接。( 預設會 Listen 所有 interface )

telnet localhost 11211

2. 輸入 stats 指令,並按下 Enter 取得目前 memcached 服務的運作狀態,有資料就代表安裝成功了

3. 輸入 quit 指令,並按下 Enter 退出

備註:完整指令請參考 memcached protocol

 

設定 ASP.NET 專案

1. 下載 Memcached Providers 組件 ==>  Memcached Providers 1.2 (.NET 3.5)

2. 將以下組件複製到 ASP.NET 網站的 bin 目錄下,或透過 加入參考(Add Reference) 方式將加入專案

  • Enyim.Caching.dll
  • Enyim.Caching.pdb
  • MemcachedProviders.dll
  • MemcachedProviders.pdb

 

設定 Memcached Cached Provider 並註冊至 web.config

1. 在 <configSections> 區段加入以下定義

<!-- Memcached -->
<section name="cacheProvider"
type="MemcachedProviders.Cache.CacheProviderSection, MemcachedProviders"
allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>

<sectionGroup name="enyim.com">
<section name="memcached"
type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>

2. 然後在 <appSettings> 之上加入以下定義

<enyim.com>
<memcached>
<servers>
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100"
connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<cacheProvider defaultProvider="MemcachedCacheProvider">
<providers>
<add name="MemcachedCacheProvider"
type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders"
keySuffix="_MyProjectName_" defaultExpireTime="2000"/>
</providers>
</cacheProvider>

 

開始使用 memcached 的 API

1. 匯入 MemcachedProviders.Cache 命名空間

using MemcachedProviders.Cache;

2. 取得 Cache 項目

object objCache = DistCache.Get(cacheKey);

3. 寫入 Cache 項目

// 寫入快取資料 (預設過期時間)
DistCache.Add(cacheKey, cacheValue);
// 快取 60 秒
DistCache.Add(cacheKey, cacheValue, 60 * 1000);
// 快取至今天結束
DistCache.Add(cacheKey, cacheValue, DateTime.Today.AddDays(1) - DateTime.Now);

4. 移除 Cache 項目

DistCache.Remove(cacheKey);

5. 移除所有 Cache 項目

DistCache.RemoveAll();

 

心得總結 (優點)

  • 架構簡單、容易上手
  • API 與 ASP.NET 快取機制類似,將現有的 HttpRuntime.Cache 替換成 DisCache 也很容易,像我大約只花半天就將一個不小的專案從 ASP.NET 快取轉移至 memcached 快取
  • 安裝部署容易
  • 很容易擴充記憶體快取的總量,增加 memcached 伺服器並修改 web.config 即可!
  • 超高效能,同時支援 TCP 與 UDP 協定
  • 跨平台、跨語言、開放協定、開放原始碼、許多大網站都使用 memcached
  • 內建提供 Session Provider

心得總結 (缺點)

  • 無法取得所有快取項目,用 ASP.NET 快取可以透過 Cache.GetEnumerator() 取得所有快取項目 ( 參考: ASP.NET 如何將目前的 Cache 物件全部清空 ),但在 memcached 完全沒辦法,因為 memcached protocol 根本沒有定義這個功能,除非你自行實做。
  • 網路上可下載的 memcached 版本都不支援 高可用性(High Availability; HA) 特性
  • AppFabric Caching (Velocity) 相比功能少很多
  • 缺乏中文資源、文件少、中文社群不積極、有 Bug 不見得有人理 (還好是開源碼可以自己改)

 

相關連結

  

此文章由 will 發表於 2010/1/27 下午 09:09:01

永久連結 | 評論 (9) | 此文章的RSSRSS comment feed |

分類: ASP.NET | ASP.NET MVC | .Net

標籤: , , , ,

收藏: