在使用Spring-Boot和Eureka Service发现构建的微服务体系结构中,我将在单独的单个服务中为许多应用程序构建C3P0连接池。 但是,当我尝试将创建的连接池作为对象返回到其各自的应用程序并使用该对象的连接时,它将无法正常工作。
例如- 当我们使用C3P0直接创建数据源时,我们写-
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(...);
但是,当我们希望数据源使用在其他微服务中创建的连接池时,是否有任何示例/ Github可以获取它?
答案 0 :(得分:2)
DB连接本质上是底层的TCP连接,由参与主机中的一对套接字唯一标识。这里的套接字表示网络地址(IP)和主机地址(端口)的组合。
建立TCP连接后,所有这些详细信息都存储在称为TCB的数据结构的任一端点上。因此,您不能仅将TCP连接从一台主机迁移到另一台主机。
有一些关于TCP连接迁移的研究,例如this one。但是,此处的主要目标不是 性能(例如,在连接池中通过在建立连接时节省TCP 3向握手的时间),而是允许现有连接继续并且不会由于IP而中断因迁移或故障转移而发生变化。
如果您参考上面的链接文章,则核心概念是再次进行三向握手,以使用新IP创建新连接。唯一的区别是,在握手期间,将传递一些其他控制数据以使用新的主机数据更新TCB,以便正在进行的数据传输可以继续进行而不会因IP更改而中断。
因此,您不能仅将数据库连接从一台主机转移到另一台主机,因为这些主机具有不同的IP。我链接的以上论文为草稿版本。即使实现了它,也无法解决您的问题,因为正如我所说,迁移将再次需要握手,这是您在连接池中要避免的事情。
如果您以某种方式将数据源从一台主机转移到另一台主机,然后尝试从该主机借用连接,则该数据源在返回连接之前所做的连接测试将失败,并且该操作将继续进行,直到所有连接用尽并然后将为该特定主机创建新连接。因此,最终您将不会从中获得任何收益。
最后,将所有连接池托管在单个微服务中的想法(尽管由于上述事实而固有地错误)似乎与基于微服务的体系结构背道而驰。这将创建一个瓶颈,与此微服务有关的任何问题都将破坏您的整个基础架构。在微服务架构中,我们要定位问题而不是扩散。您的单个微服务应尽可能地自治,并且隔板和断路器之类的模式要走很长一段路才能实现。
答案 1 :(得分:1)
不可能在服务之间传递填充的连接池,因为它们需要驻留该Java应用程序的地址空间(并从中加载类),并且物理连接也必须来自该Java应用程序。您需要以其他方式解决此问题。
可能的是在服务之间传递已配置的数据源。这实际上将序列化或外部化数据源配置,并使用相同的配置构建一个新的配置。请注意,尽管并非所有数据源实现都支持。
这在Java中已经存在多年了,例如如何使用JNDI服务器查找分布式应用程序的配置数据,或者JavaEE应用程序如何与Java客户端应用程序共享配置数据。根据我的经验,这种做法越来越不普遍,倾向于使用诸如Spring Cloud Config之类的东西。