Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Mark Thomas

On 28/05/2024 16:26, Eric Robinson wrote:




Took a bunch of thread and heap dumps during today's painful debacle. Will send 
a link to those as soon as I can.


Thanks. I have them. I have taken a look and I am starting to form a 
theory. To help with that I have a couple of questions.


1. Could you tell me where the JDBC driver JAR is located. Is it in 
WEB-INF/lib for the web application(s) or is it in $CATALINA_BASE/lib ?


2. How big is WEB-INF/lib for the web application(s)? How many JAR files 
and what is the total size on disk of that directory?


3. Would you be prepared to run Tomcat in production with a binary patch 
(against 9.0.80). This would involve placing one or more class files in 
the right directory structure under $CATALINA_BASE/lib either to collect 
additional debug logging or to test a potential fix.




Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Mark Thomas

On 29/05/2024 10:26, Mark Thomas wrote:

On 28/05/2024 16:26, Eric Robinson wrote:



Took a bunch of thread and heap dumps during today's painful debacle. 
Will send a link to those as soon as I can.


Thanks. I have them. I have taken a look and I am starting to form a 
theory. To help with that I have a couple of questions.


Scratch that. I've found some further information in the data Eric sent 
me off-list and I am now pretty sure what is going on.


There are multiple web applications deployed on the servers. I assume 
there are related but it actually doesn't matter.


At least one application is using the "new" MySQL JDBC driver:
com.mysql.cj.jdbc.Driver

At least one application is using the "old" MySQL JDBC driver:
com.mysql.jdbc.Driver


