这些年我对微服务的理解

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

  • Scaling - Vertical scaling/Horizontal scaling

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只能够水平扩展。

  • 有人说monolith能够利用数据库事务,保证强一致性,而微服务则不能保证强一致性,一般只能保证最终一致性,这是monolith的一个优势。我以为这个点须要辩证的来看,由于强一致性,有时候也会带来一些性能问题,好比事务很大且高并发的状况,数据库容易成为瓶颈,最终致使吞吐量过低。同时,正如我以前写的一篇文章(关于分布式系统数据一致性的那些事),现实生活中也不可能有一个大而全的系统能够cover因此的场景,而且用事务保证强一致性。一个典型的例子,银行转帐每每须要强一致性,单个银行系统能够用数据库事务实现,可是跨银行系统转帐就不可能利用单机数据库事务,由于不一样银行系统都是本身的数据库,因此即便是银行系统并不能保证强一致性。以前一个同事说他就亲身经历过一次银行系统短时不一致的状况:他跨行取钱,钱被扣了,可是钱没吐出来,最后是去柜台人工处理才解决。

3、微服务究竟是选择共享数据库仍是独立数据库?下面是我我的的见解:

  • 若是是共享数据库的话,仍然相似于单体设计(数据库层面的单体设计),数据库层只能水平扩展, 容易成为瓶颈,好比说锁资源占有、死锁、 DB层面紧耦合致使开发互相影响等。原则上,对于微服务系统,应该只有API是不一样微服务之间的contract,若是采用共享数据库,就又引入了另一个层面的contract,不容易维护,当有其余团队的人改了数据库,容易致使意想不到的错。

  • 有人说采用共享数据库,作报表更方便。是的,若是是共享数据库,报表生成能够直接基于数据库来作join等操做,而若是是独立数据库,直接基于数据库的join就不行。可是,采用共享数据库也并不意味着报表方便。通常来讲报表属于OLAP操做,而业务逻辑属于OLTP操做,理论上讲,列级数据库更适合OLAP操做,而行级数据库更适合OLTP操做,若是报表这类OLAP操做和业务逻辑OLTP操做同用一个数据库的话,大量的OLAP操做会影响OLTP业务处理,因此,这两类操做分开用各自合适的数据库,才能互不影响而且利用不一样数据库的优点。记得,退回去几年(2014年),大数据还比较火,你们都在炒做这个概念,Hadoop、HBase、Spark、HANA等就是那时候的产物,其实我的理解大数据就是拿来作OLAP操做的。

4、分库分表和微服务的关系?

当一个系统数据量上去了,每每都须要考虑分库分表的事情。由于一旦数据量级上去了,数据库很容易就成为瓶颈。因此,怎么实现分库分表呢?其实,微服务自己就是一个很好的分库分表的实现。首先,每一个微服务独立数据库就是一个层面的分库,不一样微服务相关的业务数据存在单独的数据库,能够必定程度缓解共享数据库的瓶颈。其次,一个SaaS系统每每须要考虑多租户,一种多租户实现策略就是:每一个租户拥有本身的独立数据库,不一样租户的数据就被存在各自独立的数据库,这样又是一个层面的分库。其实分库的本质也就是经过一种哈希算法,把数据分散到不一样的数据库实例上,以达到负载均衡的做用。另外,有时候经过分库仍然会存在一些表数据量太大的问题,好比订单表,当数据量太大的时候,其读写操做的性能每每会急剧降低,这时候就须要作分表了。其实,我的以为分库某些时候也是一种分表,除此以外,还有一些其它策略,好比说,咱们能够把比较老的数据存到另一张表去,就像一些电商平台,用户默认只能看最近三个月的订单等。

5、迁移monolith应用到微服务架构

若是咱们开发一个系统,一开始选型就是微服务,这样很容易。可是,有时候咱们须要把一个很是庞大的monolith应用迁移到微服务架构,这每每不是一件容易的事情。通常怎么作呢?咱们须要从多个层面考虑:技术层面,首先须要仔细思考怎么拆分微服务,有时候这会很难,由于对于一个庞大的monolith应用,以前的实现各个模块之间每每耦合得很是紧;其次须要把以前的数据裤拆分为每一个微服务独立的数据库,这也会很难,由于怎么实现数据迁移须要仔细考虑,能够参考我以前写过的一篇文章(如何不宕机实现数据库迁移)。另外,团队层面也须要考虑不少,好比说团队的组织结构可能须要调整、团队成员的mindset须要buildup等。

最后,最近各大云厂商都在大力炒做cloud native,我查看了一些关于相关介绍,感受其实它和微服务就是换汤不换药,其实就是基于微服务的概念,而后加了一些容器编排的概念。See https://jimmysong.io/kubernetes-handbook/cloud-native/cloud-native-definition.html

References

相关文章
相关标签/搜索