web-dev-qa-db-ja.com

Apache HTTP Server2.2.21およびTomcat7.0.23でmod_proxy_ajpを使用した負荷分散とクラスタリング

私はこれらの組み合わせを使用して負荷分散とクラスタリングを機能させるのに苦労してきました:

  • スティッキーセッションを有効にしてmod_proxy_ajpを使用するApacheHTTP Server 2.2.21(httpd-2.2.21-win32-x86-openssl-0.9.8r)。
  • Apache Tomcat 7.0.23(Apache-Tomcat-7.0.23-windows-x64)
  • JDK 7アップデート2(jdk-7u2-windows-x64)
  • Windows 764ビット
  • 春3.1

私が読んだいくつかのリンク:

これは私の構成です:

httpd.conf

# Required Modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule status_module modules/mod_status.so

# Reverse Proxy
<Proxy balancer://mybalancer>
    BalancerMember ajp://localhost:8301 route=s1
    BalancerMember ajp://localhost:8302 route=s2
    BalancerMember ajp://localhost:8303 route=s3
</Proxy>
ProxyPass / balancer://mybalancer/ stickysession=JSESSIONID|jsessionid

# Forward Proxy
ProxyRequests Off

<Proxy *>
    Order deny,allow
    Deny from none
    Allow from localhost
</Proxy>

# Balancer-manager, for monitoring
<Location /balancer-manager>
    SetHandler balancer-manager

    Order deny,allow
    Deny from none
    Allow from localhost
</Location> 

各Tomcatのserver.xml(ポート番号のみの違い)

<Server port="8001" shutdown="SHUTDOWN">
    <Listener className="org.Apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <Listener className="org.Apache.catalina.core.JasperListener" />
    <Listener className="org.Apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.Apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    <Listener className="org.Apache.catalina.core.ThreadLocalLeakPreventionListener" />

    <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
            type="org.Apache.catalina.UserDatabase" description="User database that can be updated and saved"
            factory="org.Apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/Tomcat-users.xml" />
    </GlobalNamingResources>

    <Service name="Catalina">
        <Connector port="8101" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8201" />

        <Connector port="8301" protocol="AJP/1.3" redirectPort="8201" />

        <Engine name="Catalina" defaultHost="localhost" jvmRoute="s1">

            <Cluster className="org.Apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
                <Manager className="org.Apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" 
                    notifyListenersOnReplication="true" />
                <Channel className="org.Apache.catalina.tribes.group.GroupChannel">
                    <Membership className="org.Apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4" port="45564" frequency="500" dropTime="3000" />
                    <Sender className="org.Apache.catalina.tribes.transport.ReplicationTransmitter">
                        <Transport className="org.Apache.catalina.tribes.transport.nio.PooledParallelSender" />
                    </Sender>
                    <Receiver className="org.Apache.catalina.tribes.transport.nio.NioReceiver"
                        address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" />
                    <Interceptor className="org.Apache.catalina.tribes.group.interceptors.TcpFailureDetector" />
                    <Interceptor className="org.Apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" />
                </Channel>
                <Valve className="org.Apache.catalina.ha.tcp.ReplicationValve" filter="" />
                <Valve className="org.Apache.catalina.ha.session.JvmRouteBinderValve" />
                <ClusterListener className="org.Apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
                <ClusterListener className="org.Apache.catalina.ha.session.ClusterSessionListener" />
            </Cluster> 

            <Realm className="org.Apache.catalina.realm.LockOutRealm">
                <Realm className="org.Apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
            </Realm>
            <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
                <Valve className="org.Apache.catalina.valves.AccessLogValve"
                    directory="logs" prefix="localhost_access_log." suffix=".txt"
                    pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            </Host>
        </Engine>
    </Service>

</Server>

