简体   繁体   English

实现自定义连接池?

[英]Implement custom connection pool?

I was wondering if I need to implement my own connection pool, what will be high level algorithm? 我想知道我是否需要实现自己的连接池,什么是高级算法?

I had a glance over couple of solutions(below links) on google but all of them looks not scalable to me. 我在google上浏览了几个解决方案(链接下方),但所有这些解决方案看起来都不适合我。 When i say scalable I mainly focus on getConnection()/borrowConnection() method where i need to ensure if multiple threads calls this method at same time, they don't get same connection and also wait is minimal. 当我说可扩展时我主要关注getConnection()/borrowConnection()方法,其中我需要确保如果多个线程同时调用此方法,它们不会获得相同的连接,并且等待也是最小的。 All of the below solution uses the synchronized method/block approach which is not scalable at all as in application like ecommerce threads has to wait. 以下所有解决方案都使用同步方法/块方法,这种方法根本不可扩展,因为在电子商务线程等应用程序中必须等待。

  1. https://codereview.stackexchange.com/questions/40005/connection-pool-implementation https://codereview.stackexchange.com/questions/40005/connection-pool-implementation
  2. http://www.javaworld.com/article/2076690/java-concurrency/build-your-own-objectpool-in-java-to-boost-app-speed.html http://www.javaworld.com/article/2076690/java-concurrency/build-your-own-objectpool-in-java-to-boost-app-speed.html
  3. https://sridharrao85.wordpress.com/2011/07/20/sample-connection-pool-implementation/ https://sridharrao85.wordpress.com/2011/07/20/sample-connection-pool-implementation/
  4. http://www.javamadesoeasy.com/2015/12/connection-pooling-in-java-with-example.html http://www.javamadesoeasy.com/2015/12/connection-pooling-in-java-with-example.html

Mine Solution :- Basically my approach focus on how i can reduce the concurrency at granular level instead at data structure holding the pool of connection. 我的解决方案: -基本上我的方法专注于如何在粒度级别减少并发性,而不是在持有连接池的数据结构上。 So i will keep two list(arralylist) 所以我会保留两个清单(arralylist)

  1. ConnectionsNotInUse ConnectionsNotInUse
  2. ConnectionInUse ConnectionInUse

ConnectionsNotInUse will hold all connections(wrapped in custom connection class) in pool at startup. ConnectionsNotInUse将在启动时保存池中的所有连接(包装在自定义连接类中)。 Now if a thread asks for connection, once it gets it successfully , it will remove it from ConnectionsNotInUse and put it in ConnectionsInUse. 现在,如果一个线程要求连接,一旦它成功获取,它将从ConnectionsNotInUse中删除它并将其放入ConnectionsInUse。

Inside each custom connection class, there will be method getConnection() method which will use Semaphore.tryAcquire() which Acquires a lock, if one is available and returns immediately, with the value true. 在每个自定义连接类中,将有方法getConnection()方法,它将使用Semaphore.tryAcquire()获取锁,如果有可用并立即返回,值为true。 It will be semaphore with one permit. 它将是一个许可证的信号量。 So if thread does not get connection , it will loop over for another connection in list. 因此,如果线程没有获得连接,它将循环遍历列表中的另一个连接。

If at last if thread does not get any connection, it will create another connection if max permissible limit allows otherwise it will wait to be connection to be released. 如果最后如果线程没有得到任何连接,如果最大允许限制允许,它将创建另一个连接,否则它将等待连接被释放。 Once connection is released , it notify the threads waiting for connection 一旦释放连接,它就会通知等待连接的线程

Any comments/suggestions on approach suggested ? 有关方法的任何意见/建议吗?

As far as I understand your description: 据我了解你的描述:

the original implementation of the connection pool is like a room with only one entrance and only one person (thread) is allow to get in. What you are worried is person will line up in the entrance and influence the scalability of your app. 连接池的原始实现就像一个只有一个入口的房间,只允许一个人(线程)进入。你担心的是人会在入口处排队并影响你的应用程序的可扩展性。 So you decide to have multiple entrances (free list). 所以你决定有多个入口(免费清单)。 But you seems not specify which entrance they should try, I assume you to let them try the first. 但你似乎没有说明他们应该尝试哪个入口,我假设你让他们尝试第一个。 If first is not available, they will try next entrance. 如果没有第一个,他们将尝试下一个入口。

So if my understand is right, the policy which entrance they choose is the core of performance. 因此,如果我的理解是正确的,他们选择的入口政策是绩效的核心。 If they all try first, then second, it will make little difference with original implementation. 如果他们都先尝试,那么第二,它与原始实现没什么区别。

What I can think about the fast and no sync way is to hash the identity of the person. 我能想到的快速和无同步方式是散列人的身份。 If the resulted entrance is not free any more, there would be two ways: 如果结果入口不再免费,则有两种方式:

  • find next 找下一个
    • hash again 再次哈希
    • next position, etc 下一个职位等
  • create new 创建新的

So move back from metaphor. 所以从隐喻中退出。 What I described is like the implementation of a hashmap and you may try it in two ways: 我所描述的就像是一个hashmap的实现,您可以通过两种方式尝试:

  • replace your list with hashmap 用hashmap替换你的列表
  • use a single map mixed with used and free connection, in which case, you may avoid giant lock but you need use ConcurrentHashMap or implement your version. 使用与使用和自由连接混合的单个映射,在这种情况下,您可以避免巨型锁定,但您需要使用ConcurrentHashMap或实现您的版本。

Some Notice: 一些通知:

  • If you use two lists which are shared by different threads to maintain, you still need giant lock on them, otherwise will crash it. 如果你使用两个由不同线程共享来维护的列表,你仍然需要巨大锁定它们,否则会崩溃它。
  • You will increment count of connection in order to compare with max permissible connections, which also need synchronization. 您将增加连接数,以便与最大允许连接进行比较,这也需要同步。

Some suggestions: 一些建议:

  • Use atomic integer as counter 使用原子整数作为计数器
  • Use ConcurrentHashMap or implement your version (actually it's like a array add linkedlist and the array element is the lock of list which avoid the giant lock) 使用ConcurrentHashMap或实现你的版本(实际上它就像一个数组添加链表,而数组元素是列表的锁,避免了巨锁)

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

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