微服务化路上的只言片语

类似于杂谈性质的文,总结下公司实行微服务化上遇到的一些问题。
虽然参与了开发过程,但整体更像是个旁观者,前期还是大家讨论怎么做,后来慢慢就由负责架构的同事专职做规划,拆分任务去完成。

万事开头难


最初的架构(数据库和其他部分都做了简化)

初衷并不是为了赶时髦,为了团队KPI之类的,而是遇到了一个很现实的问题。
研发团队慢慢从几个人发展为十几,几十人,所有人都在一个项目上开发,代码仓库越来越大,merge冲突越来越频繁,部署时也往往会因为一些bug导致全站部署拖延。
再加上访问量越来越高,带来的不确定性越来越大,一些流量较大的业务可能会导致整站都挂掉。
内部和外部都出现了问题。

当时虽然研发团队的人比较多了,但大家都基本是做业务兼做非业务的东西,没有成立专门的非业务部门。
大家都是在业务开发之外安排了微服务化相关的开发,这导致了进程缓慢,并且也隐式确定了微服务化不能影响现有业务开发。

最开始设想划分粒度应该粗一些,按照各个大频道来划分(有点类似于分子站)。
但遇上了一个问题,BL和DAL层的代码是共用的,再加上之前的模块化不合理,导致一个模块直接使用了属于另一个模块的业务代码。
让这更糟糕的是业务还在飞快迭代,这两层的代码也会发生很大的改变。
这时就有两种选择:
一种是复制,把需要的BL和DAL层代码复制到各服务中;
另一种是抽取依赖,把BL和DAL层代码抽离成一个单独的jar,被各个服务依赖。

前者会需要做频繁的同步,容易出现问题,很耗费精力。
当时我们选择了后者,先将他变为一个技术债解决现在的问题。


结构就成为了这样
组内也有同事开始脱离业务,慢慢专注在微服务化这一方向上,随后从业务组中慢慢抽离出了一个基础架构组(简称基架)。

路由 服务间调用

这一部分我就基本是路人了,会更接近于讲故事。
现在,spring cloud已经成为了一个比较成熟的解决方案,dubbo也重新被维护。
但当时,比较靠谱的选择只有dubbo,可能是出于对今后自己维护方便的考虑,基架最后的方案是参考dubbo,再结合一些现有的技术来实现自己的服务注册中心和服务请求路由。
注册中心用zk实现,里面存储服务版本、各个微服务名称、微服务版本以及服务器列表和API
服务间调用使用了nettyribbon等框架。
具体细节在这里不做过多描述了。
除了保留session处理相关、文件上传下载相关服务等接口以及页面渲染,原来的主站变为了一个gateway
于是变成了以下这样:

我们的坑

至此其实已经稍微有点微服务的样子了… …
但还存在很多问题。
细心的朋友可能发现了上图中所有的服务还都依赖一个db!(以及对应的只读实例等)
所以…存储挂了,该挂的还是都挂了。
于是再接下来的一段时间里,基架那边进行了一些比较大的业务拆分,将一些核心业务进行了分表分库使用单独的存储,这工作今日还在进行,为网站的稳定做出来很大贡献。

明天

其实还有很多东西都没有(链路监控已经做好了…插不进上面 这里说下):
一些服务间直接调用的解耦,举个例子,一个用户发完帖子后,现在是在代码里依次调用其他服务去执行一些操作,其实这里应该用消息发布的模式去做;
配置中心;
安全性;
等等。
其实想一想这些是现在的spring cloud开箱即用的功能,如果当时这方案已经成熟或许可以少走一些弯路也说不定。

题外话

和技术和业务无关。
专门成立了基架组其实有好处也有坏处,好处是有一部分人可以专门攻坚网站遇到的问题,坏处是其他人怎么办。
首先这并不是说业务组没有机会做一些技术相关的事,而是业务组做这些事的机会其实减少了,这给人带来的技术提升也不一样。
那在业务组怎么提升自己的技术能力呢?
这也是我一直思考的问题。

我现在的一些方式无非就是课余多看书看资料,增长自己的知识和视野。
但其实这样也挺容易迷茫的,如何实用化呢,怎么确保自己所学落地呢?
我的想法以及之后的做法会是直接在项目里用上,但这也不是说随便往项目中加入不必要的东西,而是要加入会带来性能提升潜力的东西,至于能否提升就要看自己的实战了。
书看完就过,没有自己的想法和思考终究只是表面上的东西,会随着时间漫漫淡忘,昨天在看NIO.2的笔记,14年记的现在基本已经忘却了,这就很糟糕了。
最悲惨的不是学过后忘记了相关知识,而是忘记了曾经自己学过。