这些年我对微服务的理解
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
總結
以上是生活随笔為你收集整理的这些年我对微服务的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对比Java和.NET多线程编程
- 下一篇: 程序员过关斩将--从每秒6000写请求谈