Tomcat
Azure 中的 Memcached 會話管理器:連接被強制關閉
我正在使用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 並提出一個拉取請求,並添加一個使其可配置的 :-)