早想着要写一篇博客,但由于各种原因(其实因为懒),迟迟没有动笔。今日下决心,写写关于软件服务架构的一点感悟。

三层架构

从读大学开始,老师就讲三层架构。后来的项目实施基本上也都是三层架构。对于小型项目,业务逻辑相对简单的项目,三层架构是快速迭代的利器。随着项目的迭代,功能越来越多,业务逻辑越来越复杂,业务开发团队越来越庞大,单体的三层架构就逐渐暴露出它的不足。因为这样的项目是一个高内聚、高耦合的项目,一个类、一个方法可能被多处引用,给维护带来了极大的不方便,要修改一个方法、修改一个字段,可能会影响到所有引用它的方法。如果项目中还存在包引用、dll引用,可能还会导致包名冲突、命名空间冲突。这种情况下,我们会去想,如何降低业务复杂度?答案是拆分服务,微服务化。开发团队的壮大对于高效的管理也是一个问题,微服务化后,原先业务团队被拆分成多个微服务团队,也降低了管理的难度。

微服务架构

图1

图2

对于微服务如何划分,粒度多粗多细,每个团队有每个团队的划分法。从我个人的经历来看,无外乎一种细粒度划分,一种粗粒度划分。

图1,展示了细粒度的服务划分通常的一个结构。对于一个复杂的业务,如果服务划分过细(这样的服务通常绝对禁止跨库访问),业务逻辑层必然要对服务进行组装,不管是RPC的调用方式,还是Rest的方式,此时的业务逻辑层仍然是一个高内聚、高耦合的模块。对于一个需要快速迭代的产品,这样的架构快速不起来。比如一个下单服务,业务逻辑层的负责团队需要等待商品服务相应的接口、订单服务相应的接口、库存服务相应的接口等下单涉及到的接口准备就绪,才能开始编写服务。

图2,展示课粗粒度的服务划分通常的结构。这时,一个微服务接口是一个粗粒度的接口,微服务与微服务之间不允许相互调用,而允许跨库访问,降低了服务之间的依赖,这样的的微服务是一个高内聚、低耦合的模块。还是以下单服务来举例,此时负责订单服务的团队,编写服务的时候,不必等待商品团队、库存团队、用户团队(收货地址)等其他团队,他们自己可以快速着手开发下单服务。负责库存服务的团队,只写他们关心的服务,比如商品的采购、入库。而订单团队需要的库存扣减操作接口,订单团队自给自足。(这里引申一个问题,从DDD的思想来看,一个Domain的边界,到底在哪里?拿库存来说,一切有关库存的操作都写到这个Domain叫做DDD?如果只有订单模块会扣减库存,退单后会加回库存,这样的接口还写在库存服务模块?这类接口属于订单领域还是库存领域?)

微服务,不仅能够降低业务复杂度、开发团队管理难度,而且由于微服务的特性,使得部署软件的资源能更合理高效的应用,降低资源成本。

高并发

图3

软件并发量逐渐提高,不管是三层架构、还是微服务,优化的途径都差不多,读写分离-》加缓存-》分库分表。上方所示图2到图3,展示了利用一些数据访问中间件(Sharding-JDBC、Macat、Atlas&&)实现分库分表的架构。

重构

对于一个潜在的可能存在高并发场景的项目,如何能在遇到高并发的时候,从容地重