Tomcat

Azure 中的 Memcached 會話管理器:連接被強制關閉

  • October 5, 2012

我正在使用Memcached 會話管理器以非粘性模式處理 Tomcat 會話。我在 Azure 中的部署由一個 Worker 角色和兩個實例組成,這些實例連接到執行我的 Memcached 伺服器的 Azure VM。

一切都很好,我的會話被兩個實例中的任何一個透明地持久化和檢索。當會話空閒大約4 分鐘時會出現問題;一切都表明 Azure 負載均衡器在一段時間不活動後關閉了與 VM 的 spymemcached 連接。

我的 MSM 配置是這樣的:

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
   memcachedNodes="n1:my-azure-vm.cloudapp.net:11211"
   sticky="false"
   sessionBackupAsync="false"
   sessionBackupTimeout="10000"
   lockingMode="uriPattern:/path1|/path2"
   requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js|ttf|eot|svg|woff)$"           
   transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
   customConverter="de.javakaffee.web.msm.serializer.kryo.HibernateCollectionsSerializerFactory"/>

spymemcached 客戶端列印的堆棧跟踪是這樣的:

INFO net.spy.memcached.MemcachedConnection:  Reconnecting due to 
exception on {QA sa=/10.194.132.206:13000, #Rops=1, #Wops=0, #iq=0, 
topRop=net.spy.memcached.protocol.binary.StoreOperationImpl@1d95da8, 
topWop=null, toWrite=0, interested=1} 
java.io.IOException: An existing connection was forcibly closed by the 
remote host 
   at sun.nio.ch.SocketDispatcher.read0(Native Method) 
   at sun.nio.ch.SocketDispatcher.read(Unknown Source) 
   at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source) 
   at sun.nio.ch.IOUtil.read(Unknown Source) 
   at sun.nio.ch.SocketChannelImpl.read(Unknown Source) 
   at net.spy.memcached.MemcachedConnection.handleReads 
(MemcachedConnection.java:303) 
   at net.spy.memcached.MemcachedConnection.handleIO 
(MemcachedConnection.java:264) 
   at net.spy.memcached.MemcachedConnection.handleIO 
(MemcachedConnection.java:184) 
   at net.spy.memcached.MemcachedClient.run(MemcachedClient.java:1298) 

鑑於 Azure 中的這種空閒時間限制,是否有任何其他方法可以使 MSM 在 azure 雲中工作?

沒有什麼可以開箱即用地解決這個問題。但是您可以繼承 MemcachedBackupSessionManager 並使用該backgroundProcess方法(由 tomcat 每秒或每 10 秒呼叫一次,不確定這一點)來 ping 您配置的 memcacheds。一個非常簡單的實現如下所示:

package de.javakaffee.web.msm;

public class MyMsm extends MemcachedBackupSessionManager {

   @Override
   public void backgroundProcess() {
       super.backgroundProcess();
       final MemcachedNodesManager nodesManager = _msm.getMemcachedNodesManager();
       // got through all configured node ids and ping each memcached
       // with a dummy key.
       // _msm.newSessionId("ping") generates e.g. ping-n1 for a nodeId n1
       // so this will be routed the related memcached node
       for (String nodeId : nodesManager.getPrimaryNodeIds()) {
           // use async here so that no error handling is needed
           _msm.getMemcached().asyncGet(_msm.newSessionId("ping"));
       }
   }
}

然後你 jar 這個類,將 jar 放在除了 msm jar 之外的 $CATALINA_HOME/lib 中,並將 Manager 類名更改為className="de.javakaffee.web.msm.MyMsm".

如果你願意,你也可以分叉 msm 並提出一個拉取請求,並添加一個使其可配置的 :-)

引用自:https://serverfault.com/questions/435026