(I've told Eric off-list which application is using which).

There are, therefore, two drivers registered with the java.sql.DriverManager


The web applications are not using connection pooling. Or, if they are 
using it, they are using it very inefficiently. The result is that there 
is a high volume of calls to create new database connections.


This is problem number 1. Creating a database connection is expensive. 
That is why the concept of database connection pooling was created.



When a new connection is created, java.sql.DriverManager iterates over 
the list of registered drivers and

- tests to see if the current class loader can see the driver
- if yes, tests to see if that driver can service the connection url
- if yes, use it and exit
- go on to the next driver in the list and repeat

The test to see if the current class loader can use the driver is, 
essentially, to call Class.forName(driver.getClass(), true, classloader)


And that is problem number 2. That check is expensive if the current 
class loader can't load that driver.



It is also problem number 3. The reason it is expensive is that class 
loaders don't cache misses so if a web application has a large number of 
JARs, they all get scanned every time the DriverManager tries to create 
a new connection.



The slowness occurs in the web application that depends on the second 
JDBC driver in DriverManager's list. When a request that requires a 
database connection is received, there is a short delay while the web 
application tries, and fails, to load the first JDBC driver in the list. 
Class loading is synchronized on class name being loaded so if any other 
requests also need a database connection, they have to wait for this 
request to finish the search for the JDBC driver before they can 
continue. This creates a bottleneck. Requests are essentially rate 
limited to 1 request that requires a database connection per however 
long it takes to scan every JAR in the web application for a class that 
isn't there. If the average rate of requests exceeds this rate limit 
then a queue is going to build up and it won't subside until the average 
rate of requests falls below this rate limit.




Problem number 1 is an application issue. It should be using pooling. It 
seems unlikely that we'll see a solution from the application vendor and 
- even if the vendor does commit to a fix - I suspect it will take months.



Problem number 2 is a JRE issue. I think there are potentially more 
efficient ways to perform that check but that needs research as things 
like OSGI and JPMS make class loading more complicated.



Problem number 3 is a Tomcat issue. It should be relatively easy to 
start caching misses (i.e. this class loader cannot load this class) and 
save the time spent repeatedly scanning JARs for a class that isn't there.



I intend to wok on a patch for Tomcat that will add caching that should 
speed things up considerably. I hope to have something for Eric to test 
today but it might take me until tomorrow as I have a few other time 
critical things fighting to get tot he top of my TODO list at the moment.



Moving the JDBC driver JARs from WEB-INF/lib to $CATALINA_BASE/lib may 
also be a short-term fix but is likely to create problems if the same 
JAR ever exists in both locations at the same time.



Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Query integrating Apache Tomcat with Azure Sentinel via a data connector on Azure Sentinel

2024-05-29 Thread Kele Masemola
Good day ,

We are trying to integrate Apache Tomcat with Azure Sentinel, we realized that 
the agent that needs to be installed on our Apache Tomcat machines will be 
deprecated in August 2024 and as such we would like to find out if there is 
another agent that will be provided to Microsoft as part of the Apache Tomcat 
data connector on Azure Sentinel?

If there will be a new agent provided, please advise on timeframes of when it 
will be available on Azure Sentinel.

If there is no new agent that will be provided from an Apache Tomcat 
perspective, could you please advise if the current available agent on Azure 
Sentinel will still be able to ingest logs accordingly after it has been 
deprecated?

Your assistance with this will be greatly appreciated.

Regards
Kele Masemola


Re: Query integrating Apache Tomcat with Azure Sentinel via a data connector on Azure Sentinel

2024-05-29 Thread Olaf Kock

Hi Kele,

On 29.05.24 13:53, Kele Masemola wrote:

Good day ,

We are trying to integrate Apache Tomcat with Azure Sentinel, we realized that 
the agent that needs to be installed on our Apache Tomcat machines will be 
deprecated in August 2024 and as such we would like to find out if there is 
another agent that will be provided to Microsoft as part of the Apache Tomcat 
data connector on Azure Sentinel?

If there will be a new agent provided, please advise on timeframes of when it 
will be available on Azure Sentinel.

If there is no new agent that will be provided from an Apache Tomcat 
perspective, could you please advise if the current available agent on Azure 
Sentinel will still be able to ingest logs accordingly after it has been 
deprecated?


The documentation
(https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/sentinel/data-connectors/apache-tomcat.md)
and your statement ("needs to be installed") looks like this is not a
Tomcat feature, but an extra plugin by Microsoft (in fact, the
documentation lists: "Supported by: Microsoft Corporation".

From that point of view, I don't expect anything to be provided "from
an Apache Tomcat perspective". It has never been provided in the first
place. You might find more information in Microsoft's statements about
the deprecation of their own component, and what they recommend to use
instead.

(Somebody correct me if I'm wrong and there's something on the roadmap,
or already in and I've missed it)

Olaf


RE: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Eric Robinson
Hi Mark,


> -Original Message-
> From: Mark Thomas 
> Sent: Wednesday, May 29, 2024 5:35 AM
> To: users@tomcat.apache.org
> Subject: Re: Database Connection Requests Initiated but Not Sent on the Wire
> (Some, Not All)
>
> On 29/05/2024 10:26, Mark Thomas wrote:
> > On 28/05/2024 16:26, Eric Robinson wrote:
> >
> > 
> >
> >> Took a bunch of thread and heap dumps during today's painful debacle.
> >> Will send a link to those as soon as I can.
> >
> > Thanks. I have them. I have taken a look and I am starting to form a
> > theory. To help with that I have a couple of questions.
>
> Scratch that. I've found some further information in the data Eric sent me 
> off-
> list and I am now pretty sure what is going on.
>
> There are multiple web applications deployed on the servers. I assume there 
> are
> related but it actually doesn't matter.
>
> At least one application is using the "new" MySQL JDBC driver:
> com.mysql.cj.jdbc.Driver
>
> At least one application is using the "old" MySQL JDBC driver:
> com.mysql.jdbc.Driver
>
>
> (I've told Eric off-list which application is using which).
>
> There are, therefore, two drivers registered with the java.sql.DriverManager
>
>
> The web applications are not using connection pooling. Or, if they are using 
> it,
> they are using it very inefficiently. The result is that there is a high 
> volume of
> calls to create new database connections.
>
> This is problem number 1. Creating a database connection is expensive.
> That is why the concept of database connection pooling was created.
>
>
> When a new connection is created, java.sql.DriverManager iterates over the 
> list
> of registered drivers and
> - tests to see if the current class loader can see the driver
> - if yes, tests to see if that driver can service the connection url
> - if yes, use it and exit
> - go on to the next driver in the list and repeat
>
> The test to see if the current class loader can use the driver is, 
> essentially, to
> call Class.forName(driver.getClass(), true, classloader)
>
> And that is problem number 2. That check is expensive if the current class
> loader can't load that driver.
>
>
> It is also problem number 3. The reason it is expensive is that class
> loaders don't cache misses so if a web application has a large number of
> JARs, they all get scanned every time the DriverManager tries to create
> a new connection.
>
>
> The slowness occurs in the web application that depends on the second
> JDBC driver in DriverManager's list. When a request that requires a
> database connection is received, there is a short delay while the web
> application tries, and fails, to load the first JDBC driver in the list.
> Class loading is synchronized on class name being loaded so if any other
> requests also need a database connection, they have to wait for this
> request to finish the search for the JDBC driver before they can
> continue. This creates a bottleneck. Requests are essentially rate
> limited to 1 request that requires a database connection per however
> long it takes to scan every JAR in the web application for a class that
> isn't there. If the average rate of requests exceeds this rate limit
> then a queue is going to build up and it won't subside until the average
> rate of requests falls below this rate limit.
>
>
>
> Problem number 1 is an application issue. It should be using pooling. It
> seems unlikely that we'll see a solution from the application vendor and
> - even if the vendor does commit to a fix - I suspect it will take months.
>
>
> Problem number 2 is a JRE issue. I think there are potentially more
> efficient ways to perform that check but that needs research as things
> like OSGI and JPMS make class loading more complicated.
>
>
> Problem number 3 is a Tomcat issue. It should be relatively easy to
> start caching misses (i.e. this class loader cannot load this class) and
> save the time spent repeatedly scanning JARs for a class that isn't there.
>
>
> I intend to wok on a patch for Tomcat that will add caching that should
> speed things up considerably. I hope to have something for Eric to test
> today but it might take me until tomorrow as I have a few other time
> critical things fighting to get tot he top of my TODO list at the moment.
>
>
> Moving the JDBC driver JARs from WEB-INF/lib to $CATALINA_BASE/lib may
> also be a short-term fix but is likely to create problems if the same
> JAR ever exists in both locations at the same time.
>
>
> Mark
>

That's some great sleuthing and the explanation makes a ton of sense. It leaves 
me with a couple of questions.

If you are correct, then it follows that historic activity has been hovering 
dangerously near the threshold where this symptom would manifest. Within the 
past month, an unknown change in the system climate now causes an uptick in the 
number of DB requests/second at roughly the same time daily (with occasional 
exceptions) and the system begins to trip over its own feet. I haven't seen 
anyth

RE: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Eric Robinson
Mark,

A few other thoughts come to mind. See below.

> -Original Message-
> From: Eric Robinson 
> Sent: Wednesday, May 29, 2024 7:39 AM
> To: Tomcat Users List 
> Subject: RE: Database Connection Requests Initiated but Not Sent on the Wire
> (Some, Not All)
>
> Hi Mark,
>
>
> > -Original Message-
> > From: Mark Thomas 
> > Sent: Wednesday, May 29, 2024 5:35 AM
> > To: users@tomcat.apache.org
> > Subject: Re: Database Connection Requests Initiated but Not Sent on
> > the Wire (Some, Not All)
> >
> > On 29/05/2024 10:26, Mark Thomas wrote:
> > > On 28/05/2024 16:26, Eric Robinson wrote:
> > >
> > > 
> > >
> > >> Took a bunch of thread and heap dumps during today's painful debacle.
> > >> Will send a link to those as soon as I can.
> > >
> > > Thanks. I have them. I have taken a look and I am starting to form a
> > > theory. To help with that I have a couple of questions.
> >
> > Scratch that. I've found some further information in the data Eric
> > sent me off- list and I am now pretty sure what is going on.
> >
> > There are multiple web applications deployed on the servers. I assume
> > there are related but it actually doesn't matter.
> >
> > At least one application is using the "new" MySQL JDBC driver:
> > com.mysql.cj.jdbc.Driver
> >
> > At least one application is using the "old" MySQL JDBC driver:
> > com.mysql.jdbc.Driver
> >
> >
> > (I've told Eric off-list which application is using which).
> >
> > There are, therefore, two drivers registered with the
> > java.sql.DriverManager
> >
> >
> > The web applications are not using connection pooling. Or, if they are
> > using it, they are using it very inefficiently. The result is that
> > there is a high volume of calls to create new database connections.
> >
> > This is problem number 1. Creating a database connection is expensive.
> > That is why the concept of database connection pooling was created.
> >
> >
> > When a new connection is created, java.sql.DriverManager iterates over
> > the list of registered drivers and
> > - tests to see if the current class loader can see the driver
> > - if yes, tests to see if that driver can service the connection url
> > - if yes, use it and exit
> > - go on to the next driver in the list and repeat
> >
> > The test to see if the current class loader can use the driver is,
> > essentially, to call Class.forName(driver.getClass(), true,
> > classloader)
> >
> > And that is problem number 2. That check is expensive if the current
> > class loader can't load that driver.
> >
> >
> > It is also problem number 3. The reason it is expensive is that class
> > loaders don't cache misses so if a web application has a large number
> > of JARs, they all get scanned every time the DriverManager tries to
> > create a new connection.
> >

Maybe a potential solution is to have the class loader cache misses? Wait, I 
see you answered that further down...

> >
> > The slowness occurs in the web application that depends on the second
> > JDBC driver in DriverManager's list. When a request that requires a
> > database connection is received, there is a short delay while the web
> > application tries, and fails, to load the first JDBC driver in the list.
> > Class loading is synchronized on class name being loaded so if any
> > other requests also need a database connection, they have to wait for
> > this request to finish the search for the JDBC driver before they can
> > continue. This creates a bottleneck. Requests are essentially rate
> > limited to 1 request that requires a database connection per however
> > long it takes to scan every JAR in the web application for a class
> > that isn't there. If the average rate of requests exceeds this rate
> > limit then a queue is going to build up and it won't subside until the
> > average rate of requests falls below this rate limit.
> >
> >
> >
> > Problem number 1 is an application issue. It should be using pooling.
> > It seems unlikely that we'll see a solution from the application
> > vendor and
> > - even if the vendor does commit to a fix - I suspect it will take months.
> >

I believe your assessment is correct. How hard is it to enable pooling? Can it 
be bolted on, so to speak, through changes to the app context, such that the 
webapp itself does not necessarily need to implement special code?

> >
> > Problem number 2 is a JRE issue. I think there are potentially more
> > efficient ways to perform that check but that needs research as things
> > like OSGI and JPMS make class loading more complicated.
> >
> >
> > Problem number 3 is a Tomcat issue. It should be relatively easy to
> > start caching misses (i.e. this class loader cannot load this class)
> > and save the time spent repeatedly scanning JARs for a class that isn't 
> > there.
> >
> >
> > I intend to wok on a patch for Tomcat that will add caching that
> > should speed things up considerably. I hope to have something for Eric
> > to test today but it might take me until tomorrow as I have a few

Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Mark Thomas

On 29/05/2024 13:38, Eric Robinson wrote:

-Original Message-
From: Mark Thomas 





I intend to wok on a patch for Tomcat that will add caching that should
speed things up considerably. I hope to have something for Eric to test
today but it might take me until tomorrow as I have a few other time
critical things fighting to get tot he top of my TODO list at the moment.


Moving the JDBC driver JARs from WEB-INF/lib to $CATALINA_BASE/lib may
also be a short-term fix but is likely to create problems if the same
JAR ever exists in both locations at the same time.


Just an FYI. On further reflection, moving the JDBC driver JARs isn't 
going to help. Sorry. You'll need my fix.


Assuming, of course, you are willing to test a patch to address this on 
a production system.



That's some great sleuthing and the explanation makes a ton of sense. It leaves 
me with a couple of questions.

If you are correct, then it follows that historic activity has been hovering 
dangerously near the threshold where this symptom would manifest. Within the 
past month, an unknown change in the system climate now causes an uptick in the 
number of DB requests/second at roughly the same time daily (with occasional 
exceptions) and the system begins to trip over its own feet. I haven't seen 
anything in my Zabbix graphs that stood out as potentially problematic. Armed 
with this information, I am now taking a closer look.


Ack.


The natural next question is, what changed in the application or the users' 
workflow to push activity over the threshold? We'll dig into that.


Could be all sorts of things.

It might just have been coincidence the first time and now the users all 
request the data they need at the start of their day in case the problem 
happens again. And by doing that they cause the very problem they are 
trying to avoid.


Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Mark Thomas

On 29/05/2024 16:08, Eric Robinson wrote:


I believe your assessment is correct. How hard is it to enable pooling? Can it 
be bolted on, so to speak, through changes to the app context, such that the 
webapp itself does not necessarily need to implement special code?


It looks like - from the database configuration you provided earlier - 
there is an option to configure the database via JNDI. If you do that 
with Tomcat you will automatically get pooling. That might be something 
to follow up with the vendor. If you go that route, I'd recommend 
configuring the pool to remove abandoned connections to avoid any issues 
with connection leaks.


Not sure if all the web applications support a JNDI based configuration.




Would the problem be relieved if the vendor stuck to one driver?


Yes. That would avoid the attempt to load the "other" driver which is 
causing the delay.


Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



RE: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Eric Robinson
Hi Mark,


> -Original Message-
> From: Mark Thomas 
> Sent: Wednesday, May 29, 2024 10:10 AM
> To: users@tomcat.apache.org
> Subject: Re: Database Connection Requests Initiated but Not Sent on the Wire
> (Some, Not All)
>
> On 29/05/2024 13:38, Eric Robinson wrote:
> >> -Original Message-
> >> From: Mark Thomas 
>
> 
>
> >> I intend to wok on a patch for Tomcat that will add caching that
> >> should speed things up considerably. I hope to have something for
> >> Eric to test today but it might take me until tomorrow as I have a
> >> few other time critical things fighting to get tot he top of my TODO list 
> >> at the
> moment.
> >>
> >>
> >> Moving the JDBC driver JARs from WEB-INF/lib to $CATALINA_BASE/lib
> >> may also be a short-term fix but is likely to create problems if the
> >> same JAR ever exists in both locations at the same time.
>
> Just an FYI. On further reflection, moving the JDBC driver JARs isn't going to
> help. Sorry. You'll need my fix.
>
> Assuming, of course, you are willing to test a patch to address this on a
> production system.
>

Absolutely. We and the users are ready to do what it takes.

> > That's some great sleuthing and the explanation makes a ton of sense. It
> leaves me with a couple of questions.
> >
> > If you are correct, then it follows that historic activity has been hovering
> dangerously near the threshold where this symptom would manifest. Within the
> past month, an unknown change in the system climate now causes an uptick in
> the number of DB requests/second at roughly the same time daily (with
> occasional exceptions) and the system begins to trip over its own feet. I 
> haven't
> seen anything in my Zabbix graphs that stood out as potentially problematic.
> Armed with this information, I am now taking a closer look.
>
> Ack.
>
> > The natural next question is, what changed in the application or the users'
> workflow to push activity over the threshold? We'll dig into that.
>
> Could be all sorts of things.
>
> It might just have been coincidence the first time and now the users all 
> request
> the data they need at the start of their day in case the problem happens 
> again.
> And by doing that they cause the very problem they are trying to avoid.
>

One of the webapps is related to voice reminder messages that go out to people. 
The reminders go out sometime after 9 am, which tracks with the slowdowns.

> Mark
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org

Disclaimer : This email and any files transmitted with it are confidential and 
intended solely for intended recipients. If you are not the named addressee you 
should not disseminate, distribute, copy or alter this email. Any views or 
opinions presented in this email are solely those of the author and might not 
represent those of Physician Select Management. Warning: Although Physician 
Select Management has taken reasonable precautions to ensure no viruses are 
present in this email, the company cannot accept responsibility for any loss or 
damage arising from the use of this email or attachments.


RE: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-29 Thread Eric Robinson

> -Original Message-
> From: Mark Thomas 
> Sent: Wednesday, May 29, 2024 10:19 AM
> To: users@tomcat.apache.org
> Subject: Re: Database Connection Requests Initiated but Not Sent on the Wire
> (Some, Not All)
>
> On 29/05/2024 16:08, Eric Robinson wrote:
>
> > I believe your assessment is correct. How hard is it to enable pooling? Can 
> > it
> be bolted on, so to speak, through changes to the app context, such that the
> webapp itself does not necessarily need to implement special code?
>
> It looks like - from the database configuration you provided earlier - there 
> is an
> option to configure the database via JNDI. If you do that with Tomcat you will
> automatically get pooling. That might be something to follow up with the
> vendor. If you go that route, I'd recommend configuring the pool to remove
> abandoned connections to avoid any issues with connection leaks.
>

In reviewing live threads with Visual VM, I note that there are apparently 
threads related to cleaning up abandoned connections, and maybe even pooling?

The threads are:

mysql-cj-abandoned-connection-cleanup (2 of those)
OkHttp Connection Pool (2 of those)
OkHttp https://ps.pndsn.com (not sure what that is)


> Not sure if all the web applications support a JNDI based configuration.
>
> 
>
> > Would the problem be relieved if the vendor stuck to one driver?
>
> Yes. That would avoid the attempt to load the "other" driver which is causing
> the delay.
>
> Mark
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org

Disclaimer : This email and any files transmitted with it are confidential and 
intended solely for intended recipients. If you are not the named addressee you 
should not disseminate, distribute, copy or alter this email. Any views or 
opinions presented in this email are solely those of the author and might not 
represent those of Physician Select Management. Warning: Although Physician 
Select Management has taken reasonable precautions to ensure no viruses are 
present in this email, the company cannot accept responsibility for any loss or 
damage arising from the use of this email or attachments.