Monolith、SOA、DDD、The two-pizza rule、分库分表这些概念跟微服务有啥关系,你知道吗?这篇文章记录我的理解,分享给大家。

微服务(micro service),个人感觉也就近几年才吵起来的概念,记得退回去四五年(2014年),那时候大家还谈论SOA(service orentied architecture)比较多。在SOA之前,一个软件系统大多都是前后端不分离的monolith的架构,通常采用比如说spring mvc、java SSH (spring/structs/hibernate)、.net framework mvc、.net framework web form等技术方案实现。

在计算机这个领域,好像每隔一段时间总会有一些概念被炒作起来,就像近几年在炒作的微服务、云原生、人工智能AI、区块链等,大家都在努力抓住这些风口,听说现在有的大学里面,学生不发AI相关的论文就不让毕业,我想这或许是python近两年在有的语言排行榜超过java成为榜首的原因之一吧。

关于微服务架构的概念,网上有很多介绍,大家可以自行搜索。这里推荐一个业界比较有名的网址,Martin Fowler的个人网址:https://martinfowler.com/articles/microservices.html。Martin fowler是微服务领域的一个专家,它有很多关于微服务方面的研究,有兴趣的童鞋可以去他的个人网址上查阅相关资料。

那么,如何构建一个微服务架构的应用呢?基于之前的经验,我的总结如下:

一、掌握好拆分微服务的粒度,使得每个微服务相对独立,但又是整个业务流程的一部分。怎样才能掌握好这个粒度呢?我觉得有一种说法挺有道理:从业务角度,可以遵循DDD(domain driven development),即领域建模,按照具体的业务流程来划分;从团队组织角度,一个团队负责一个或多个微服务,团队大小遵循“The two-pizza rule”。

二、系统的整体设计需要遵循12 factors原则。

三、从系统实现的角度来看,考虑下面这些点:

  • 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

此外,下面是我对微服务相关话题的一些思考:

一、微服务火了之后,业界一直有这样一个问题:微服务和SOA的区别到底是什么?

我个人的理解是这样的,SOA出现的背景大约是前后端不分离的monolith应用时代,为了解决各个应用系统之间的集成,于是就出现了SOA(service oriented architecture),意即面向服务的架构,idea就是把应用系统当成一个服务来设计,这样外部系统就可以很好的来消费这个服务,记得那时候把服务暴露出来的常用做法就是SOAP;而微服务出现的背景是,SOA本质上大多还是monolith架构,即是单体应用,为了解决单体应用很重的问题,出现了微服务。所以SOA是第一阶段,服务主要面向系统外部集成;而微服务则是第二阶段,服务不但面向系统外部,同时也面向系统内部。

二、微服务和monolith的比较,下面是我个人的看法:

  • 微服务开发效率更高,环境setup简单,build/checkout/run更快,ut/it 时间更短。各个微服务职责分离,边界清晰,有利于cross team开发,特别是对于跨location的协作开发,优势更加明显。记得之前有一个monolith的项目,代码总共几百万行,从git上拉下来都要几十分钟,build也很慢,ut/it需要跑非常长时间,开发效率很低,同时也非常不利于实现CI/CD。

  • 从扩展性方面来讲,微服务既可以水平扩展,也可以垂直扩展。而monolith只可以水平扩展。

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

三、微服务到底是选择共享数据库还是独立数据库?下面是我个人的看法:

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

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

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

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

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

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

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

References

  • https://martinfowler.com/articles/microservices.html#HowBigIsAMicroservice

  • https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice

  • https://12factor.net/

  • https://jimmysong.io/kubernetes-handbook/cloud-native/cloud-native-definition.html

  • https://www.oreilly.com/library/view/microservices-antipatterns-and/9781492042716/ch04.html

