软件服务架构的一些感悟

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

三层架构

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

微服务架构

(图1) (图2)

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

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

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

微服务,不只可以下降业务复杂度、开发团队管理难度,并且因为微服务的特性,使得部署软件的资源能更合理高效的应用,下降资源成本。优化

高并发

图3

          (图3)spa

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

重构

对于一个潜在的可能存在高并发场景的项目,如何能在遇到高并发的时候,从容地重构一个项目?我有一些浅见,供你们讨论:日志

 

(临时搭建的项目,凑合看吧) 中间件

如上图所示,项目划分了两个Package,一个Product,一个Membership,请注意,ProductController里面引用了Membership这个Package里的UserService,换句话说,就是ProductController依赖了Membership这个Package里的UserService。假如咱们约定,不容许跨Package依赖,那么Product这个Package里有须要用到User相关的服务的时候,本身写到Product这个Package里。那么当我要进行服务拆分的时候,只须要把Product这个Package单独打包成一个jar,便可拆分完成。这样约定,方便从三层架构重构到上图2的架构,对未来可能的分库分表没有任何影响。

若是以为不容许跨Package调用代码不能复用,形成了代码冗余,也能够采用下面的项目结构:

 Service如下层(包含Service)仍然安装单体应用的开发模式开发,拆分时,只须要将Controller层拆开打包成jar便可,后续的维护要求拆分后的团队各自维护各自的代码,而不是继续一个团队维护底层。

若是业务进一步复杂,采用图2所示架构也会遇到问题。好比库存数据,若是除了订单服务以外还有其余的服务都去修改库存数据的话,在没有统一日志或者这样的服务数量比较多的状况下,想要知道这个库存数据是怎么来的,会很是困难。这个时候只能重构成图1的架构。采用图1的架构,须要业务专家来定义接口,使其尽量地适应多的使用场景。

相关文章
相关标签/搜索