ポート番号(同じサーバーにデプロイされている場合は、インスタンスが同じポートを使用しないようにしてください)

  • 80-> ApacheHTTPサーバーポート
  • 80xx-> Tomcatサーバーのシャットダウンポート
  • 81xx-> Tomcatコネクタポート(HTTP)
  • 82xx-> TomcatSSLリダイレクトポート
  • 83xx-> TomcatAJPポート
  • 40xx-> NioReceiverのTomcattcp受信ポート

スプリングコントローラー

@Controller
@RequestMapping("/login")
public class LoginController {
    @RequestMapping(method=RequestMethod.GET)
    public String show(@ModelAttribute("user") User user, HttpServletRequest request) {
        user.setUsername("YUSUF");

        HttpSession session = request.getSession();
        Integer tambah = (Integer) session.getAttribute("tambah");
        if(tambah == null) tambah = new Integer(1);
        else tambah = new Integer(tambah.intValue() + 1);
        session.setAttribute("tambah", tambah);

        return "login";
    }
}

login.jsp

    <div class="mainFooter">
        Tambah = ${sessionScope.tambah}
        <br>
        ID = ${pageContext.session.id}
    </div>

これまでのところ、負荷分散部分は機能していますが、セッションレプリケーションは機能していません。
基本的に、ログインページで更新を押し続けると、変数「tambah」がインクリメントされ、セッションに保持されます。また、現在のTomcatノードがダウンしている場合、セッションは次のTomcatノードに複製され、データは失われません。しかし、これが起こっていることです:

ログイン画面:

Tambah = 39 
ID = C1D59C8CA5D10EB98C1DE08AC618204D.s1 

Tomcat1を停止し、Tomcat2とTomcat3を実行したままにします。ログイン画面は次のとおりです:

Tambah = 1
ID = A83KJFO38FK30FJDL40FLREI39FKDKGD.s2

フェイルオーバーが機能しておらず、セッションが複製されておらず、アプリケーションが新しいセッションを作成したようです。誰かが私を正しい方向に向けるのを手伝ってもらえますか?

ありがとう

編集:@Shane Maddenのおかげで、質問を解決しました。これは私が行った変更です:

<Receiver className="org.Apache.catalina.tribes.transport.nio.NioReceiver"
                        address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" />

Tomcatごとに、tcpレシーバーポートが異なる必要があります(同じサーバーで実行されている場合)。たとえば、4001、4002、4003などを使用します。

2
Yusuf S

@Shane Maddenのコメントのおかげで、Tomcatクラスターのドキュメントを http://Tomcat.Apache.org/Tomcat-7.0-doc/cluster-howto.html 、特にこの部分で読み直しました- >「Tomcatインスタンスが同じマシンで実行されている場合は、tcpListenPort属性がインスタンスごとに一意であることを確認してください。ほとんどの場合、Tomcatは、4000〜4100の範囲の使用可能なポートを自動検出することで、これを独自に解決できるほど賢いです。」.

私が行った変更は、Tomcatインスタンスのserver.xmlのそれぞれにあります。各ポートが異なることを確認します(たとえば、4001、4002、4003)。

<Receiver className="org.Apache.catalina.tribes.transport.nio.NioReceiver"  
  address="auto" port="4001" autoBind="100" 
  selectorTimeout="5000" maxThreads="6" />

そして出来上がり!負荷分散とクラスタリングが機能しています(もちろん、最も基本的な構成で)。この投稿が他の人の初期設定に役立つことを願っています。

2
Yusuf S

私は同様のソフトウェアスタック(Apache2.2.15とTomcat7.0.65)を持っていますが、すべてのLinuxと私はバランサーステータスページで次の問題に遭遇しました:ステータスページに入る代わりにProxyPassディレクティブ

ProxyPass / balancer://mybalancer/ stickysession=JSESSIONID|jsessionid

/ balancer-managerリクエストをtomcatの1つにリダイレクトしていました(したがって、tomvatエラーページが表示されていました)。 ProxyPassを/よりも制限的なものに設定することで問題を回避しました

ProxyPass /myapp balancer://mybalancer/myapp stickysession=JSESSIONID|jsessionid

しかし、これが正しい方法であるかどうかはわかりませんか?

0
louigi600