简体   繁体   English

有关Servlet应用程序中的连接池的一些问题

[英]Some questions about connection pooling in a servlet application

I'm new to java in web application design and I'm getting surprised how many things I don't now. 我是Web应用程序设计中Java的新手 ,但我感到惊讶的是我现在没有多少东西。
In particular I'm having problems in understending how servlet containers manage resources like connection pooling classes. 特别是在理解servlet容器如何管理资源(如连接池类)时遇到问题。

Assuming that I choose a pooling library (let's say c3p0), I read that there are many ways to use and manage the connection pooling classes. 假设我选择了一个池库(比方说c3p0),我读到有很多使用和管理连接池类的方法。

For instance in many examples I saw that a certain class (let's say ComboPooledDataSource) is instantiated in the init() method of the servlet and here I'm getting a bit confusing. 例如,在许多示例中,我看到某个类(例如ComboPooledDataSource)在servlet的init()方法中实例化,在这里我有点困惑。 I mean, I think that a connection pooling system must exist and have a separate life with respect to all the servlets that will need a connection, otherwise it make no sense. 我的意思是,我认为一个连接池系统必须存在,并且对于需要连接的所有servlet都有单独的生命,否则就没有意义。 So I think that the class below may be a Thread that is started once from the first servlet that call the init method and then it continues to exist until someone doesn not interrupt it. 因此,我认为下面的类可能是一个线程,该线程从调用init方法的第一个servlet启动一次,然后一直存在,直到有人不中断它为止。 Is that correct? 那是对的吗? If not how does it work? 如果没有,它如何运作?

Anyway once I start this class , is it shared among all the servlets in the context (I mean all the servlets that call it in the init method)? 无论如何,一旦启动此类,它是否在上下文中的所有servlet之间共享(我的意思是在init方法中调用它的所有servlet)?

Other examples set up the connection pooling system as a resource by for instance defining it in the context.xml and then any servlet that want a connection just have to access it via JNDI (JNDI is correct?). 其他示例将连接池系统设置为资源,例如在context.xml中定义它,然后任何需要连接的servlet都必须通过JNDI访问它(JNDI是正确的吗?)。 What i understood (or I think to) is that in this case the thread that will execute the pooling system is started when the application is started and each servlet can access it when it wants to. 我了解(或我认为)的是,在这种情况下,将在应用程序启动时启动执行池系统的线程,并且每个Servlet都可以在需要时访问它。 Is that correct? 那是对的吗?

In this case can I modify the connection pooling system properties by a servlet or a background thread runtime? 在这种情况下,我可以通过servlet或后台线程运行时来修改连接池系统属性吗? (for example if I want to change the number of connections as a function of the statistics on the number of requests and so on) (例如,如果我想根据请求数的统计信息来更改连接数等)

If I want to create different pools (for example I want to subdivide the database access to N different databases or I want to access using different usernames ) do I need to create as many resources as are the different kind of connection I want? 如果我想创建不同的池(例如,我想将数据库访问权限细分为N个不同的数据库,或者我想使用不同的用户名进行访问),是否需要创建与我想要的其他类型的连接一样多的资源?

Is there a "better" way among these two or they are equivalent? 这两者之间是否存在“更好”的方式,或者它们是等效的?

It comes down to ease of use of the webapp and (Tomcat) server maintenance. 它归结为易于使用的Web应用程序和(Tomcat)服务器维护。
You describe 2 use cases: 您描述了2个用例:

  1. a connection pool used by one webapp 一个webapp使用的连接池
  2. a connection pool shared between webapps Webapp之间共享的连接池

The first case is suitable for "ease of use": you can drop the war-file in any Tomcat server and it will work (eg Jenkins delivers such a war-file) since the webapp contains all the code needed to access a database. 第一种情况适合于“易用性”:您可以将war文件放在任何Tomcat服务器中,并且由于web应用程序包含访问数据库所需的所有代码,因此它可以工作(例如Jenkins提供了这样的war文件)。 No need to change the configuration of the Tomcat server and restart it. 无需更改Tomcat服务器的配置并重新启动它。
If I can, I like to deliver these kind of war-files since less things can go wrong (eg no clashes with configuration for other webapps). 如果可以的话,我喜欢提供这类war文件,因为出错的地方更少了(例如,与其他Web应用程序的配置没有冲突)。 You can take it a step further by delivering Tomcat embedded with an application (so you don't need a Tomcat server to start with, an example project is here ). 您可以通过提供嵌入有应用程序的Tomcat来进一步采取措施(因此,您不需要Tomcat服务器作为开始, 此处为示例项目)。

Note that opening a database connection pool (preferably via ServletContextListener.contextInitialized , not a servlet) and closing it (via contextDestroyed ) does not involve starting and stopping a thread. 请注意,打开数据库连接池(最好通过ServletContextListener.contextInitialized而不是servlet)并关闭它(通过contextDestroyed )并不涉及启动和停止线程。 The pool implementation may decide to start a background thread (eg to remove idle and/or abandoned connections), but it does not have to. 池实现可以决定启动后台线程(例如,删除空闲和/或放弃的连接),但是不必这样做。

The second case is suitable for several webapps that share a common ground. 第二种情况适用于具有共同点的几个Web应用程序。 For example, if several webapps all running in the same Tomcat server all use the same database, it saves time and effort if the Tomcat server already has a connection pool available for the different webapps (via JNDI). 例如,如果所有都在同一个Tomcat服务器上运行的多个Web应用程序都使用相同的数据库,如果Tomcat服务器已经具有可用于不同Web应用程序的连接池(通过JNDI),则可以节省时间和精力。 The Tomcat server can contain the JDBC driver software and connection pool software in the "lib" directory and configuration is done once in the context.xml of the server. Tomcat服务器可以在“ lib”目录中包含JDBC驱动程序软件和连接池软件,并且只需在服务器的context.xml中进行一次配置即可。 If the database changes or different (patched) software components are required, only the tomcat server needs to be updated and all the webapps can remain the same. 如果数据库更改或需要不同的(已修补的)软件组件,则仅需要更新tomcat服务器,并且所有Web应用程序都可以保持不变。 In this case, updating the Tomcat server instead of each webapp is a lot easier. 在这种情况下,更新Tomcat服务器而不是每个Web应用程序要容易得多。

The second case is also more suitable for monitoring: there is a good chance you can monitor the connection pool via JMX. 第二种情况也更适合监视:您很有可能可以通过JMX监视连接池。 This kind of monitoring may not be available in the first case. 这种监视可能在第一种情况下不可用。

Changing "the number of connections as a function of the statistics on the number of requests " is not needed with connection pools: you set a maximum amount of connections to use and a timeout to remove idle connections. 连接池不需要更改“根据请求数统计信息来确定连接数”:您可以设置要使用的最大连接数,并可以设置超时来删除空闲连接。 The connection pool will then grow and shrink with the number of requests. 然后,连接池将随着请求数量的增长和收缩。

Subdividing the database access to N different databases would require a different connection pool for each database, unless this is "read-only" in which case you could also use a load-balancer. 将数据库访问权限细分为N个不同的数据库,每个数据库将需要一个不同的连接池,除非这是“只读”的,在这种情况下,您还可以使用负载平衡器。

Access using different usernames is a bit tricky. 使用不同的用户名进行访问有些棘手。 I read in another question (which I cannot find anymore, sorry) that you can change the schema during runtime, but changing username/password might require a new connection in which case connection pooling is out. 我读了另一个问题(抱歉,我现在找不到了),您可以在运行时更改架构,但是更改用户名/密码可能需要新的连接,在这种情况下,连接池将消失。

Are you using Tomcat to run your servlets? 您是否正在使用Tomcat运行servlet? Tomcat 7 has a new pooling solution that you could investigate. Tomcat 7具有您可以研究的新池化解决方案。 Tomcat also includes the dbcp libraries you can use them by setting the factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory". Tomcat还包括dbcp库,您可以通过设置factory =“ org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory”来使用它们。 The DBCP pools are self managed and you can define the configuration values in the context.xml file I am not aware of how to change these values on the fly. DBCP池是自我管理的,您可以在context.xml文件中定义配置值,我不知道如何动态更改这些值。 I believe the Tomcat 7 pool use the same configuration as the DBCP with a couple of added options to make the conversion between the two simple. 我相信Tomcat 7池使用与DBCP相同的配置,并带有几个添加的选项,以使两者之间的转换变得简单。 We use DBCP in all our applications and have not experienced problems so I have not used the Tomcat 7 pooling. 我们在所有应用程序中都使用DBCP,并且没有遇到问题,因此我没有使用Tomcat 7池。 I am thinking you would need to create many pools to handle most of your requirements. 我认为您需要创建许多池来处理大多数需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM