解決 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

標籤: , ,

收藏:

在 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

標籤: , , , ,

收藏:

利用 WebClient 類別模擬 HTTP POST 表單送出的注意事項

我們都知道 WebClient 類別是個簡單易用的東西,不只可以用作 HTTP 用途,連 FTP 都能用,想偷懶時很快就能寫出一些網路資料上傳、下載的程式,像我在寫一些測試程式時經常會使用 WebClient 類別,但大多情況都用來「下載網頁」居多,少有模擬表單上傳資料的情況,但利用 WebClient 類別在「傳送表單資料」時要小心使用,否則遠端接不到資料又很難除錯時哪就麻煩了。

與「上傳資料」有關的方法有以下四種 (不考慮非同步模式的方法)

如果是你,你會選用哪一種呢?你會不會覺得 string 比較友善呢? ^__^

像我們之前就這樣寫,以為可以順利的將資料上傳(錯誤示範):

using (WebClient wc = new WebClient())
{
  try
  {
	  wc.Encoding = Encoding.UTF8;

	  string resultXML = wc.UploadString(Config.PostURL, 
		  String.Format("id={0}&pw={1}", user.ID, user.PW));
  }
  catch (WebException ex)
  {
	  throw new Exception("無法連接遠端伺服器");
  }
}

透過這段程式所送出的 HTTP Request Header 如下:

POST /Home/Echo HTTP/1.1
Host: my.example.com:52215
Content-Length: 13
Connection: Keep-Alive

id=aaa&pw=bbb

雖然一樣是 POST 方法,但是缺少了最重要的 Content-Type 標頭,也就是:

Content-Type: application/x-www-form-urlencoded

以我們常用 ASP.NET MVC 為例,你不傳送標準的 Content-Type 過去,就無法正確抓到所有表單資料,也無法透過 Model Binder 自動繫結到 Action 參數中!

雖然你可以利用 wc.Headers 屬性自行將缺少的 Header 加上去,例如:

wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

但後來我們改用 UploadValues 方法,程式碼範例如下:

using (WebClient wc = new WebClient())
{
  try
  {
      wc.Encoding = Encoding.UTF8;
      
      NameValueCollection nc = new NameValueCollection();
      nc["id"] = "aaa";
      nc["pw"] = "bbb";
      
      byte[] bResult = wc.UploadValues(Config.PostURL, nc);
      
      string resultXML = Encoding.UTF8.GetString(bResult);
  }
  catch (WebException ex)
  {
      throw new Exception("無法連接遠端伺服器");
  }
}

雖然多了幾行 Code,但是其實語法更容易理解,而且也不用自己組 POST 資料中類似 QueryString 的字串,還會自動做 URLEncode 動作,只是最後多一個步驟要將 byte[] 轉回 string 而已,這段程式最後會送出的 HTTP Request Header 如下:

POST /Home/Echo HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: my.example.com:52215
Content-Length: 13
Connection: Keep-Alive

id=aaa&pw=bbb

但是,使用 WebClient 類別其實有許多缺點,所以我文章一開頭就說過「想偷懶時」,主要的缺點有:

  • 無法指定 Timeout,所以當網路連不上時,網頁或程式會整個停在那裡很久!
  • 不適合用來下載大量的檔案,高負載的網站也不適合這樣用,即便你用非同步的方式撰寫,也會讓 WebClient 因為佔據過多 Threads 而導致效能降低,壹台電腦的 Threads 數是有限制的。

對於較正式的場合,還是建議改用 HttpWebRequest 類別處理。

相關連結

  

此文章由 will 發表於 2010/1/23 下午 01:34:45

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

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

標籤: , , ,

收藏:

如何關閉 AppFabric Caching (Velocity) 的安全性檢查

之前才剛將 AppFabric Caching 的開發環境設好,也都 Run 過範例專案都可以正常運作,但今天同事卻遇到無法連接 CacheHost 的問題,而這個問題也很有可能讓許多 AppFabric Caching 新手遭遇相同的困難,因此將此問題解決的過程做個記錄。

先來看看錯誤訊息的樣子:

ErrorCode<ERRCA0022>:SubStatus<ES0006>:There is a temporary failure, please retry after some time. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. Please ensure security permission has been granted for this client account on cluster and ensure that cache service is allowed through firewall on all cache hosts. Retry later)

