關于微服務的那點事兒

前言

傳統(tǒng)的單體項目有什么問題?
想想看,當你的項目源碼達到幾十M時,開個新功能啟動一次項目需要20分鐘,稍微修改一下bug也要20分鐘,團隊的效率得有多么低

再想想看這么大的項目,必定伴隨著復雜的業(yè)務,對于新人來說直接接觸這么多復雜的業(yè)務,沒有半年時間難以融入團隊進行輸出

最主要的是,每次稍微改動一點bug,就要發(fā)版整個單體項目,出問題影響的是全部功能,這個是不能忍的

如何拆分微服務?

確認服務邊界上下文,所謂邊界上下文就是服務自身的職責的劃分,每個服務都是個高內聚的個體,各個服務之間不發(fā)生耦合,我們需要脫離表的束縛,從業(yè)務上梳理出模塊之間的邊界

拆分微服務以后會有哪些問題?

1.服務之間如何調用?

單體項目里無非就是方法調用,微服務之間調用需要走網絡通訊,是一個序列化與反序列化的數據傳輸過程,對于spring cloud,使用http傳輸協(xié)議,由feign進行聲明式調用

2.如何保證服務的高可用?

為了保證服務的可用性,微服務模塊不可能是單點跑的,一定是集群部署的,對于調用方客戶端來說,我們需要知道目前已經注冊的服務都有哪些,并且還需要對服務有著動態(tài)的上下線感知,除了這些,客戶端還需要一個負載均衡的機制吧?這個就是ribbon做的事。

引入一句忘了在哪看到的話,計算機的所有問題都可以通過引入中間層來解決。這個中間件就是注冊中心。注冊中心維護了所有的注冊的微服務,客戶端依賴注冊中心來找到真實的微服務地址。這塊細節(jié)比較多,比如注冊中心掛了怎么辦,微服務內部是不是應該有個緩存的注冊列表?如果出現了網絡分區(qū),分區(qū)內的注冊中心應該仍然可以正常使用(zookeeper別到處看了。。。說的就是你。。。)

3.容錯機制

想想這樣的一個場景,某個后端微服務接口出現異常,客戶端的請求發(fā)生超時。用戶一般有個習慣,哪里出問題了會一直點,那么每一個請求都對應了后臺的某一個線程,這個線程還是一直在runing直到超時的,系統(tǒng)資源是有限的,次數多了,系統(tǒng)必然由一個接口的問題導致大面積的雪崩。

傳統(tǒng)做法是http請求設置sessionTimeout與connectTimeout,但這不是解決問題的根本。

我們需要有個類似家里保險絲的熔斷機制,當服務出現問題時,斷路器自動熔斷。除了這個,斷路器還要有自我修復能力,比如過段時間放出一個請求,如果成功了就自我修復。再一個比較重要的是資源隔離,各個微服務接口調用不同的線程池或者信號燈。springcloud hystrix

4.鏈路追蹤

對于單體項目,都是單個jvm內的方法調用,日志的上下文很容易查看。對于微服務就不太一樣了,服務都在不同的jvm通過網絡進行通信,如何能拿到完整的調用鏈路日志?我們需要在微服務調用時傳遞traceID,使用traceID追蹤調用鏈路,這個就是sleuth做的事

5.微服務網關

還是對比傳統(tǒng)單體項目,項目的controller接口都在一起,統(tǒng)一管理很容易,但是到微服務就不太一樣了,各個項目都會提供rest服務,我們需要一個統(tǒng)一的網關來做權限驗證、統(tǒng)一跨域處理、路由跳轉等等。。。這個就是zuul負責的功能。

6.配置中心

單體項目的配置都是放在一個項目內,如果要改的配置的話,比如改mysql地址,直接改一次就想了,微服的配置分散在各個服務內部,我們需要一個集中式的配置管理 ,這個就是配置中心springcloud config,配置中心除了集中管理配置,還應該有修改配置實時同步到各個服務內的功能,做的好一點的配置中心,還有灰度發(fā)布,父子配置繼承的概念。

7.日志落地

單體項目的日志都是落在服務器的某個固定磁盤上,微服務的日志分散在各個機器的各個角落,而且微服務都是集群部署的,查一個完整的調用日志特別痛苦,我們需要一個日志收集機制,集中統(tǒng)一管理日志。

日志收集:logbak → kafka→ logstash → elasticsearch,kabana負責圖形化展示

8.服務上線

這么多微服務,如果靠人工運維手動copy jar包java -jar啟動,恐怕要累死運維,不像傳統(tǒng)項目就一個包直接發(fā)就行了。這個時候就聊到容器化技術了,這里需要感謝docker與k8s解放了生產力。

傳統(tǒng)的虛擬機比如vmvare,他在宿主機上完全虛擬了一套操作系統(tǒng),而docker與他最大的不同就是他直接運行于宿主機內核bootfs,沒有硬件虛擬,依托于linux的資源隔離。這樣使單機可以跑大量的docker服務,性能甚至與原始方式相差無二。

光靠docker肯定是不行的,還是沒有解決我們需要挨個輪流運維各個微服務,這個時候就輪到k8s登場了,k8s負責對容器的編排,所謂編排,就是對容器的管理,可以配置我們在集群內要啟動哪個服務,這個服務在集群內要有幾個副本,k8s會自動幫忙我們完成這個工作,如果服務某段時間掛掉了,k8s還會幫我們自動重新拉起來。服務上線時,他還會有個平緩的上線過度,比如服務x有A、B、C三個節(jié)點,他會先中斷A節(jié)點,啟動個新服務,啟動成功之后再中斷B節(jié)點。。。。k8s還有很多強大的功能,是個未來的趨勢,是DevOps的重要環(huán)節(jié)??梢哉f,不會k8s,就談不上懂DevOps。

現在有個docker容器跟k8s編排,最后一個工作是如果把這套流程動起來,從拉代碼到maven打包再到構建容器發(fā)布到k8s集群,這個流水線就是jenkins。

微服務架構

寫在最后

微服務除了上面的難題,還有許多其他的難題,比如分布式事務等等。。。但是技術不能因為這些難題而放棄復雜業(yè)務項目的微服務,作為技術也不能盲目追新,微服務并不適合小項目。還是那句話,微服務好是好,但不是適合所有項目,看自身項目情況來決定微服務是否引入。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容