关于数据源方面的一些思考

225 阅读4分钟

最近在进展一项技术优化工作,主要是将各个微服务系统内部的数据源连接进行收拢,例如A服务专门访问A数据库,B服务专门访问B数据库,如果出现了B服务内部查询A数据库信息的操作,必须将该类操作聪B服务中迁移至A服务中,这样保证对应的服务专门处理对应的数据库,达到数据源统一管理的好处。

数据库连接的底层细节

数据源连接的过程中其实是有一定的资源开销和成本在其中的。常见一条数据库的连接需要:

  • 建立TCP连接,完成三次握手。【这里面就需要涉及到传输的源ip,源端口,目标ip,目标端口】
  • 完成握手之后,需要对传输过来的账号密码进行校验。
  • 在连接创建好了之后,便会到数据库里面查询对应连接的权限。

在业务应用当中,常见会有两种方式创建数据库连接,长连接短连接

长链接:

客户端和服务端建立连接之后,执行crud操作,当操作结束后不会直接断开链接。

短链接:

客户端和服务端建立连接之后,执行crud操作,当操作结束后直接断开链接。

通常我们在建立连接之后是会对MySQL的服务端产生一定的内存占用。

为什么要对各个微服务的数据库连接进行管理?

  • 数据库性能瓶颈排查更加方便

对不同的微服务进行数据库连接管理可以帮助我们对每个数据库的资源更好管理。

例如A服务只是专注于A数据库,如果那天A数据库的压力达到了瓶颈,那么主要的压力都来自于A服务,这样我们进行性能优化和排查的时候就可以将关注点放在A服务中,让开发者更加能够专注。

  • 连接数调节更加方便

例如A数据库的连接只会给到A服务使用,那么当出现链接不足的时候只需要增大数据库可连接数目即可,而且还不用担心A数据库的连接被其他服务占用的情况了。

收拢数据源过程中可能会遇到哪些问题?

其实数据源的迁移本质就是将A服务的数据源访问压力调整到B服务中。

  • 数据连接池的连接数增加

例如B,C,D服务中对于A数据库的查询操作全部统一到了A服务中,那么A服务内部原先对于A数据库的连接池就需要合理增大连接数目。

  • 缓存压力的扩散

这类情况主要出现在原先代码中将sql查询出来的数据还需要额外加载到缓存中的情况,如果将B,C,D服务中的跨数据库查询操作统一到A服务中后,对应的缓存同步操作也需要被迁移到A服务中,那么这个时候如果涉及到Redis,本地Cache相关的操作就需要注意下是否会有影响。

  • JVM方面的影响

这类情况主要出现在需要将数据库中大量数据加载到内存中进行计算的场景,这种操作会增大相关服务的内存占用,所以JVM方面也要关注。

  • 加大接口的访问延迟

原先可能只是通过本地函数调用,执行sql查询即可,但是现在可能就是变成了需要通过rpc远程调用来获取数据结果集的这么一个方式,整体的耗时需要在开发过程中进行合理评估。

设计一款数据库连接池的时候需要考虑些什么要点?

  • 连接池需要支持预创建机制
  • 连接如何分配机制
  • 连接的资源参数支持配置(例如兼容原先单连接的配置形式)
  • 扩展点有哪些
  • 是否可以对连接的信息进行监控,例如慢sql,耗时,参数,连接使用情况等等

常见的数据库连接池种类

  • proxool 更新时间截止2008年。速度可以,稳定性稍差,发较高的情况下会出错。
  • c3p0 太古老,代码及其复杂,不利于维护。貌似都比它强。
  • dbcp 是 apache上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。
  • druid 是alibba出品的一个功能比较全面,且扩展性较好的数据库连接池,比较方便对jdbc接口进行监控跟踪等。
  • BoneCP 13年前最快的连接池项目。2013年后不再更新,心灰意冷。
  • HikariCP 光连接池,目前被SpringBoot2官方推荐使用的数据库连接池。