在服务中构建连接池并在其他服务中使用它们

Building connection pool in a service and using them in other services

在使用 Spring-Boot 和 Eureka 服务发现构建的微服务架构中,我在单独的单个服务中为许多应用程序构建 C3P0 连接池。 但是当我试图 return 将创建的连接池作为一个对象连接到它们各自的应用程序并使用来自该对象的连接时,它不起作用。

例如- 当我们直接使用C3P0创建DataSource时,我们写-

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(...);

但是当我们想让dataSource使用在不同微服务中创建的Connection Pool时,有没有example/Github可以获取呢?

无法在服务之间传递已填充的连接池,因为它们需要存在(并从中加载 类)该 Java 应用程序的地址 space,并且物理连接也需要来自那个 Java 应用程序。您需要以不同的方式解决此问题。

可能的是在服务之间传递配置的数据源。这将实质上序列化或外部化数据源配置,并构建一个具有相同配置的新配置。请注意,并非所有数据源实现都支持这一点。

这在 Java 中已经存在多年,例如 JNDI 服务器如何用于查找分布式应用程序的配置数据,或者 JavaEE 应用程序如何共享Java 客户端应用程序的配置数据。根据我的经验,这种做法越来越不常见,人们倾向于使用 Spring Cloud Config 等

数据库连接本质上是一个底层的 TCP 连接,由参与主机中的一对套接字唯一标识。这里的套接字是指网络地址(IP)和主机地址(端口)的组合。

建立 TCP 连接后,所有这些详细信息都存储在称为 TCB 的数据结构中的任一端点上。因此,您不能只是将 TCP 连接从一台主机迁移到另一台主机。

有一些关于 TCP 连接迁移的研究,例如 this one。然而,这里的主要 objective 是 而不是 性能(如在连接池中通过在连接建立期间节省 TCP 3 次握手的时间),而是允许现有连接到由于移动或故障转移而导致 IP 更改,继续而不中断。

如果你参考上面的链接文件,核心概念是再次进行 3 次握手以创建与新 IP 的新连接。唯一的区别是,在握手期间,将传递一些额外的控制数据以使用新的主机数据更新 TCB,这样正在进行的数据传输可以继续进行,而不会因 IP 更改而中断。

因此,您不能将数据库连接从一台主机转移到另一台主机,因为这些主机具有不同的 IP。我链接的上述论文是草稿版本。即使实现了,也无济于事,因为正如我所说,迁移将再次需要握手,而这正是您在连接池中要避免的。

如果您以某种方式将数据源从一台主机传输到另一台主机,然后尝试从它那里借用一个连接,则数据源在返回连接之前所做的连接测试将失败,并且这将一直持续到所有连接都成功为止耗尽,然后将为该特定主机创建新连接。所以,最终你什么也得不到。

最后,将所有连接池托管在单个微服务中的想法(尽管由于上述事实在本质上是错误的)似乎与基于微服务的架构背道而驰。它会造成瓶颈,并且此微服务的任何问题都会导致整个基础架构崩溃。在微服务架构中,我们希望将问题本地化而不是扩散。您的个人微服务应该尽可能地自治,而舱壁和断路器等模式对实现这一目标大有帮助。