问题
I'm using Apache Commons Pool library to maintaing a pool of couchbase connections (can be seen as any kind of connection, doesn't really matter).
The problem I'm facing is that the only way I've found to return objects to the pool is to do it programmatically by calling the returnObject method from the GenericObjectPool class. This forces the application to guarantee the return of the object once is borrowed from the pool, regardless any exception or unexpected behavior in the application.
Even though I'm controlling the return of the objects to the pool in the whole application, I find risky to depend exclusively on the programmer to return the objects. Does anybody knows a way to automatically return objects once a given timeout is exceeded (reclaim objects). It would also work any way to make the pool create new objects, once a timeout is exceeded for the borrowed objects.
PS: My application exposes a set of REST Web Services, that connect to distributed memcache server (Couchbase). The pool creates a set of connections to Couchbase.
Any suggestion would help!
EDIT
The first solution I've tried was to create a New Class (CouchbaseClientHandler) containing a connection Object from the type of Objects stored in the pool (CouchbaseClient). I've implemented the finalize method on CouchbaseClientHandler, ensuring that the associated was actually returned to the pool, if the reference to this object was getting lost by an unexpected exception. The object would be returned when the garbage collector destroys the object. This didn't worked as expected. Is impossible to predict when the garbage collector will arrive a reclaim objects, and it was normally taken higher time than desired.
The solution I've actually working right now is a bit different, but wide safer. Since my Pool is intended to be used by Web Services, and since every web service is running in a separate and unique thread (I'm using Jersey on Tomcat), I'm decided to use a static hashmap variable that maps unique Thread Id's to a list of CouchbaseClient objects created borrowed from the pool in the execution of the webservice. Since my web services are designed in such a way that, not matter what happens, a handler method will process the final output before returning, I can be sure to always run a method that returns to the pool those borrowed objects (connections), that have not been effectively returned to the pool.
Although this worked pretty well for me, I would really like to know if there is a better way of claiming or wiping by timeout borrowed objects that have not been returned.
回答1:
Assuming that the destroy / create new approach is OK and you are using version 2.0+ of commons pool, you can use abandoned object tracking and removal to make sure capacity is not permanently leaked when objects are borrowed and never returned. See the javadoc for AbandonedConfig for the configuration settings and the GenericObjectPool constructor that takes an AbandonedConfig instance as an argument. With abandoned object tracking and removal enabled, the pool will destroy instances that have been borrowed but not returned for longer than the removeAbandonedTimeout when the pool is low on capacity.
If for some reason you have to use a version 1.x pool, you can grab the source or use directly the AbandonedObjectPool that ships with DBCP 1.x.
来源:https://stackoverflow.com/questions/11001801/how-to-return-objects-to-the-pool-by-timeout-using-apache-commons-pool