最近項目中使用的membase發現出了點問題,生產環境中讀寫各種數據都正常,可是新搭建的開發環境下,只有default bucket寫不進去數據,調用store總是返回FALSE,配置文件也是一模一樣,實在不知道哪里出問題了,其他的幾個bucket都正常讀寫,而且,在開發環境的membase上在新建一個bucket也是正常讀寫的。最后發現生產上windows版本的membase,而開發環境是Linux(centos)版本,懷疑可能跟server版本有關系,于是新裝了一個windows版本的,果然,一切正常。至于Linux版本的(couchbase)為什么出這個問題,還是得花時間找找原因的。
項目使用的dll:membase.dll 2.14.0.0,Enyim.Caching.dll 2.11.0.0,反編譯是可以看到代碼的,但是不好調試,可以在網上找到相應的源碼:
第二個是把membase的源碼包在了LightFramework.Caching項目中,我就是那這個代碼來查原因的。
既然是store失敗,那我們單步跟蹤,看看default的bucket和其他bucket在store方法中有哪里不一樣。
public bool Store(StoreMode mode, string key, object value){ ulong tmp = 0; return this.PerformStore(mode, key, value, 0, ref tmp);}
可以看到實際調用的是PerformStore方法,跟進去后發現var node = this.pool.Locate(hashedKey);會返回null,也就是沒有找到對應的bucket了,那還寫什么數據啊。
查查為什么返回是null,我們發現在初始化membaseclient實例時,需要向注冊的serverurl獲取該bucket信息(是否合法,狀態是否正常等),調用ResolveBucket方法,結果異常了。401錯誤,未授權!
我們使用其他bucket初始化時,發現該方法的client參數中credential是有值的(username、passWord),而default的bucket卻都是null。應該就是這個原因導致的。手動將credential的username設為default,再次請求bucket驗證信息,果然,正確返回了。
納悶了,不是默認的default不能設置密碼的么,怎么這里有需要驗證呢?Google相關的問題,發現不少人都不知道怎么破,甚至說是membase的bug:
在查找問題的過程中,我發現如果bucket是default,membase.dll會將其bucketname和password都置空,意思是不需要身份驗證,走的是特殊端口11210(其他bucket走的是11211驗證),既然注釋都這么講了,那為毛在bucket驗證信息的請求中還需要身份驗證呢?
Default無法寫入的問題就是由上面的原因導致的,對于windows版本的membase server是不存在的,我測試過,對于default bucket沒有身份驗證的限制。而對于Linux版本,通過源碼跟蹤過程中,將身份驗證信息手動改好,也是可以正常讀寫的,可惜的是,無法在外部初始化membaseclient時將其credential配置正確。有另一個解決方案,就是使用MemcachedClient,因為membase是兼容memcached sdk的,所以可以按照下面的方式初始化操作實例:
var config = new MemcachedClientConfiguration();config.AddServer("192.168.1.12",11211);var client = new MemcachedClient(config);client.Store(StoreMode.Set, DateTime.Now.ToString("HHmmss"), "testValue");
這種方式讀寫default bucket也是正常的。
新聞熱點
疑難解答