I have a verticle, which consumes a message from the event bus and processes it. I have a question as to when the JDBC connection should be closed. There are 2 approaches
Closing the connection once the message is processed. But this will be very expensive because I will open/close connection every time.
Trust that vertx will close the connection when the verticle is stopped/undeployed (which is literally never) and that there wont be any memory leaks as long as the connection is open. I will open the connection in the start() method, so that whenever there is a message it available.
On the other hand, If I have an elastic search backend and I am using the elastic search SDK, which has a specific method to close the client, when should the connection be really closed?
Use a connection pool, that will take away most of the cost of closing/opening connections. When using a connection pool, closing the connection returns it to the connection pool for re-use.
The basic usage pattern is:
try (Connection connection = dataSource.getConnection()) {
// use connection
}
At the end of the block the connection is closed, which - if dataSource has a connection pool - will make it available for re-use.
You can always put your clean up code in Stop() method of Verticle interface. It will be called when the verticle starts it's un-deploy procedure.
See Vert.x Docs
Related
So I read this article https://www.baeldung.com/httpclient-timeout and it says that connection timeout adds to its own penalty if the underlying service's DNS that httpclient tries to connect to has multiple IPs configured to it.
So if I have a connection timeout set to 100ms and the called service DNS has 5 IPs mapped to it then, I am looking at a max connection timeout of 500ms assuming what works is the last IP.
Is there a way to have a cap on this connection timeout regardless what the underlying service topology is as being a client, I will always be agnostic to it.
As far as I understood, you don't have a code-wise case to run in 5 or more IPs situation rather curiosity. So here my experience :
Since you're using RestTemplate which by default uses SimpleClientHttpRequestFactory.
And as the definition of connection time out goes :
The connection timeout is the timeout in making the initial
connection; i.e. completing the TCP connection handshake and getting
connected to the requested Server.
So, as far as theory goes :
Regardless of the underlying service topology, RestTemplate will try to make connection as per the connection timeout value.
And in order to figure out the almost exact timeout in your case, you must run some latency test, print the time differences which restTemplate is taking to get 200 OK.
Also, SimpleClientHttpRequestFactory internally uses HttpURLConnection which has default timeout of infinite (0/-1).
Yes, it has also been observed in rare cases, the connection keeps trying unless Thread.interrupt() explicitly being called to end.
Thus it becomes vital to describe your read-time-out and connection-time-out values and in this way you cap your connection to the limits you defined.
Hope this helps.
I am using C3P0NativeJdbcExtractor to extract the native JDBC connection as below.
public Connection getNativeConnection() throws SQLException{
C3P0NativeJdbcExtractor nativeJbdc;
nativeJbdc = new C3P0NativeJdbcExtractor();
return nativeJbdc.getNativeConnection(dataSource.getConnection());
}
Note that the data source here is obtained of a C3P0 Connection Pool. When I do a Connection.close() returned on this method, it is actually closing the connection instead of returning to the pool.
However if we close the unwrapped connection, then it is returned to the Pool.
Is there is a reason to why closing the wrapped connection here is failing to return the connection to the pool?
A connection pool like c3p0, holds a collection of physical ('native') connections created by a JDBC driver. When you ask it for a connection, it wraps that physical connection in a proxy, also known as the logical connection.
That proxy will intercept certain methods like Connection.close(). For close() instead of closing the connection, it invalidates the logical connection so it behaves as a closed connection, and it returns the physical connection to the connection pool.
Your code extracts the physical connection from the logical connection, and returns that instead, so if you call close() on that, you actually close the connection to the database instead of returning it to the pool.
You should almost never have a reason to extract the native connection like that. The only reason is when you need access to driver-specific features. You should try to use standard JDBC as much as possible, and only unwrap to access driver-specific features when you really need to.
When you call close(), make sure you call close() on the logical connection that you received from the connection pool, not on the unwrapped physical connection.
In Go/Golang, once a connection object (Conn) is created with the following code:
conn, err := net.Dial("tcp","33.33.33.33:444")
if err != nil {
// good connection
}
I would like to preserve the conn value for later on verifying if the connection is active. I dont want to re-connect from time to time to check the connection as it causes various TIME_WAITs on the OS, so overall my requirements are:
create a connection
preserve the connection object
capture if the connection drops for any reason
do not send or receive any data
Any thoughts on how to achieve this ? Is there a way to capture that the connection is discontinued without sending or receiving data or reconnecting ?
I don't think it is possible to do without performing an operation. If it is infrequently used, when you try to read you may get an error if the client (or some proxy) closed the connection. If that happens then reconnect and retry.
Many protocols will bake in a heartbeat mechanism to facilitate this kind of thing. Then you can read constantly (with SetDeadline if you want) and know within a heartbeat frame that something went wrong.
For example, I use a redis client that supports connection pooling. When I retrieve an idele connection from the pool, I immediately perform a PING operation. If that succeeds, I know the connection is ready to use. If not, I get another idle one, or connect anew.
Does SQL Azure allow 3-rd party connection pool like HikariCP or BoneCP?
We configured HikariCP it works when we just run app but later db doesnt response on request. Is it HikariCP issue or it's common connection poool issue and no need spending more time on investigation?
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(50);
config.setDriverClassName(env.getProperty("jdbc.driverClassName"));
config.setJdbcUrl(env.getProperty("jdbc.url"));
config.setUsername(env.getProperty("jdbc.user"));
config.setPassword(env.getProperty("jdbc.pass"));
config.addDataSourceProperty("cachePrepStmts", env.getProperty("jdbc.cachePrepStmts"));
config.addDataSourceProperty("prepStmtCacheSize", env.getProperty("jdbc.prepStmtCacheSize"));
config.addDataSourceProperty("prepStmtCacheSqlLimit", env.getProperty("jdbc.prepStmtCacheSqlLimit"));
config.addDataSourceProperty("useServerPrepStmts", env.getProperty("jdbc.useServerPrepStmts"));
See this SQL Azure page re: Connection Constraints.
Maximum allowable durations are subject to change depending on the resource usage.
A logged-in session that has been idle for 30 minutes will be terminated
automatically. We strongly recommend that you use the connection pooling and
always close the connection when you are finished using it so that the unused
connection will be returned to the pool. For more information about connection
pooling, see Connection Pooling.
See if any of these errors match up to your logs. Search that page for "terminated" and "busy" to find error codes that might be relevant to your issue.
I would suggest setting the maxLifetime property in HikariCP to 15 minutes, and the idleTimeout to 2 minutes.
There is nothing on the SQL Azure side that would prohibit you from using a 3rd party connection pool. My guess is that the connection failed between the server and the client and the client didn't remove the connection from the pool.
Moving forward, I'd ensure that whichever 3-rd part connection pool you end up using tests that the connection exists before taking it out of the pool for use.
Hope that helps.
This question already has answers here:
Closing JDBC Connections in Pool
(3 answers)
Closed 2 years ago.
Suppose I have the following code
DataSource source = (DataSource) (new InitialContext()).lookup("jdbc/myName");
Connection connnection = source.getConnection()
//use the connection to do some database operations...
at the end, should I still call
connection.close() to release the resource?
If the connection is from a connection pool, if I don't do anything, the connection should be automatically returned to the pool, right?
On the other hand, if I close it, is there gonna be any adverse effect on the connection pool (ie, after several calls, there won't be any connection left in the pool?)
The answer is yes, and check Closing JDBC Connections in Pool and JDBC Connection Pooling Best Practices for more information.
Yes, you should be closing the connection, if only for quick recovery by the pool.
This article http://www.javaranch.com/journal/200601/JDBCConnectionPooling.html advises placement of a .close() call in a finally block.