Memcached Session Manager を使用してTomcatセッションを非スティッキーモードで処理しています。 Azureでのデプロイは、Memcachedサーバーを実行しているAzure VM)に接続する2つのインスタンスを持つワーカーロールで構成されています。
すべてが非常にうまく機能し、私のセッションは永続化され、2つのインスタンスのいずれかによって透過的に取得されます。この問題は、セッションが約4分間アイドル状態のときに発生します。すべての点で、Azure Loadbalancerは、一定期間非アクティブになった後、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秒ごとに呼び出されます。これについてはよくわかりません)を使用して、構成済みのmemcachedにpingを実行できます。非常に単純な実装は次のようになります。
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し、msmjarのほかに$ CATALINA_HOME/libに配置し、Managerクラス名をclassName="de.javakaffee.web.msm.MyMsm"
に変更します。
必要に応じて、msmをフォークして、これを構成可能にする追加機能を使用してプルリクエストを送信することもできます:-)