Monolith、SOA、DDD、The two-pizza rule、分库分表这些概念跟微服务有啥关系,你知道吗?这篇文章记录个人理解,分享给你们。html
微服务(micro service),我的感受也就近几年才吵起来的概念,记得退回去四五年(2014年),那时候你们还谈论SOA(service orentied architecture)比较多。在SOA以前,一个软件系统大多都是先后端不分离的monolith的架构,一般采用好比说spring mvc、java SSH (spring/structs/hibernate)、.net framework mvc、.net framework web form等技术方案实现。java
在计算机这个领域,好像每隔一段时间总会有一些概念被炒做起来,就像近几年在炒做的微服务、云原生、人工智能AI、区块链等,你们都在努力抓住这些风口,据说如今有的大学里面,学生不发AI相关的论文就不让毕业,我想这或许是python近两年在有的语言排行榜超过java成为榜首的缘由之一吧。python
关于微服务架构的概念,网上有不少介绍,你们能够自行搜索。这里推荐一个业界比较有名的网址,Martin Fowler的我的网址:https://martinfowler.com/articles/microservices.html。Martin fowler是微服务领域的一个专家,它有不少关于微服务方面的研究,有兴趣的童鞋能够去他的我的网址上查阅相关资料。nginx
那么,如何构建一个微服务架构的应用呢?基于以前的经验,个人总结以下:git
1、掌握好拆分微服务的粒度,使得每一个微服务相对独立,但又是整个业务流程的一部分。怎样才能掌握好这个粒度呢?我以为有一种说法挺有道理:从业务角度,能够遵循DDD(domain driven development),即领域建模,按照具体的业务流程来划分;从团队组织角度,一个团队负责一个或多个微服务,团队大小遵循“The two-pizza rule”。web
2、系统的总体设计须要遵循12 factors原则。算法
3、从系统实现的角度来看,考虑下面这些点:spring
API Gateway数据库
Service Registry and Discovery - Eureka后端
Circuit Breaker - Hystrix
Fault Tolerant - Hystrix
Message Broker - RabbitMQ
Database - Postgres
Logging and Tracing - ELK
Authorization and Authentication - OpenID/SAML/OAuth/JWT
Secure Credential Store - Vault
Security and Audit
CI/CD - Jenkins
Monitoring - Grafana
Container Runtime - Docker/CloudFoundry/Kuberntes
Proxy and Load Balancer - nginx
Multi-Tenancy
此外,下面是我对微服务相关话题的一些思考:
1、微服务火了以后,业界一直有这样一个问题:微服务和SOA的区别究竟是什么?
我我的的理解是这样的,SOA出现的背景大约是先后端不分离的monolith应用时代,为了解决各个应用系统之间的集成,因而就出现了SOA(service oriented architecture),意即面向服务的架构,idea就是把应用系统当成一个服务来设计,这样外部系统就能够很好的来消费这个服务,记得那时候把服务暴露出来的经常使用作法就是SOAP;而微服务出现的背景是,SOA本质上大多仍是monolith架构,便是单体应用,为了解决单体应用很重的问题,出现了微服务。因此SOA是第一阶段,服务主要面向系统外部集成;而微服务则是第二阶段,服务不但面向系统外部,同时也面向系统内部。
2、微服务和monolith的比较,下面是我我的的见解:
微服务开发效率更高,环境setup简单,build/checkout/run更快,ut/it 时间更短。各个微服务职责分离,边界清晰,有利于cross team开发,特别是对于跨location的协做开发,优点更加明显。记得以前有一个monolith的项目,代码总共几百万行,从git上拉下来都要几十分钟,build也很慢,ut/it须要跑很是长时间,开发效率很低,同时也很是不利于实现CI/CD。
从扩展性方面来说,微服务既能够水平扩展,也能够垂直扩展。而monolith只能够水平扩展。
3、微服务究竟是选择共享数据库仍是独立数据库?下面是我我的的见解:
若是是共享数据库的话,仍然相似于单体设计(数据库层面的单体设计),数据库层只能水平扩展, 容易成为瓶颈,好比说锁资源占有、死锁、 DB层面紧耦合致使开发互相影响等。原则上,对于微服务系统,应该只有API是不一样微服务之间的contract,若是采用共享数据库,就又引入了另一个层面的contract,不容易维护,当有其余团队的人改了数据库,容易致使意想不到的错。
4、分库分表和微服务的关系?
当一个系统数据量上去了,每每都须要考虑分库分表的事情。由于一旦数据量级上去了,数据库很容易就成为瓶颈。因此,怎么实现分库分表呢?其实,微服务自己就是一个很好的分库分表的实现。首先,每一个微服务独立数据库就是一个层面的分库,不一样微服务相关的业务数据存在单独的数据库,能够必定程度缓解共享数据库的瓶颈。其次,一个SaaS系统每每须要考虑多租户,一种多租户实现策略就是:每一个租户拥有本身的独立数据库,不一样租户的数据就被存在各自独立的数据库,这样又是一个层面的分库。其实分库的本质也就是经过一种哈希算法,把数据分散到不一样的数据库实例上,以达到负载均衡的做用。另外,有时候经过分库仍然会存在一些表数据量太大的问题,好比订单表,当数据量太大的时候,其读写操做的性能每每会急剧降低,这时候就须要作分表了。其实,我的以为分库某些时候也是一种分表,除此以外,还有一些其它策略,好比说,咱们能够把比较老的数据存到另一张表去,就像一些电商平台,用户默认只能看最近三个月的订单等。
5、迁移monolith应用到微服务架构
若是咱们开发一个系统,一开始选型就是微服务,这样很容易。可是,有时候咱们须要把一个很是庞大的monolith应用迁移到微服务架构,这每每不是一件容易的事情。通常怎么作呢?咱们须要从多个层面考虑:技术层面,首先须要仔细思考怎么拆分微服务,有时候这会很难,由于对于一个庞大的monolith应用,以前的实现各个模块之间每每耦合得很是紧;其次须要把以前的数据裤拆分为每一个微服务独立的数据库,这也会很难,由于怎么实现数据迁移须要仔细考虑,能够参考我以前写过的一篇文章(如何不宕机实现数据库迁移)。另外,团队层面也须要考虑不少,好比说团队的组织结构可能须要调整、团队成员的mindset须要buildup等。
最后,最近各大云厂商都在大力炒做cloud native,我查看了一些关于相关介绍,感受其实它和微服务就是换汤不换药,其实就是基于微服务的概念,而后加了一些容器编排的概念。See https://jimmysong.io/kubernetes-handbook/cloud-native/cloud-native-definition.html。
References