spymemcached 中,一個 mc client 與某一個 mc node 之間已建立的 connection 上,
如果執行操作屢屢超時(net.spy.memcached.OperationTimeoutException),
那么,有一個計數器專門記錄超時次數(connected或reconnecting就清零)。
當某一個 mc node 的連續超時次數達到一定閾值(如 998 次),
就會……
- 關閉原來的 socket channel,並將該 mc node 放入重連隊列 reconnectQueue :lostConnection(mn),
- 遍歷 reconnectQueue ,逐一嘗試重新建立 socket 連接:attemptReconnects(),
- 然后不管連沒連上,rehash 隊列中的操作:redistributeOperations(retryOps)。(rehash 指重新計算hash值,看是否要連接其他的節點)。
這個超時次數閾值,既可以在 spring 里如下這樣設置,也可以采用默認值 998 次:
<beanid="memcachedClient"class="net.spy.memcached.spring.MemcachedClientFactoryBean">
|
相關代碼:
每一次 handle io over the connections 時,都會檢測一下這個 connection 對應的節點上登記的“連續超時次數”是否已經達到閾值:
|
MemcachedConnection.java
|
|
private final int timeoutExceptionThreshold;
……
timeoutExceptionThreshold = f.getTimeoutExceptionThreshold();
……
|
|
/**
* MemcachedClient calls this method to handle IO over the connections.
*/
public void handleIO() throws IOException {
……
// see if any connections blew up with large number of timeouts
for (SelectionKey sk : selector.keys()) {
MemcachedNode mn = (MemcachedNode) sk.attachment();
if (mn.getContinuousTimeout() > timeoutExceptionThreshold) {//檢查一下
getLogger().warn("%s exceeded continuous timeout threshold", sk);
lostConnection(mn);//斷開連接,放入重連隊列
}
}
if (!shutDown && !reconnectQueue.isEmpty()) {
attemptReconnects();//重新連接
}
// rehash any operations that are in retry state
redistributeOperations(retryOps);//
retryOps.clear();
|
| 如果配置文件也沒配 timeoutExceptionThreshold ,初始化時也沒傳這個參數, 那么 DefaultConnectionFactory 就取默認值 DEFAULT_MAX_TIMEOUTEXCEPTION_THRESHOLD,即998次(anyway,也許是1000次)! |
| DefaultConnectionFactory.java |
|
/**
* Maximum number + 2 of timeout exception for shutdown connection.
*/
public static final int DEFAULT_MAX_TIMEOUTEXCEPTION_THRESHOLD = 998;
|
| DefaultConnectionFactory.java |
|
public int getTimeoutExceptionThreshold() {
return DEFAULT_MAX_TIMEOUTEXCEPTION_THRESHOLD;
}
|
針對每一個 memcache node 設置一個“連續超時次數”計數器:
|
TCPMemcachedNodeImpl.java
|
|
// operation Future.get timeout counter
private final AtomicInteger continuousTimeout = new AtomicInteger(0);
……
public void setContinuousTimeout(boolean timedOut) {
if (timedOut && isActive()) {
continuousTimeout.incrementAndGet();
} else {
continuousTimeout.set(0);
}
}
|
| MemcachedConnection.java |
|
/**
* helper method: increase timeout count on node attached to this op.
*
* @param op
*/
public static void opTimedOut(Operation op) {
MemcachedConnection.setTimeout(op, true);
}
|
參考資源:
1)智深,2012,
spymemcached源碼深入分析;
2)2011,
Issue 173: Spymemcached fail reconnect to local memcahed under high load ..;
3)我的相關文章:
spymemcached 的 useNagle 問題與 TCP/IP延遲發送數據
3)
最佳實踐系列:前端代碼標准和最佳實踐
(2012-12-19 23:33)
2)
電商課題V:分布式鎖
(2012-11-17 22:16)
3)
電商課題:cookie防篡改
(2012-11-17 22:24)
4)
電商課題VI:分布式Session
(2012-11-17 22:30)
5)
電商課題:RBAC權限控制
(2012-11-17 22:47)
6)
電商課題:冪等性
(2012-11-22 23:52)
7)
電商課題:客戶端的IP地址偽造、CDN、反向代理、獲取的那些事兒
(2012-09-19 01:17)
8)
電商課題:對付秒殺器等惡意訪問行為的簡單梳理
(2012-09-18 03:51)
9)
電商課題VII:支付交易一般性准則
(2012-12-14 01:38)
贈圖一枚