这些年我对微服务的理解相关推荐

  1. 谈谈我对微服务的理解

    微服务是一个近些年说的非常热的概念,尤其在互联网的大背景下,微服务的理论有机会被广泛实践.但是在实践过程中,大家对微服务的理解确大相径庭,到底要怎样做才能真正掌握微服务的架构理论呢?通过此文笔者想和大 ...

  2. 微服务的理解 —— 江湖往事

    微服务的理解 -- 江湖往事 一.90年代 -- 一招半式闯江湖 8.90年代的时候,计算机刚开始疏疏落落进入一些人的视野,这些人在研究所.学校.银行这样的机构,那时中国人称计算机叫微机,因为那时候还 ...

  3. 单体、集群、分布式、微服务概念理解

    单体: 单独的一个项目,所有的模块都会写在一个项目中,并且单独部署在一台服务器上,这就是一个最简单的单体架构的一个模型 集群: 单机处理到达瓶颈的时候,把单机复制几份,分别部署在多台服务器上,集群中每 ...

  4. (一)浅谈微服务概念理解

    1.什么是微服务 让我们以一个餐厅为例来解释微服务的概念. 想象一家传统的餐厅,它有一个集中式的厨房,所有的菜品都在同一个厨房中准备和烹饪.这个厨房负责接收顾客的点餐请求,准备食材,烹饪菜品,并最终将 ...

  5. 当我们谈微服务,我们在谈什么?谈谈我对微服务的理解!

    作者:fredal fredal.xin/talking-msa-understand-msa 阅读目录 微服务是什么 微服务是什么样的 服务化的前提 服务的发布与引用 服务的注册与发现 服务的远程通 ...

  6. java微服务的理解

    Java微服务是一种架构风格,它将单个应用程序拆分成许多小型服务,每个服务都有自己的独立功能并且可以被独立部署.这种架构的优势在于可以让团队更轻松地开发.测试和部署应用程序,并使系统更加可扩展和可靠. ...

  7. 【微服务】重新理解微服务之它还那么纯粹吗?

    温故而知新 不少同行,对于"什么是微服务",都在各平台发表过相关理解.看法等.随着这些年的技术发展,只要涉及到"微服务"这三个字已经不再纯粹,几乎无论是什么方向 ...

  8. 【转载】微服务,我们需要哪些基础框架?

    微服务(MicroServices)架构是当前互联网业界的一个技术热点,圈里有不少同行朋友当前有计划在各自公司开展微服务化体系建设,他们都有相同的疑问:一个微服务架构有哪些技术关注点(technica ...

  9. 微服务和其他常见架构

    我们看一下这个定义是怎么来的,微服务是由James和Martin两个人提出来的,他们在14年的3月份,写过一篇文章,就叫MicroService,就是微服务,有兴趣的可以去看一下原文,这里大家可以看一 ...

最新文章

  1. ​一个参数一张Excel表,玩转Pandas的read_excel()表格读取
  2. 修改mysql+io算法_MySQL磁盘IO设置问题
  3. Spring Initializr创建项目,利用阿里云URL解决Initialization failed for https://start.spring.io Please check URL
  4. 【C/C++】代码换行问题
  5. 更加安全的密钥生成方法Diffie-Hellman
  6. 微信小程序小结(3) -- 使用wxParse解析html及多数据循环
  7. GraphQL:简单开开始一个查询
  8. 想做Bezier动画,可惜弄出来这个差远了。
  9. 【WPS·Excel】数据分析方法汇总
  10. web前端简历的详解
  11. lvds接口屏线安装图解_lvds液晶屏幕接口详解
  12. JavaFX的webview下载文件的一种实现思路
  13. matlab tic和toc单位,matlab toc tic 的用法
  14. 通过rundll32调用系统对话框
  15. sql命令手册(转载)http://www.fanqiang.com
  16. linux 配置trac界面显示为中文,Trac的安装和配置
  17. mysql水平分区方案_SQL Server表分区(水平分区及垂直分区)
  18. Spring task corn表达式
  19. Spark Jdbc报NullPointerException
  20. Python编程:socket实现文件传输(文件服务器简易版)

热门文章

  1. shared_ptrT make_shared( Args ... args );
  2. ACPI知识学习笔记
  3. Membership学习记录
  4. Teams数据统计 - 聊天消息
  5. hotmail_在新的Hotmail Wave 4中禁用Messenger
  6. stl中Priority Queues(优先队列)的基本用法
  7. SQL Server 中使用 Try Catch 处理异常
  8. 【2】开发环境的搭建,Ubuntu14.04
  9. localStorage、sessionStorage用法总结
  10. [新手学go]关于go语言中的变量重复声明