context: Apache 2.0.54, Tomcat 5.5.12, jk 1.2.15, ajp 1.3

I am observing something which I think I understand, but I want to make sure it is expected behaviour and not something I should attempt to try and fix. See config at the end of this email for more information.

We have configured Apache 2 to have a load-balancer between 2 Tomcat instances and configured it as per standard configurations (what we believe to be standard configurations). When doing the following failover test:

1) Start up both tomcat nodes, and 'warm' them up by ensuring that the sticky session OR round-robin logic (we've tried both) routes some requests to both nodes. 2) Pause the submission of requests to the cluster just for testing purposes, then shut down one of the tomcat nodes cleanly via shutdown command leaving one clean node in the cluster. 3) _First_ request that comes into the cluster that would normally by 'stickied'/stuck/round-robin'd to the now deceased node is shown a 500 Error. Subsequent requests are moved successfully over to the remaining node.

If I think about this a bit, it seems reasonable to design the ajp connectors this way because of trying to check the state of the worker before sending it a request introduces quite a lot of overhead, and would probably reduce performance. The design is 'optimistic' in that it assumes that for the majority of the time the tomcat node will be there. Unfortunately the first request in gets nuked.

Is this the correct and expected behaviour in this scenario? Or have we simply configured something incorrectly? Perhaps that's just The Way It Is?

cheers,

Paul Smith

--begin configs --

[EMAIL PROTECTED] conf]# more workers.properties
# Define workers
worker.list=loadbalancer,status
worker.maintain=5

# -------------------------------------
# First Tomcat Server: worker1 (ajp13)
# -------------------------------------
#
# Talk to Tomcat listening on machine mel.neil.aconex.com at port 8009
worker.worker1.type=ajp13
worker.worker1.host=192.168.0.218
worker.worker1.port=8009
worker.worker1.lbfactor=1
# Use up to 10 sockets, which will stay no more than 10min in cache
worker.worker1.cachesize=10
worker.worker1.cache_timeout=600
# Ask operating system to send KEEP-ALIVE signal on the connection
worker.worker1.socket_keepalive=1
# Want ajp13 connection to be dropped after 10secs (recycle)
worker.worker1.socket_timeout=300

# -------------------------------------
# Second Tomcat Server: worker2 (ajp13)
# -------------------------------------
#
# Talk to Tomcat listening on machine mel.neil.aconex.com at port 8010
worker.worker2.type=ajp13
worker.worker2.host=192.168.0.219
worker.worker2.port=8009
worker.worker2.lbfactor=0
# Use up to 10 sockets, which will stay no more than 10min in cache
worker.worker2.cachesize=10
worker.worker2.cache_timeout=600
# Ask operating system to send KEEP-ALIVE signal on the connection
worker.worker2.socket_keepalive=1
# Want ajp13 connection to be dropped after 10secs (recycle)
worker.worker2.socket_timeout=300

# -------------------------------------
# Load Balancer worker: loadbalancer
# -------------------------------------
#
# The loadbalancer (type lb) worker performs weighted round-robin
# load balancing with non-sticky sessions.
# Note:
#  ----> If a worker dies, the load balancer will check its state
#        once in a while. Until then all work is redirected to peer
#        worker.
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=worker1,worker2
worker.loadbalancer.sticky_session=false
worker.loadbalancer.recover=65
# -------------------------------------
# Status worker: status
# -------------------------------------
#
worker.status.type=status



[EMAIL PROTECTED] conf]# more httpd.conf
#
# Based upon the NCSA server configuration files originally by Rob McCool.
#


[snip]


#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so

LoadModule jk_module modules/mod_jk.so


[snip]


#
# Bring in additional module-specific configurations
#
<IfModule mod_ssl.c>
    Include conf/ssl.conf
</IfModule>

#
# Configure module: mod_jk
#
JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkRequestLogFormat "%w %V %T"
JkOptions +ForwardKeySize
JkShmFile share/mod_jk.shm

JkMount /* loadbalancer
JkUnMount /*.html loadbalancer
JkUnMount /*.ico loadbalancer
JkUnMount /html/*/*.html loadbalancer
JkUnMount /html/*/*.htm loadbalancer
JkUnMount /html/*/*.ico loadbalancer
JkUnMount /html/*/*.gif loadbalancer
JkUnMount /html/*/*.jpg loadbalancer
JkUnMount /html/*/*.css loadbalancer
JkUnMount /html/*/*.js loadbalancer
JkUnMount /html/*/*.js loadbalancer

# Add jkstatus manager
# Manage loadbalancer with the URL http://servername/jkstatus/
#
JkMount /jkstatus/* status
<Location /jkstatus/>
AuthType Basic
AuthName "JK Status"
AuthUserFile /aconex/apache/passwd/passwords
Require user apacheadmin
</Location>


### Section 3: Virtual Hosts
#

[snip]

[EMAIL PROTECTED] conf]#


Tomcat Server.xml


[EMAIL PROTECTED] conf]# more server.xml
<Server port="8005" shutdown="SHUTDOWN">

  <GlobalNamingResources>
    <!-- Used by Manager webapp -->
    <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="8080" />

    <!-- This is here for compatibility only, not required -->
    <Connector port="8009" protocol="AJP/1.3" />

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase" />
        <Host name="localhost" appBase="foo" >
<Context path="/" docBase="${catalina.home}/app/ mel/" distribu
table="true" >
<Manager className="org.apache.catalina.session.PersistentMan
ager" >
<Store className="org.apache.catalina.session.JDBCStor
e"
connectionURL="jdbc:inetdae7:tower.aconex.com?database
=paul&amp;user=sql&amp;password=sql"
                        driverName="com.inet.tds.TdsDriver"
                        sessionIdCol="session_id"
                        sessionValidCol="valid_session"
                        sessionMaxInactiveCol="max_inactive"
                        sessionLastAccessedCol="last_access"
                        sessionTable ="tomcat_sessions"
                        sessionAppCol = "app_name"
                        sessionDataCol = "session_data"
                        />
                 </Manager>
        </Context>
        </Host>

    </Engine>

  </Service>
</Server>

Reply via email to