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