Re: Tomcat JDBC Connection Pool initialization question
On 23. Juli 2014 01:20:27 MESZ, Wes Clark wcl...@guidewire.com wrote: I want to initialized a new connection being added to the pool with more than one SQL statement. I cannot see how to override the existing methods to do this. Has anyone done this, or have a suggestion for me? Have you tried to separate them with a semicolon? Something like SELECT 1; SELECT 2 Regards Felix - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Query timeouts using tomcat jdbc pool
Thank you, I have changed timeBetweenEvictionRunsMillis value and it is working properly now. Another problem has appeared: although the timeout is handled correctly, no exception is thrown. I thought an SQLException would be thrown if query takes too long. Maybe pool does not throw exceptions at all in that situation? Than you! 2014-07-21 20:40 GMT+04:00 Daniel Mikusa dmik...@gopivotal.com: On Mon, Jul 21, 2014 at 11:05 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Hello, dear tomcat users! I am developing high-load application using tomcat jdbc connection pool and Oracle database. It is very important to ensure my app to have very small DB query timeouts (no longer than 3 seconds) to prevent long-running queries or database slowness from blocking all my application. To simulate long-running queries I have put the DB in QUIESCE state using ALTER SYSTEM QUIESCE RESTRICTED statement. But it looks like the timeout values have no impact - when i begin to test my application, it hangs... Have you taken thread dumps of your application when it hangs? What do these show your threads are doing? Here is my jdbc pool configuration: String connprops = oracle.net.CONNECT_TIMEOUT=3000;oracle.jdbc.ReadTimeout=3000; + oracle.net.READ_TIMEOUT=3000; pp.setConnectionProperties(connprops); pp.setDriverClassName(oracle.jdbc.OracleDriver); pp.setTestOnBorrow(true); pp.setTestOnConnect(true); pp.setTestOnReturn(true); pp.setTestWhileIdle(true); It's probably not necessary to have all of these enabled. I usually only see testOnBorrow and testWhileIdle enabled. TestOnReturn is almost worthless, in my opinion. TestOnConnect might be helpful to catch connection issues at boot, but generally a connection that is just created should be good unless you have configuration problems. pp.setMaxWait(2000); pp.setMinEvictableIdleTimeMillis(2); pp.setTimeBetweenEvictionRunsMillis(2); This might be high given your aggressive settings for removeAbandonedTimeout. The timeBetweenEvictionRunsMillis setting dictates how often the pool looks for idle connections, abandoned connections, and how often it validates idle connections. If you set this to 20 secs, using an abandoned timeout less than 20 seconds is probably not going to be accurate. For example, if the cleaner thread runs and your application has been holding a connection for 2999ms, it won't consider the connection abandoned. However the cleaner thread won't run again for another 20 secs (based on the config value you used), thus the application can continue using that connection for way over the abandoned timeout you've configured. pp.setValidationInterval(3000); pp.setValidationQuery(SELECT 1 FROM DUAL); Seems OK. pp.setMaxAge(3000); This seems pretty short and might limit how much pooling actually occurs. Also, since this is enforced when you return the connection to the pool it's not going to help with your current issue. What are you trying to accomplish by setting this value so low? pp.setRemoveAbandoned(true); pp.setRemoveAbandonedTimeout(3); This is a pretty low value for abandoned timeout. If you're hoping to use this to limit how long a query can executed, it's probably not the best approach. This will limit the amount of time that a connection can be checked out of the connection pool, and unless you also configure the ResetAbandonedTimer interceptor, it's going to limit the total time your application has to use the connection. If you configure the ResetAbandonedTimer interceptor, it will function closer to the use case you've described but it's probably not the most efficient way to accomplish this task. Generally you'd set the remove abandoned timeout to reclaim connections that were not properly closed, not to reclaim connections where a query is stuck or running for a long time. I think the jdbc driver can more easily handle killing stuck / long running queries. See next comment. pp.setJdbcInterceptors(org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor(queryTimeout=3)); I'm a little surprised this isn't working for you. By setting the statement's query timeout, you're telling the jdbc driver to limit how long each query can run. If a query runs longer than 3 seconds, you should get an SQLTimeoutException. Otherwise there's an issue / limitation with your jdbc driver. I would suggest setting up a test without the connection pool to validate that the jdbc driver and your method for slowing down the database is working correctly. In theory this test should be something like make a connection, set the query timeout,
Re: Query timeouts using tomcat jdbc pool
Vasily, the exception depends on where the timeout occurs. If the timeout is triggered by the driver, because you hit the setQueryTimeout limit http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setQueryTimeout(int) then yes, as per javadoc, it is up to the JDBC driver to throw an exception. Filip On Wed, Jul 23, 2014 at 10:04 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Thank you, I have changed timeBetweenEvictionRunsMillis value and it is working properly now. Another problem has appeared: although the timeout is handled correctly, no exception is thrown. I thought an SQLException would be thrown if query takes too long. Maybe pool does not throw exceptions at all in that situation? Than you! 2014-07-21 20:40 GMT+04:00 Daniel Mikusa dmik...@gopivotal.com: On Mon, Jul 21, 2014 at 11:05 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Hello, dear tomcat users! I am developing high-load application using tomcat jdbc connection pool and Oracle database. It is very important to ensure my app to have very small DB query timeouts (no longer than 3 seconds) to prevent long-running queries or database slowness from blocking all my application. To simulate long-running queries I have put the DB in QUIESCE state using ALTER SYSTEM QUIESCE RESTRICTED statement. But it looks like the timeout values have no impact - when i begin to test my application, it hangs... Have you taken thread dumps of your application when it hangs? What do these show your threads are doing? Here is my jdbc pool configuration: String connprops = oracle.net.CONNECT_TIMEOUT=3000;oracle.jdbc.ReadTimeout=3000; + oracle.net.READ_TIMEOUT=3000; pp.setConnectionProperties(connprops); pp.setDriverClassName(oracle.jdbc.OracleDriver); pp.setTestOnBorrow(true); pp.setTestOnConnect(true); pp.setTestOnReturn(true); pp.setTestWhileIdle(true); It's probably not necessary to have all of these enabled. I usually only see testOnBorrow and testWhileIdle enabled. TestOnReturn is almost worthless, in my opinion. TestOnConnect might be helpful to catch connection issues at boot, but generally a connection that is just created should be good unless you have configuration problems. pp.setMaxWait(2000); pp.setMinEvictableIdleTimeMillis(2); pp.setTimeBetweenEvictionRunsMillis(2); This might be high given your aggressive settings for removeAbandonedTimeout. The timeBetweenEvictionRunsMillis setting dictates how often the pool looks for idle connections, abandoned connections, and how often it validates idle connections. If you set this to 20 secs, using an abandoned timeout less than 20 seconds is probably not going to be accurate. For example, if the cleaner thread runs and your application has been holding a connection for 2999ms, it won't consider the connection abandoned. However the cleaner thread won't run again for another 20 secs (based on the config value you used), thus the application can continue using that connection for way over the abandoned timeout you've configured. pp.setValidationInterval(3000); pp.setValidationQuery(SELECT 1 FROM DUAL); Seems OK. pp.setMaxAge(3000); This seems pretty short and might limit how much pooling actually occurs. Also, since this is enforced when you return the connection to the pool it's not going to help with your current issue. What are you trying to accomplish by setting this value so low? pp.setRemoveAbandoned(true); pp.setRemoveAbandonedTimeout(3); This is a pretty low value for abandoned timeout. If you're hoping to use this to limit how long a query can executed, it's probably not the best approach. This will limit the amount of time that a connection can be checked out of the connection pool, and unless you also configure the ResetAbandonedTimer interceptor, it's going to limit the total time your application has to use the connection. If you configure the ResetAbandonedTimer interceptor, it will function closer to the use case you've described but it's probably not the most efficient way to accomplish this task. Generally you'd set the remove abandoned timeout to reclaim connections that were not properly closed, not to reclaim connections where a query is stuck or running for a long time. I think the jdbc driver can more easily handle killing stuck / long running queries. See next comment. pp.setJdbcInterceptors(org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor(queryTimeout=3)); I'm a little surprised this isn't
Re: Query timeouts using tomcat jdbc pool
So, it means that if the timeout is detected not using setQueryTimeout method, but by the tomcat pool settings (setMaxAge or setTimeBetweenEvictionRunsMillis), it means that no exception can be thrown at all? Vasily 2014-07-23 12:14 GMT+04:00 Filip Hanik fi...@hanik.com: Vasily, the exception depends on where the timeout occurs. If the timeout is triggered by the driver, because you hit the setQueryTimeout limit http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setQueryTimeout(int) then yes, as per javadoc, it is up to the JDBC driver to throw an exception. Filip On Wed, Jul 23, 2014 at 10:04 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Thank you, I have changed timeBetweenEvictionRunsMillis value and it is working properly now. Another problem has appeared: although the timeout is handled correctly, no exception is thrown. I thought an SQLException would be thrown if query takes too long. Maybe pool does not throw exceptions at all in that situation? Than you! 2014-07-21 20:40 GMT+04:00 Daniel Mikusa dmik...@gopivotal.com: On Mon, Jul 21, 2014 at 11:05 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Hello, dear tomcat users! I am developing high-load application using tomcat jdbc connection pool and Oracle database. It is very important to ensure my app to have very small DB query timeouts (no longer than 3 seconds) to prevent long-running queries or database slowness from blocking all my application. To simulate long-running queries I have put the DB in QUIESCE state using ALTER SYSTEM QUIESCE RESTRICTED statement. But it looks like the timeout values have no impact - when i begin to test my application, it hangs... Have you taken thread dumps of your application when it hangs? What do these show your threads are doing? Here is my jdbc pool configuration: String connprops = oracle.net.CONNECT_TIMEOUT=3000;oracle.jdbc.ReadTimeout=3000; + oracle.net.READ_TIMEOUT=3000; pp.setConnectionProperties(connprops); pp.setDriverClassName(oracle.jdbc.OracleDriver); pp.setTestOnBorrow(true); pp.setTestOnConnect(true); pp.setTestOnReturn(true); pp.setTestWhileIdle(true); It's probably not necessary to have all of these enabled. I usually only see testOnBorrow and testWhileIdle enabled. TestOnReturn is almost worthless, in my opinion. TestOnConnect might be helpful to catch connection issues at boot, but generally a connection that is just created should be good unless you have configuration problems. pp.setMaxWait(2000); pp.setMinEvictableIdleTimeMillis(2); pp.setTimeBetweenEvictionRunsMillis(2); This might be high given your aggressive settings for removeAbandonedTimeout. The timeBetweenEvictionRunsMillis setting dictates how often the pool looks for idle connections, abandoned connections, and how often it validates idle connections. If you set this to 20 secs, using an abandoned timeout less than 20 seconds is probably not going to be accurate. For example, if the cleaner thread runs and your application has been holding a connection for 2999ms, it won't consider the connection abandoned. However the cleaner thread won't run again for another 20 secs (based on the config value you used), thus the application can continue using that connection for way over the abandoned timeout you've configured. pp.setValidationInterval(3000); pp.setValidationQuery(SELECT 1 FROM DUAL); Seems OK. pp.setMaxAge(3000); This seems pretty short and might limit how much pooling actually occurs. Also, since this is enforced when you return the connection to the pool it's not going to help with your current issue. What are you trying to accomplish by setting this value so low? pp.setRemoveAbandoned(true); pp.setRemoveAbandonedTimeout(3); This is a pretty low value for abandoned timeout. If you're hoping to use this to limit how long a query can executed, it's probably not the best approach. This will limit the amount of time that a connection can be checked out of the connection pool, and unless you also configure the ResetAbandonedTimer interceptor, it's going to limit the total time your application has to use the connection. If you configure the ResetAbandonedTimer interceptor, it will function closer to the use case you've described but it's probably not the most efficient way to accomplish this task. Generally you'd set the remove
Re: Query timeouts using tomcat jdbc pool
maxAge is not a timeout setting. It simply means the connection gets retired(closed) instead of returned to the pool after a certain amount of time timeBetweenEvictionRunsMillis is not a timeout either. It is the interval that the thread checks for timeouts, but not query, connection checkout time out. removeAbandonedTimeout - is the timeout you're looking for. This is the timeout for a connection usage. That is the time between the DataSource.getConnection() call and the Connection.close() call. And whether an exception is thrown here, depends on the driver. the pool simply calls close() on the driver connection, if that yields an exception if another thread is executing a query or not, depends on the driver itself. See http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html On Wed, Jul 23, 2014 at 10:56 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: So, it means that if the timeout is detected not using setQueryTimeout method, but by the tomcat pool settings (setMaxAge or setTimeBetweenEvictionRunsMillis), it means that no exception can be thrown at all? Vasily 2014-07-23 12:14 GMT+04:00 Filip Hanik fi...@hanik.com: Vasily, the exception depends on where the timeout occurs. If the timeout is triggered by the driver, because you hit the setQueryTimeout limit http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setQueryTimeout(int) then yes, as per javadoc, it is up to the JDBC driver to throw an exception. Filip On Wed, Jul 23, 2014 at 10:04 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Thank you, I have changed timeBetweenEvictionRunsMillis value and it is working properly now. Another problem has appeared: although the timeout is handled correctly, no exception is thrown. I thought an SQLException would be thrown if query takes too long. Maybe pool does not throw exceptions at all in that situation? Than you! 2014-07-21 20:40 GMT+04:00 Daniel Mikusa dmik...@gopivotal.com: On Mon, Jul 21, 2014 at 11:05 AM, Vasily Kukhta v.b.kuk...@gmail.com wrote: Hello, dear tomcat users! I am developing high-load application using tomcat jdbc connection pool and Oracle database. It is very important to ensure my app to have very small DB query timeouts (no longer than 3 seconds) to prevent long-running queries or database slowness from blocking all my application. To simulate long-running queries I have put the DB in QUIESCE state using ALTER SYSTEM QUIESCE RESTRICTED statement. But it looks like the timeout values have no impact - when i begin to test my application, it hangs... Have you taken thread dumps of your application when it hangs? What do these show your threads are doing? Here is my jdbc pool configuration: String connprops = oracle.net.CONNECT_TIMEOUT=3000;oracle.jdbc.ReadTimeout=3000; + oracle.net.READ_TIMEOUT=3000; pp.setConnectionProperties(connprops); pp.setDriverClassName(oracle.jdbc.OracleDriver); pp.setTestOnBorrow(true); pp.setTestOnConnect(true); pp.setTestOnReturn(true); pp.setTestWhileIdle(true); It's probably not necessary to have all of these enabled. I usually only see testOnBorrow and testWhileIdle enabled. TestOnReturn is almost worthless, in my opinion. TestOnConnect might be helpful to catch connection issues at boot, but generally a connection that is just created should be good unless you have configuration problems. pp.setMaxWait(2000); pp.setMinEvictableIdleTimeMillis(2); pp.setTimeBetweenEvictionRunsMillis(2); This might be high given your aggressive settings for removeAbandonedTimeout. The timeBetweenEvictionRunsMillis setting dictates how often the pool looks for idle connections, abandoned connections, and how often it validates idle connections. If you set this to 20 secs, using an abandoned timeout less than 20 seconds is probably not going to be accurate. For example, if the cleaner thread runs and your application has been holding a connection for 2999ms, it won't consider the connection abandoned. However the cleaner thread won't run again for another 20 secs (based on the config value you used), thus the application can continue using that connection for way over the abandoned timeout you've configured. pp.setValidationInterval(3000); pp.setValidationQuery(SELECT 1 FROM DUAL); Seems OK. pp.setMaxAge(3000); This seems pretty short and might
Unexpanded WAR and FileNotFoundException: META-INF/MANIFEST.MF
Hi. We have Tomcat with: Host name=localhost appBase=webapps unpackWARs=false autoDeploy=false deployOnStartup=true While startup I got ERROR in log: 14-07-22 15:13:01,551+0100 289 INFO [com.***.listener.PropertiesConfigListener] (main:) Adapter is a log4j adapter ?org.slf4j.impl.Log4jLoggerAdapter 14-07-22 15:13:01,552+0100 290 ERROR [com.***.listener.PropertiesConfigListener] (main:) Exception getting codebase versionjava.io.FileNotFoundException: META-INF/MANIFEST.MF (No such file or directory) I understood, that PropertiesConfigListener can't find path to this file, but - it can't get MANIFEST.MF from inside WAR-file? Any tips - how it can be fixed? Thanks.
Re: Unexpanded WAR and FileNotFoundException: META-INF/MANIFEST.MF
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Арсений, On 7/23/14, 10:14 AM, Арсений Зинченко wrote: We have Tomcat with: Host name=localhost appBase=webapps unpackWARs=false autoDeploy=false deployOnStartup=true While startup I got ERROR in log: 14-07-22 15:13:01,551+0100 289 INFO [com.***.listener.PropertiesConfigListener] (main:) Adapter is a log4j adapter ?org.slf4j.impl.Log4jLoggerAdapter 14-07-22 15:13:01,552+0100 290 ERROR [com.***.listener.PropertiesConfigListener] (main:) Exception getting codebase versionjava.io.FileNotFoundException: META-INF/MANIFEST.MF (No such file or directory) I understood, that PropertiesConfigListener can't find path to this file, but - it can't get MANIFEST.MF from inside WAR-file? Any tips - how it can be fixed? Your com.***.listener.PropertiesConfigListener needs to know how to load files from inside WAR files if you don't want to expand the WAR file. How does your code currently attempt to load the file? You are probably using a FileInputStream or something like that, which can't operate within a JAR/WAR file. - -chris -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJTz8YJAAoJEBzwKT+lPKRYuaAQAKO7Ck6MIVnT672vX1ZzY41Z HKgg+Dk/sjVdZXh+fXWTTyAD9FeG5hN7eEkd95LuO5RApmwj03EU8AsHs8drGQX9 rOdkpc0ucrgxP0KCQ7VlJ7n3SPZ64ASQ8PPMbs0VpkdWFueMz53GjL6hAkEi5p4f 5xK1NJK95e50AokMElbi4YBienZYCDWKV1/0Wh9FfhVnaBWqwFKfiBxoePpHsr18 m8Xh9I27Q+4HPP+34AOGpDSSN2LIl9VFa1suBsgEjdlKvN3HAjQfFee2dAgvUj64 lDGCJbzUD+HriQeNqXjUSDYqsLsfn2Wd/cA6HgP2tTvt3AFciDFqON6nyWC9Cl22 3W+8L5rKmzIYP/Se2084VB8TOEKBg2D9T8Am0FDyKExwvJNY/l8Hxc7IPbZw5aWE /cwTIvO2u9M4lPzDx5RUrhy8VlZSIubAr41P1vgO58BPKLM8vSJsqE/SNMKuoZ+c 3TgqiYyUwlGRQV0JsCNARQw2haDq1YLfGfpsnt0/wWh1LJ9caD8S2d++6IT56x66 oCmIwZvTI9lmBzIqA8ZGifIyzuiVut79Xcg/CL8Pvje5uZhRXkRw8yIuAp86ymH5 S2setIwthjGBKsEOnPMGXjQDePIA83Xa220jQpxyfnUXWb3xXZSb1OGb3IeZepM9 2QXHx/ouQpeV7dsXrjLi =WKOD -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/18/14, 12:13 PM, Rainer Jung wrote: late answer but at least an answer. See below. I appreciate the late answer, because it was very helpful. I have some concerns, though. Please see below. On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you switch a node to activation disabled, mod_jk will not send requests there, that have no session id (and of course also not when the session route points to another node). But the old cookie requests might still go there. Yes, this is what we would normally do. For that you can use the feature, that mod_jk forwards the activation state to the Tomcat node. The node can then decide on itself, whether it will handle a request coming in with an invalid session id, or for example clears the session cookie and does a self-referential redirect, which then by mod_jk is balanced on the fully enabled nodes. This sounds like a promising technique. I was thinking we'd just tell the Tomcat node directly (e.g. set a context-scoped flag) that it was disabled, but having AJP forward that information would be even better, so the state can be managed entirely by the status worker on the httpd side. This logic can be put into a servlet filter. I'm not sure it can be in a Filter because of the interaction with the saved-request features described above. If in a Filter, the request would be saved before the Filter has a chance to see it, then authentication would take place, etc. I think this has to be in a Valve, and it has to happen before the AuthenticatorValve sees the request. Do you see a way around using a Valve? Assuming that such a Valve would be required, I think we should provide one with Tomcat. I'd be happy to write such a Valve. You have to be careful though to not produce redirecting cycles, e.g. in case of errors or all other nodes are down. You could add the name of the first node the the URL as a query param, and if you see it a second time, then do not redirect again. I think that's a good way of doing it. One could also use cookies if they can be relied upon, if you don't want to modify the URL. The request attribute is named JK_LB_ACTIVATION. Search for that name on http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html I'll definitely look at using this. Thanks, - -chris -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: GPGTools -
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 10:37 AM, Christopher Schultz wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you switch a node to activation disabled, mod_jk will not send requests there, that have no session id (and of course also not when the session route points to another node). But the old cookie requests might still go there. Yes, this is what we would normally do. For that you can use the feature, that mod_jk forwards the activation state to the Tomcat node. The node can then decide on itself, whether it will handle a request coming in with an invalid session id, or for example clears the session cookie and does a self-referential redirect, which then by mod_jk is balanced on the fully enabled nodes. This sounds like a promising technique. I was thinking we'd just tell the Tomcat node directly (e.g. set a context-scoped flag) that it was disabled, but having AJP forward that information would be even better, so the state can be managed entirely by the status worker on the httpd side. This logic can be put into a servlet filter. I'm not sure it can be in a Filter because of the interaction with the saved-request features described above. If in a Filter, the request would be saved before the Filter has a chance to see it, then authentication would take place, etc. I think this has to be in a Valve, and it has to happen before the AuthenticatorValve sees the request. Do you see a way around using a Valve? Assuming that such a Valve would be required, I think we should provide one with Tomcat. I'd be happy to write such a Valve. You have to be careful though to not produce redirecting cycles, e.g. in case of errors or all other nodes are down. You could add the name of the first node the the URL as a query param, and if you see it a second time, then do not redirect again. I think that's a good way of doing it. One could also use cookies if they can be relied upon, if you don't want to modify the URL. The request attribute is named JK_LB_ACTIVATION. Search for that name on http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html I'm not seeing this in my request attributes. Do I have to specifically enable it using JkEnvVar? Thanks, - -chris -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org Comment: Using
Re: Unexpanded WAR and FileNotFoundException: META-INF/MANIFEST.MF
Hi, Chris. Thanks for replay. Biggest problem is that I'm not our application developer . 2014-07-23 17:26 GMT+03:00 Christopher Schultz ch...@christopherschultz.net : -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Арсений, On 7/23/14, 10:14 AM, Арсений Зинченко wrote: We have Tomcat with: Host name=localhost appBase=webapps unpackWARs=false autoDeploy=false deployOnStartup=true While startup I got ERROR in log: 14-07-22 15:13:01,551+0100 289 INFO [com.***.listener.PropertiesConfigListener] (main:) Adapter is a log4j adapter ?org.slf4j.impl.Log4jLoggerAdapter 14-07-22 15:13:01,552+0100 290 ERROR [com.***.listener.PropertiesConfigListener] (main:) Exception getting codebase versionjava.io.FileNotFoundException: META-INF/MANIFEST.MF (No such file or directory) I understood, that PropertiesConfigListener can't find path to this file, but - it can't get MANIFEST.MF from inside WAR-file? Any tips - how it can be fixed? Your com.***.listener.PropertiesConfigListener needs to know how to load files from inside WAR files if you don't want to expand the WAR file. How does your code currently attempt to load the file? You are probably using a FileInputStream or something like that, which can't operate within a JAR/WAR file. - -chris -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJTz8YJAAoJEBzwKT+lPKRYuaAQAKO7Ck6MIVnT672vX1ZzY41Z HKgg+Dk/sjVdZXh+fXWTTyAD9FeG5hN7eEkd95LuO5RApmwj03EU8AsHs8drGQX9 rOdkpc0ucrgxP0KCQ7VlJ7n3SPZ64ASQ8PPMbs0VpkdWFueMz53GjL6hAkEi5p4f 5xK1NJK95e50AokMElbi4YBienZYCDWKV1/0Wh9FfhVnaBWqwFKfiBxoePpHsr18 m8Xh9I27Q+4HPP+34AOGpDSSN2LIl9VFa1suBsgEjdlKvN3HAjQfFee2dAgvUj64 lDGCJbzUD+HriQeNqXjUSDYqsLsfn2Wd/cA6HgP2tTvt3AFciDFqON6nyWC9Cl22 3W+8L5rKmzIYP/Se2084VB8TOEKBg2D9T8Am0FDyKExwvJNY/l8Hxc7IPbZw5aWE /cwTIvO2u9M4lPzDx5RUrhy8VlZSIubAr41P1vgO58BPKLM8vSJsqE/SNMKuoZ+c 3TgqiYyUwlGRQV0JsCNARQw2haDq1YLfGfpsnt0/wWh1LJ9caD8S2d++6IT56x66 oCmIwZvTI9lmBzIqA8ZGifIyzuiVut79Xcg/CL8Pvje5uZhRXkRw8yIuAp86ymH5 S2setIwthjGBKsEOnPMGXjQDePIA83Xa220jQpxyfnUXWb3xXZSb1OGb3IeZepM9 2QXHx/ouQpeV7dsXrjLi =WKOD -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 10:40 AM, Christopher Schultz wrote: Rainer, On 7/23/14, 10:37 AM, Christopher Schultz wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you switch a node to activation disabled, mod_jk will not send requests there, that have no session id (and of course also not when the session route points to another node). But the old cookie requests might still go there. Yes, this is what we would normally do. For that you can use the feature, that mod_jk forwards the activation state to the Tomcat node. The node can then decide on itself, whether it will handle a request coming in with an invalid session id, or for example clears the session cookie and does a self-referential redirect, which then by mod_jk is balanced on the fully enabled nodes. This sounds like a promising technique. I was thinking we'd just tell the Tomcat node directly (e.g. set a context-scoped flag) that it was disabled, but having AJP forward that information would be even better, so the state can be managed entirely by the status worker on the httpd side. This logic can be put into a servlet filter. I'm not sure it can be in a Filter because of the interaction with the saved-request features described above. If in a Filter, the request would be saved before the Filter has a chance to see it, then authentication would take place, etc. I think this has to be in a Valve, and it has to happen before the AuthenticatorValve sees the request. Do you see a way around using a Valve? Assuming that such a Valve would be required, I think we should provide one with Tomcat. I'd be happy to write such a Valve. You have to be careful though to not produce redirecting cycles, e.g. in case of errors or all other nodes are down. You could add the name of the first node the the URL as a query param, and if you see it a second time, then do not redirect again. I think that's a good way of doing it. One could also use cookies if they can be relied upon, if you don't want to modify the URL. The request attribute is named JK_LB_ACTIVATION. Search for that name on http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html I'm not seeing this in my request attributes. Do I have to specifically enable it using JkEnvVar? Duh: You can retrieve the variables on
Re: mod_jk and session stickiness
On 23.07.2014 16:37, Christopher Schultz wrote: On 7/18/14, 12:13 PM, Rainer Jung wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. Whatever saved exactly means: if you can identify that situation in terms of any part of the request (e.g. something in the referer header etc.), you can add that as a positive or negative condition via RewriteCond (or the 2.4 unified expression parser) and set JK_STICKY_IGNORE in a RewriteRule that does not change the URI, only sets the variable and also only of the RewriteConds apply. You'd have to analyze the request-response stream e.g. with a browser plugin to look for a useful header or similar which can be used to distinguish the saved and the normal case. One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you switch a node to activation disabled, mod_jk will not send requests there, that have no session id (and of course also not when the session route points to another node). But the old cookie requests might still go there. Yes, this is what we would normally do. For that you can use the feature, that mod_jk forwards the activation state to the Tomcat node. The node can then decide on itself, whether it will handle a request coming in with an invalid session id, or for example clears the session cookie and does a self-referential redirect, which then by mod_jk is balanced on the fully enabled nodes. This sounds like a promising technique. I was thinking we'd just tell the Tomcat node directly (e.g. set a context-scoped flag) that it was disabled, but having AJP forward that information would be even better, so the state can be managed entirely by the status worker on the httpd side. This logic can be put into a servlet filter. I'm not sure it can be in a Filter because of the interaction with the saved-request features described above. If in a Filter, the request would be saved before the Filter has a chance to see it, then authentication would take place, etc. I think this has to be in a Valve, and it has to happen before the AuthenticatorValve sees the request. Do you see a way around using a Valve? Assuming that such a Valve would be required, I think we should provide one with Tomcat. I'd be happy to write such a Valve. Can't comment because I don't know what exactly the saved request feature means, resp. how it works. Regards, Rainer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail:
Security Manager Exception
On 7/22/2014 11:04 AM, George Sexton wrote: I'm using Tomcat 7.0.54 with the security manager. I'm getting an exception I don't understand: 2014-07-22 09:27:03,934 [http-bio-80-exec-64] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[somehostname.mhsoftware.com].[/].[jsp]- Servlet.service() for servlet [jsp] in context with path [] threw exception [java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)] with root cause java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader) at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.ClassLoader.checkClassLoaderPermission(Unknown Source) at java.lang.ClassLoader.getParent(Unknown Source) at org.apache.juli.ClassLoaderLogManager.findProperty(ClassLoaderLogManager.java:295) at org.apache.juli.ClassLoaderLogManager.getProperty(ClassLoaderLogManager.java:266) at org.apache.juli.ClassLoaderLogManager.addLogger(ClassLoaderLogManager.java:144) at java.util.logging.LogManager.demandLogger(Unknown Source) at java.util.logging.Logger.demandLogger(Unknown Source) at java.util.logging.Logger.getLogger(Unknown Source) at com.sun.mail.util.MailLogger.init(MailLogger.java:115) at javax.mail.Session.initLogger(Session.java:226) at javax.mail.Session.init(Session.java:210) at javax.mail.Session.getInstance(Session.java:247) at com.MHSoftware.net.mail.MHMail.sendSMTP(MHMail.java:470) Line 144 of ClassLoaderLogManager is the addLogger method trying to read the .level property for the logger being created. The catalina.policy is pretty much the stock one. I'm confused because the catalina.policy has: grant codeBase file:${catalina.home}/bin/tomcat-juli.jar { permission java.lang.RuntimePermission getClassLoader; The page in question that's erroring out is a JSP that's calling a per-context jar. The hierarchy looks something like: JSP - context/WEB-INF/lib/jar Class File - $CATALINA_BASE/lib/ MH Software.jar - $CATALINA_BASE javax.mail.jar - $CATALINA_HOME/bin/tomcat-juli.jar $CATALINA_BASE/lib, has the grant for java.security.AllPermission; I don't know if this makes a difference, but I'm using log4j, and following the instructions here: http://tomcat.apache.org/tomcat-7.0-doc/logging.html#Using_Log4j I've made $CATALINA_BASE/conf/logging.properties an empty file. Finally, it SEEMS to only be happening in JSP files. calls directly from classes in the context jar file don't seem to be failing. If anyone could point me in the right direction, I would really appreciate it. Have you granted permissions to the classes in WEB-INF? -Terence Bandoian - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 11:23 AM, Rainer Jung wrote: On 23.07.2014 16:37, Christopher Schultz wrote: On 7/18/14, 12:13 PM, Rainer Jung wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. Whatever saved exactly means: if you can identify that situation in terms of any part of the request (e.g. something in the referer header etc.), you can add that as a positive or negative condition via RewriteCond (or the 2.4 unified expression parser) and set JK_STICKY_IGNORE in a RewriteRule that does not change the URI, only sets the variable and also only of the RewriteConds apply. You'd have to analyze the request-response stream e.g. with a browser plugin to look for a useful header or similar which can be used to distinguish the saved and the normal case. When I say saved I mean this workflow: 1. User requests a protected resource 2. Container saves the request (which creates a new session), presents the login screen 3. User authenticates 4. User is redirected to request saved in step #1 One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you switch a node to activation disabled, mod_jk will not send requests there, that have no session id (and of course also not when the session route points to another node). But the old cookie requests might still go there. Yes, this is what we would normally do. For that you can use the feature, that mod_jk forwards the activation state to the Tomcat node. The node can then decide on itself, whether it will handle a request coming in with an invalid session id, or for example clears the session cookie and does a self-referential redirect, which then by mod_jk is balanced on the fully enabled nodes. This sounds like a promising technique. I was thinking we'd just tell the Tomcat node directly (e.g. set a context-scoped flag) that it was disabled, but having AJP forward that information would be even better, so the state can be managed entirely by the status worker on the httpd side. This logic can be put into a servlet filter. I'm not sure it can be in a Filter because of the interaction with the saved-request features described above. If in a Filter, the request would be saved before the Filter has a chance to see it, then authentication would take place, etc. I think this has to be in a Valve, and it has to happen before the AuthenticatorValve sees the request. Do you see a way around using a
Re: mod_jk and session stickiness
Am 23.07.2014 um 17:59 schrieb Christopher Schultz: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 11:23 AM, Rainer Jung wrote: On 23.07.2014 16:37, Christopher Schultz wrote: On 7/18/14, 12:13 PM, Rainer Jung wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. Whatever saved exactly means: if you can identify that situation in terms of any part of the request (e.g. something in the referer header etc.), you can add that as a positive or negative condition via RewriteCond (or the 2.4 unified expression parser) and set JK_STICKY_IGNORE in a RewriteRule that does not change the URI, only sets the variable and also only of the RewriteConds apply. You'd have to analyze the request-response stream e.g. with a browser plugin to look for a useful header or similar which can be used to distinguish the saved and the normal case. When I say saved I mean this workflow: 1. User requests a protected resource 2. Container saves the request (which creates a new session), presents the login screen 3. User authenticates 4. User is redirected to request saved in step #1 So where's the interaction with putting a JK_STICKY_IGNORE on the login page if directly retrieved? The above sequence of steps does not retrieve the login page from the outside via its real URL, e.g. /login, does it? That env var is only useful for URIs for which you know that they either don't need a session (unprotected static content) or will start a new session (login page accessed by URI). The other case, a request with an invalid session ID accessing a tomcat instance with activation disabled can IMHO be handled by a filter that - checks whether the request has a valid session using getSession(false), if it has one, let the request proceed - checks activation state, if active, let the request proceed - checks the request method, if not GET, let the request proceed - otherwise: - set the session cookie, e.g. JSESSIONID the an empty value - issue an external redirect to the same request URL - optional redirect loop detection: add a query string param or cookie that gets the local jvmRoute appended during each redirect. Before doing the redirect, check that the local jvmRoute is not already part of that token (we have already been here before) This would not really interfere with your saved requests: they would get a redirect which the browser follwos automatically and after that you will observe the normal behavior. One option we have here is to provide separate URLs for regular logins versus the saved-request logins mentioned above: that would probably solve both problems. 2) Improve handling of sessions for node with activation disabled If you
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 1:49 PM, Rainer Jung wrote: Am 23.07.2014 um 17:59 schrieb Christopher Schultz: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 11:23 AM, Rainer Jung wrote: On 23.07.2014 16:37, Christopher Schultz wrote: On 7/18/14, 12:13 PM, Rainer Jung wrote: On 17.06.2014 16:43, Christopher Schultz wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 All, I've been using sticky sessions with mod_jk and I can see that there is a bit of a problem when attempting to take a backend Tomcat server out of load-balanced rotation: a user who never (or rarely) restarts their web browser will keep the same JSESSIONID cookie forever and therefore end up with the same backend server whether it has been disabled or not. Quick series of events: 1. User visits load-balancer and gets a randomly-assigned backend server/route. We'll call this route X. The JSESSIONID cookie set by the backend server is therefore foo.X. 2. User's requests are routed by mod_jk to route X. 3. Route X is disabled using mod_jk's status worker 4. User's session on server X expires. [Technically, 3 and 4 can happen in either order] 5. User makes a new request to the load-balancer, and mod_jk sees the JSESSIONID cookie still set to foo.X. mod_jk sends the request to route X which allows the user to login, etc. Thus, it takes more time than necessary to bleed all the traffic from route X for maintenance, etc. Is there a way for mod_jk to ask route X if the session is *still* valid? It seems that mod_jk will not re-route a request that looks like it's got a valid session id to a new (active) backend server unless the backend server X is actually down. Any ideas? Not exactly what you want, but you can build something around it: 1) Switch off stickyness for specific URLs If you know that users will come via specific URLs, like a login page, and you want that page to be handled non-sticky to optimize load balancing even if users have an old cookie, you can do that by setting the Apache envvar JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on: http://tomcat.apache.org/connectors-doc/reference/apache.html This seems like a reasonable way to do things, except that we still want to support requests to protected resources being saved and redirected to the login page. If we did this (JK_STICKY_IGNORE), then we'd end up forgetting the saved request (because the client would be re-balanced to another node for the login page) and ending up with a (useless) session on the node we are trying to take down. We'd like to retain the request-saving capabilities of the container. Whatever saved exactly means: if you can identify that situation in terms of any part of the request (e.g. something in the referer header etc.), you can add that as a positive or negative condition via RewriteCond (or the 2.4 unified expression parser) and set JK_STICKY_IGNORE in a RewriteRule that does not change the URI, only sets the variable and also only of the RewriteConds apply. You'd have to analyze the request-response stream e.g. with a browser plugin to look for a useful header or similar which can be used to distinguish the saved and the normal case. When I say saved I mean this workflow: 1. User requests a protected resource 2. Container saves the request (which creates a new session), presents the login screen 3. User authenticates 4. User is redirected to request saved in step #1 So where's the interaction with putting a JK_STICKY_IGNORE on the login page if directly retrieved? No problem there. The above sequence of steps does not retrieve the login page from the outside via its real URL, e.g. /login, does it? Yes, it does: the request in #2 results in a *redirect* to the login page. Thus, the saved request would be lost if we stripped the stickiness of the request. That env var is only useful for URIs for which you know that they either don't need a session (unprotected static content) or will start a new session (login page accessed by URI). That why I think we might want to start to use a different URI for regular logins versus logins prompted by the container (those that are for saved requests). The above poses the following problem: users with expired session ids will create saved request sessions on a node that should not be used, then they will be redirected to another node in the cluster, thereby losing the saved session. I'd like to avoid both parts of that problem and I believe it can be done with a Valve (but not a Filter). The other case, a request with an invalid session ID accessing a tomcat instance with activation disabled can IMHO be handled by a filter that - checks whether the request has a valid session using getSession(false), if it has one, let the request proceed - checks activation state, if active, let the request proceed -
Re: mod_jk and session stickiness
Am 23.07.2014 um 21:03 schrieb Christopher Schultz: On 7/23/14, 1:49 PM, Rainer Jung wrote: The other case, a request with an invalid session ID accessing a tomcat instance with activation disabled can IMHO be handled by a filter that - checks whether the request has a valid session using getSession(false), if it has one, let the request proceed - checks activation state, if active, let the request proceed - checks the request method, if not GET, let the request proceed - otherwise: - set the session cookie, e.g. JSESSIONID the an empty value - issue an external redirect to the same request URL - optional redirect loop detection: add a query string param or cookie that gets the local jvmRoute appended during each redirect. Before doing the redirect, check that the local jvmRoute is not already part of that token (we have already been here before) This would not really interfere with your saved requests: they would get a redirect which the browser follwos automatically and after that you will observe the normal behavior. This is exactly what I have implemented -- as a Filter since we can insert it before SecurityFilter intercepts the requests -- and my tests suggest that it will work correctly. I added code to strip-out any ;jsessionid path parameter from the URL ACK if it exists, but haven't done any of the redirect loop detection (yet). I think the loop detection is going to have to keep a running list of visited nodes which, in large clusters, could grow very large especially if the node names are long. I'll post my code when it's a little more featureful. As long as nothing goes wrong, the first redirect - having no more session info - should not end up in getting redirected as well, because it should only be send to an active node by mod_jk. So you can even stop redirecting if you detect, that it already happened once. For a large cluster that might be better. Multiple might happen (didn't check the code), if all active members are in error state. Even then one would not like to produce many of those redirects for one request, so again, only allowing one redirect might be the right solution. Regards, Rainer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: mod_jk and session stickiness
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Rainer, On 7/23/14, 4:10 PM, Rainer Jung wrote: Am 23.07.2014 um 21:03 schrieb Christopher Schultz: On 7/23/14, 1:49 PM, Rainer Jung wrote: The other case, a request with an invalid session ID accessing a tomcat instance with activation disabled can IMHO be handled by a filter that - checks whether the request has a valid session using getSession(false), if it has one, let the request proceed - checks activation state, if active, let the request proceed - checks the request method, if not GET, let the request proceed - otherwise: - set the session cookie, e.g. JSESSIONID the an empty value - issue an external redirect to the same request URL - optional redirect loop detection: add a query string param or cookie that gets the local jvmRoute appended during each redirect. Before doing the redirect, check that the local jvmRoute is not already part of that token (we have already been here before) This would not really interfere with your saved requests: they would get a redirect which the browser follwos automatically and after that you will observe the normal behavior. This is exactly what I have implemented -- as a Filter since we can insert it before SecurityFilter intercepts the requests -- and my tests suggest that it will work correctly. I added code to strip-out any ;jsessionid path parameter from the URL ACK if it exists, but haven't done any of the redirect loop detection (yet). I think the loop detection is going to have to keep a running list of visited nodes which, in large clusters, could grow very large especially if the node names are long. I'll post my code when it's a little more featureful. As long as nothing goes wrong, the first redirect - having no more session info - should not end up in getting redirected as well, because it should only be send to an active node by mod_jk. So you can even stop redirecting if you detect, that it already happened once. For a large cluster that might be better. Multiple might happen (didn't check the code), if all active members are in error state. Even then one would not like to produce many of those redirects for one request, so again, only allowing one redirect might be the right solution. That's a good thought, and simplifies things. The request parameter could then just be a boolean flag and not actually identify the node that produced the redirect: any node considering redirecting simply would not redirect if that flag had been set. - -chris -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJT0CW9AAoJEBzwKT+lPKRYPlsQAJUFuK+nBO3jty473UgIqZCK of3S+yux9FxzowMUCIkwnXi61zazDJqOmEuPO/qvWdmxPb9/cEj8U7h9V8lC04zI zc3Z0Fq4m9mMgmMmhi4MEu2vXuW01pw6YaePxyMsP0LqNxCb6xvp0UkQsBDCEd46 X7GJpt3q1MreFCD4lPYqDhiKm5oR3HqsJC+CmajpcfWMTg5VT4k8jX9HM5xS1p7N bvCYbxFB8I7/QMOG7cQ2+Dok5C9h/j9MGQvlL3UXCgWS7LRLPBFNzoZn9UfUhZNz VsEWJspIn8KETP02AGV5vFd00ydpi53ZwlySUwjznrNixrPt7R4O+yhR5dB8tyNm Yx8NA1rtWKVoKOeBiB/r3WBnNWg2f+AzND92DmaAvRZevSoOK1OY6oeAYnoBYVg6 2Oipes/dUEalq+oeNqAh2/jAmzo195MuOfo/vCDwGLTE26j+sjEDFRqKOcnR0EmO g2Y13hFa60ueswrI5Ixq5beFz0SRd2St6V6FBQRl7+7TRPI9wwEbYnZwT3iCL4qT 8jWP7XvWWOySLM7rEKldbcVpEElobWVtfhhjLWjQWhjXgnsdOAj0elfAzWAS+kFq YeKJRHCbi8dka5TGv31fhfGSNgTnlUyMaZ+J+idzCNw0O+yBgIgZWPMPUsC9RqDq 5gBLNkXTUQb+VSzBbteQ =Uwwp -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: Tomcat 7.0.54 Slow Unpack and Deploy
Process explorer, select columns, Process I/O, delta total bytes might show the story. http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Christopher Schultz wrote: - -1 CPU +1 I/O