【電子商取引】nginx+tomcat+memcached session共有クラスタを実現



分散型マルチtomcat webクラスタ環境では、まずsessionの共有問題を解決し、一般的な実現構想は以下の通りである.
(1)セッションレプリケーション:マルチtomcat間でセッションの同期を行い、クラスタ内のtomcatは同じセッション情報を格納する
(2)共有セッションストレージ:redis/memcached、DBなどのセッションセットを同じ場所に格納する.tomcat自体のメモリにはセッションは格納されていません
(3)session粘性:実はsession粘性はsession共有のスキームではなく、マルチtomcatのクラスタスキームであり、nginx/apacheと協力して実現され、同じユーザ要求を同じtomcatノードに移行し、マルチノード間でsesisonを共有しない.利点は実現が簡単で,欠点はノード障害時にsessionの一部が失われることである.一般的には前の2つの方法に合わせて使用されます.
 
この文書では、memcached-session-managerコンポーネントを使用してnginx+tomcat+memcachedを構築し、クラスタとsession共有ストレージ環境を実現するすべてのプロセスを記録します.
nginx:1.8.0
tomcat 2個:6.0.44
memcachedクラスタ:1.4.4
 
memcached-session-managerは、複数のsessionデータシーケンス化ポリシーを提供します.
(1)javaシーケンス化:保存する情報にjavaを実現することを要求する.io.Serializableインタフェース;
(2)kryoシーケンス化
(3) javolution
(4) xstream
(5) flexjson
参照:http://code.google.com/p/memcached-session-manager/wiki/SerializationStrategies
ここで使用するシーケンス化ポリシーはkryoである
(1)以下の依存するjarパケットを$TOMCAT_にすべて置くHOME/lib中:
asm-3.2.jar  kryo-1.04.jar  kryo-serializers-0.11.jar  memcached-session-manager-1.8.3.jar  memcached-session-manager-tc6-1.8.3.jar  minlog-1.2.jar  msm-kryo-serializer-1.8.3.jar  reflectasm-1.01.jar  spymemcached-2.11.1.jar
(2)2つのtomcatはそれぞれconf/contextを配置する.xml、追加:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="n1:localhost:11211,n2:localhost:11212"
    sticky="false"
    sessionBackupAsync="false"
    lockingMode="uriPattern:/path1|/path2"
    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />

ここで使用するポリシーはsession非粘性でありmemcachedは2つのノードのクラスタを使用する
また、2つのtomcatをそれぞれ配置するHTTPリスニングポートは7181と7182である
(3)nginx構成:
    
upstream cluster_memcached {
        server localhost:7181;
        server localhost:7182;
   }
   server {
       listen 7180;
       server_name localhost;
       location / {
         proxy_pass http://cluster_memcached;
       }
   }

ここでnginxリスニングポートを7190とし、7181および7182のtomcatクラスタにすべてのリクエストを逆エージェントしてください.
 
(4)テストコードsession.jsp:
<%@ page import="java.util.Enumeration" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>session test</title>
  <%
    String key = request.getParameter("sessionKey");
    String value = request.getParameter("sessionValue");
    if(key != null && !"".equalsIgnoreCase(key.trim())) {
      session.setAttribute(key, value);
    }
  %>
</head>
<body>
<form action="session.jsp" method="post">
<input type="text" name="sessionKey" value="key1"><input type="text" name="sessionValue" value="value1">
<input type="submit" value="  ">
</form>
<h4>     session--<%=session.getServletContext().getRealPath("/")%></h4>
<table>
  <tr>
  <th>key</th>
  <th>value</th>
  </tr>
  <%
  Enumeration<String> keys = session.getAttributeNames();
    while(keys.hasMoreElements()){
      String k = keys.nextElement();
      String v = (String)session.getAttribute(k);
      %>
  <tr>
    <td><%=k%></td>
    <td><%=v%></td>
  </tr>
  <%
    }
  %>
</table>
</body>
</html>

 
 
 
分散クラスタ高可用性session理論記事:http://tendyming.iteye.com/blog/1815136