ErrorCode<ERRCA0022>:SubStatus<ES0006>:There is a temporary failure, please retry after some time. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. Please ensure security permission has been granted for this client account on cluster and ensure that cache service is allowed through firewall on all cache hosts. Retry later)

由於 AppFabic Caching (Velocity) 一直沒有關於使用權限相關的文件,所以我只好選擇完全關閉安全性檢查的部分,若要關閉安全性檢查,在 Cluster 與 Client 兩端都要配合修改才行:

設定 Cluster 共有 6 個步驟

1. 開啟 PowerShell 管理工具

2. 匯出目前的 Cluster 設定檔

Export-CacheClusterConfig -File C:\VelocityConfigExport.xml

3. 編輯匯出的 Cluster 設定檔,加入如下圖的 <securityProperties> 區段

<securityProperties mode="None" protectionLevel="None" />

4. 停止 Cache Cluster

Stop-CacheCluster

5. 匯入新的設定檔

Import-CacheClusterConfig -File C:\VelocityConfigExport.xml

6. 啟動 Cache Cluster

Start-CacheCluster

 

設定 Client 執行環境需要調整 new DataCacheFactory 的參數

DataCacheFactory myCacheFactory = new DataCacheFactory(servers, true, true, 
100, DataCacheLocalCacheSyncPolicy.TimeoutBased, 10000, 200,
new DataCacheSecurity(DataCacheSecurityMode.None, DataCacheProtectionLevel.None));

如果是用 XML 定義 AppFabric Caching 的參數可參考如下:

<securityProperties mode="None" protectionLevel="None" />
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="dataCacheClient" type="Microsoft.Data.Caching.DataCacheClientSection, CacheBaseLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <dataCacheClient deployment="simple">
    <hosts>
      <host name="your.host" cachePort="22233"   cacheHostName="DistributedCacheService" />
    </hosts>
    <advancedProperties>
      <securityProperties mode="None" protectionLevel="None" />
    </advancedProperties>
  </dataCacheClient>
  <runtime>
    <gcServer enabled="true" />
  </runtime>
</configuration>

 

相關連結

  

此文章由 will 發表於 2010/1/14 下午 11:01:34

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

分類: Windows Azure | .Net

標籤: , , ,

收藏:

如何設立 AppFabric Caching (Velocity) 開發環境

研究 Beta 版的技術真是累人,很多事情講的不清不楚,害我花了好多時間才將 AppFabric Caching (Code Name: Velocity) 的開發環境弄好,以下是將 Velocity 開發環境設立完成的完整過程。

設立環境主要分兩個步驟:

  1. 安裝 AppFabric Caching 必要元件
  2. 取得開發用必要 .NET 組件

 

安裝 AppFabric Caching 必要元件

我們可以透過 Web Platform Installer 直接安裝 AppFabric Caching 服務,事實上在未來正式 AppFabric Caching 會整合成一個「伺服器角色」稱為 Application Server ( 大概會叫這個名字 ),安裝過程圖示如下:

如果不想自動安裝,也可以到 Download details: Windows Server AppFabric Beta 1 下載獨立安裝檔與相關文件 ( Installation GuideRelease Notes )。

安裝完成後,所有程式與 .NET 組件都會擺在以下目錄:

C:\Windows\System32\ApplicationServerExtensions

 

取得開發用必要 .NET 組件

在安裝目錄下有兩個組件是開發時必須的,這就是開發時所需的組件 ( Client Library )

安裝完成後其實所有必要組件都會直接註冊進 GAC 中,且命名空間為 Microsoft.Data.Caching,但是透過 Visual Studio 卻無法「加入參考」( Add Reference ),因為在加入參考的對話框中怎樣也找不到 Microsoft.Data.Caching 這個命名空間,若你透過「瀏覽」( Browse ) 的方式直接進入安裝目錄也會發生找不到檔案的錯誤,讓你無法將這兩個組件加入參考,如下圖示:

Add Reference

最後,我研究出兩種方法可以成功加入組件參考:

1. 直接修改專案檔 ( 透過 Windows Server AppFabric Beta 1 Samples 範例程式查到的 )

2. 將組件複製到專案目錄下,然後再透過「瀏覽」的方式加入參考

 

相關連結

  

此文章由 will 發表於 2009/12/29 下午 08:33:46

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

分類: .Net | 心得分享 | Windows Azure

標籤: , , ,

收藏: