Golang 中间件集成最佳实践 0x01 中间件集成的思考

Golang 1408 字

你好,我是一笑。

在企业中越早进行公共库的沉淀越有利,在企业开发中中间件的集成是每个团队都需要的比如 MySQL、Redis、Kafka 这些中间件,几乎每个团队都需要使用,我们在开发项目的时候也需要使用这些中间件来构建我们的应用。

在团队使用 Go 语言构建应用的时候,各个项目组可能会存在自己封装中间件的行为,虽然大部分 SDK 功能比较齐全,但是正式由于功能丰富度上的考虑 sdk提供的接口都是比较原子化的,在实际使用的时候需要我们根据业务的使用场景来进行进一步的封装异常更多的细节。

另外一方面每隔中间件都需要考虑断线重连,SQL 调试等功能,这样使用起来更方便,代码也显得更加简洁,降低了学习成本,让经验不是特别丰富的开发成员快速上手。

各个项目组之间也存在数据交互,比如 A 团队丢到 kafka 之后,b 团队来消费数据,如果这个时候两个团队对 kafka 组件的封装不同使用不同的编解码方式,B 项目从 kafka 中消费出来的数据就需要看 A 团队采用的那种编码方式,这样一来了增加了沟通和开发成本。

还有在发送请求时候,每隔团队都使用了自己的默认值,那就可能出现 B 项目组调用 A 项目组的接口时由于超时时间不一致,导致客户端已经超时,但是服务端还在处理的情况,所以学习中间件的封装是在开发过程中是不可或缺的。

在集成中间件时需要考虑那些内容?

在 Go 中我们常用的中间件都有哪些呢?

  • ES
  • MySQL
  • MongoDB
  • Redis
  • Kafka
  • Promethues
  • 协程池

上面这些都是我们项目中经常集成的中间件。

在集成这些中间件之前,我们首先要进行一些思考。

安全第一,防止直接删库删表

数据是整个系统最宝贵的资源,数据安全怎么重视都不过分。

删库删表操作一般都是通过运维工单经过审核后才能执行,通过代码直接删除数据库和数据库表存在巨大的风险,因为通过代码我们无法判断是否为误操作,MySQL 在删除的时候可能会忘记带 where 条件,或者是传错了表名或者员工的负面情绪导致的恶意删除数据,都会给项目的数据带来极大的风险,所以数据库的删除操作要做严格的把控。

如果是一些日志数据我们可以分表存储进行定期的清理,我们一般可以选择 NoSQL,这样我们就可以对存储核心数据的关系型数据库做严格的把控,如果使用的都是 NoSQL,那么我们可以使用隔离原则,将核心数据库和非核心数据库隔离开,对于编码中需要进行删表的操作来使用白名单的方式只允许在白名单中的表进行操作。

我们同时还可以阻止异常操作:

  • mysql 中不带 where 条件的查询,更新和删除
  • ES 查询条件过多或者过深的嵌套查询语句
  • ....

这些异常操作都可能对集群服务造成影响,导致线上事故。

监控上报

集成后的 SDK 作为应用和这些中间件之间的桥梁,便于增加监控埋点,可以汇总统计这些中间件的调用信息,特别是调用失败的信息,能有效帮助我们发现问题。

多客户端支持

在同一个工程中我们可能会使用不同的中间件服务,比如数据库如果使用读写分离,那么我们就会访问不同的数据库,这些中间件初始化的时候我们通常只会初始化一次,我们可以考虑初始化多次来满足访问不同实例。

与原生操作保持一致,减少学习成本

在封装 sdk 的时候我们应该尽量和原生操作保持一致,这样可以减少学习的成本。

对参数的优雅处理

默认参数和自定义参数可以结合起来提供更好的使用体验,由于各个业务方对不同中间件的依赖程度不同,例如搜索业务会依赖于参数的设置,而且他业务可能只需要基本的默认参数就可以了。

func InitSimpleClient(urls [] string, username, password string) error

func InitClient(clientName string, urls []string, username string, password string, version int) error

func InitClientWithOptions(clientName string, urls []string, username string, password string, version int, options ...Option) error

过多的参数,我们可以使用函数式选项模式来进行处理。

单元测试和使用样例

单元测试和使用样例可以让使用者快速入门,掌握使用细节,降低学习和沟通成本。

文档和代码注释详细清晰

详细的代码注释,基本上可以取代文档的地位,开发之前我们先过一遍文档,使用过程中我们有的时候会直接去看代码来快速了解一些函数的功能以及参数的含义,这样回去看文档可能会更高效。

合理的默认值+参数校验

比如 ES bulk 提交参数的设置,mysql 中设置最大的打开连接数。

其他

  • 断线重连
  • 熔断限流
  • 超时控制
maksim
Maksim(一笑,吡罗),PHPer,Goper
OωO
开启隐私评论,您的评论仅作者和评论双方可见