微服務開發與治理(一)

前言

         微服務架構與治理實戰。微服務架構目前已經成爲主流的互聯網技術架構方案,在項目初始階段就採用了微服務架構來開發和部署線上服務,經過一年多的實戰演變,目前我們幾人的開發團隊,維護和管理數十個微服務,實現了一套快速開發,部署,以及服務治理和追蹤的技術棧。這次我將主要給大家分享我們用到的技術內容以及開源產品的一些使用經驗。主要是從系統構建,系統從0到1構建過程、微服務架構怎麼樣、微服務我們怎麼做追蹤和治理的,以及我們遇到的開源技術棧和一些總結。

 

一、系統從0->1的構建

       一開始構建我們的系統,做一個互聯網項目,部署這些東西的時候,第一個問題就是用什麼樣的架構創建我們這套系統。我們選了SpringCloud,因爲SpringCloud確實在這些方面有些優勢。

      Why SpringCloud?

       部署更輕量

       第一,SpringCloud是基於SpringBoot的一整套實現微服務的框架。它提供了微服務開發所需的配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分佈式會話和集羣狀態管理等組件。最重要的是,基於SpringBoot,會讓開發微服務架構非常方便。在編譯和部署上面,時間上面的開銷也非常少,這就帶來了時間上的節省,開發效率更高。

       第二,SpringCloud的源碼更可控,主要是SpringCloud生態圈裏面我們用到第三方工具包大部分是以開源的形式開放給我們,所以我們用到它的時候,我們很容易知道它的源碼。另外如果它缺少一些特性,我們可以手動添加一些特性。當然這裏面最主要的一個原因,是因爲SpringCloud從一開始設計的時候有一個很重要的思想,就是這個源碼寫起來要簡單,不會同一個東西有很多種寫法。這樣在閱讀別人源碼的時候更輕鬆一些,不會有源代碼看起來很費勁的情況。所以這也確實是SpringCloud的一個優勢,就算是在團隊內部互相去看其他同學代碼的時候,也會發現比之前好很多。

       生態圈內部漸漸成熟,很多優秀的工具

   SpringCloud的生態圈裏面有非常多優秀的工具,SpringCloud的工具,很多工具都非常優秀,業界鼎鼎大名,包括做Eureka、Zuul等等,在各自行業裏都非常好用,給了我們非常大的支持。拋開源本身,我覺得生態作用可能更大一點。

         系統構建與運維

       當時我們構建系統的時候遇到了一些問題,一開始我們沒有專門的運維人員,其實到目前爲止我們也沒有專門的運維人員,開發人員數量也有限。在項目初期,我們對開發效率又看的比較高。當然我們有一個好處,在一開始業務量級不像大公司那麼大,所以一開始不太需要考慮大規模的挑戰。

       系統部署框架

       結合我們的業務場景,這是我們構建的部署方案,因爲我們最終交付給用戶的產品是一個web端的東西,所以需要把前端代碼部署在OSS上,把所有後端服務部署到k8s裏面去,大部分還是k8s請求,做各個微服務之間的轉法,微服務之間的通信我們用的是REST和RMQ。

       這是我們整體的部署方案,部署方案完了,我們從一開始定位了運維和開發輔助工具,來幫助我們完成開發。在日誌跟蹤方面,因爲微服務,你的服務數量又多,又都是分佈式的。包括線上預警、資源配置、存儲管理。

 

二、微服務架構

        微服務架構

      

       接下來,我來介紹一下在我們公司內部微服務架構使用的一些實踐。

       首先微服務的架構,現在微服務架構已經成爲一個主流,幾乎很少有新的業務場景會使用單體應用的架構模式,大部分都會從一開始都定義出微服務。就以典型的小電商網站爲例,基本架構,以前我要做一個電商網站,代碼是一套,部署也是一套,幾臺機器。現在我們做了拆分,我們會按照業務率,比如會員註冊、會員登陸、修改密碼,都在會員系統裏,會拆分成很多微服務。

       微服務架構優勢

      微服務有什麼好處?從領域模型緯度上,把原來很複雜的龐大系統拆分成了各個系統,各個系統之間通過這個接口來進行交互,這樣以來各個業務系統變得很清晰。另一個好處是從開發人員的角度,因爲這些微服務的拆分,比如我是做交易開發的,我肯定是基於交易的實現。針對會員我只關心接口怎麼給我,但不關心具體實現,我編譯的代碼也不會影響到它的系統。所以這是微服務拆分的好處。

        微服務粒度劃分

   微服務的粒度劃分,業界都認可的一種方式是按照業務領域模型進行劃分,比如會員系統和交易系統,它們倆在業務上有很強的隔離性,會員就管會員註冊登陸方面,交易主要完成交易。這時候劃分很清晰,大家也不會有什麼意見。但如果交易跟退款,這倆業務模型算不算一個獨立的業務模型?是分開還是合在一起?人們可能會認爲它們兩個是獨立的業務領域,這是可以的。我一般的做法是按照開發人員緯度來配,比如退款有專門的團隊或者專門的同學來管理,這時候就會拆分。如果交易和退款是同一個團隊開發的,我覺得拆不拆無所謂,這時候不是很重要的。

       快速構建一個微服務

       再講一下在我們內部如何快速構建一個微服務。強調快速的原因,也是因爲在我們內部構建一個微服務是一個很輕鬆平常的事,不像之前體量比較大的時候,或者微服務不那麼微的時候,這時候不太會去創建一個新的應用,除非你開一條新的應用線。在我們公司內部,平均每週會創建一個微服務,每週可能都要創建一個新的微服務,然後再部署上線。我們內部的微服務相對來說都比較簡單,重點是提供接口,第一步定義好微服務的接口,微服務主要分三步走,第一定義接口,第二實現接口定義上線。第一定義接口,在微服務裏面一旦把你的接口定義清楚,整個業務域就定義的很清楚了,接口定義清楚之後其他夥伴就可以拿接口做一些定向開發了。

       還有一個要談的話題是接口可拓展性問題,我們想象一下,在微服務沒有拆分的時候我們把所有代碼都寫在一個工程裏,這時候這些微服務除了沒有互相隔離開,沒有互相部署,這時候沒有太大的差別。這時候互相調用,比如交易系統要去獲取會員的信息,這時候也會調用會員的接口,只是這是一個純代碼,編譯上就直接調用的東西。現在由於微服務的調用,我們強行把它部署到兩臺機器上。因爲現在微服務的存在,會員已經上線了,交易這邊有一個接口,做一個改動就會帶來問題,所以接口擴展性非常重要。這時候如果想要擴展接口,只要多加一個字段都可以。

       說起接口擴展性,確實很重要,以前也有參與國其他的,比如我們在定義這個接口的時候,我一開始定義輸入是一個參數端,這時候如果想再加一個參數,我這個接口就得再寫一個XXXV2這樣的版本。另外還有一種場景,我們想要統一去分流你的遠程調用的時候成本比較高,所以一開始設計好可擴展性很重要。

        至於實現接口部分就是寫具體業務邏輯的事項,這部分主要的意見是要給大家提供豐富的工具,能夠讓大家快速的實現,有一些配置性的東西要提供便捷的方式。比如有一個應用要裂變數據庫,最好你能提供獲取知識庫連接很便捷的方式。因爲使用大量的微服務以後,微服務每天配的就會很多,你每天重複配就會很煩,所以儘量用工具化的方式,以及約定大於配置的方式避免這些問題。  

       最後是配置上線,一個新人或者老人,最好能用自動化配置上線的方式,而不是傳統的方式,我有一個配置上線,我先找運維申請一臺機器資源,再去申請帳號密碼等等。這些東西我們在內部用了一些腳本和工具自動化解決掉了,會自動分配這些東西。

      快速構建微服務網關

       網關用了openResty,是一個基於nginx的可伸縮的Web應用服務器,提供了很多高質量的第三方模塊,開發人員可以使用lua腳本調動nginx支持的各種C以及lua模塊。在性能方面,OpenResty可以快速構造出支持10k以上併發連接響應的高性能Web應用系統。OpenResty在本項目中,用於JWT權限校驗、Token超時時間更新、限流保護、無需登錄接口的加密串驗證

 

      微服務註冊與發現

       

      採用Nacos微服務註冊中心和配置中心。註冊中心,支持權重路由和閾值保護,防止雪崩,本項目中,作爲微服務模塊的註冊中心。配置中心,基於版本管理配置文件,業務配置參數修改後,5即可推送業務模塊。

      微服務間通信

       在服務間通信這個方面,Feign設計的目的是實現跨語言遠程調用的協議,在我們公司使用的場景是同語言的,因爲我們內部服務大部分都是java。我們把client和server統統包在k8s集羣內部,也就是後端服務全都是部署在k8s內部的,結合k8s的API來實現REST沒有實現的負載均衡和服務發現這個環節,比如這個客戶端要調用這個服務,它拿這個服務的名字去k8s的API查詢服務對應的IP,然後再通過這個返回值調用匹配目標服務。

       另外是RabbitMQ,消息模式在微服務間通信也是非常重要的模型,在互聯網系統和微服務架構比較流行的情況下會非常適用,對於系統的解耦和服務非常有價值。比如當一個訂單支付成功的時候,我可能有其他三個微服務都去訂閱這個訂單支付成功這個消息,這三個系統根據訂單支付成功分別做了自己的業務邏輯,比如同時賣家發貨等等,這主要是業務通信的環節,也是微服務通信中重要的一環。

 

三、服務追蹤與治理

       微服務的追蹤跟治理,當微服務數量比較多,而且人員又比較少的時候,服務追蹤、治理就顯得比較重要了。因爲確實太多了,如果憑過去一個一個LOW的方式可能管不過來。這時候從服務標準化和工具上面,一方面是把服務變成非常標準,另外一方面是提供各種各樣的工具來管理和運維微服務。

      微服務標準化

       服務標準化,分爲4個部分:

      第一是各種命名規範標準化

      第二是工程目錄標準化

      第三是標準化以後可以利用工具生來梳理

      第四是標準化以後開發的效率也會提升

      全鏈路日誌追蹤

      接下來介紹一下服務治理的工具。第一個是全鏈路的日誌追蹤,每個微服務輸入主要有三種,http、feign、mq,以及會調用DB、redis、API、FEIGN、MQ。

      這時候我們在每個節點上都打上了插件,各個都打一些插件,投入這些插件採集出這些節點上面的輸入輸出,還有一些性能相關的數據,把這些數據通過一些格來存儲到ES上去。

       我們在這些插件上幾乎記錄了所有的信息,每個輸入、輸出以及異常情況。還有每個請求的執行時間、每個請求鏈路以及每個請求的上下文環境。把這些鏈路記錄下來就很容易實現一些功能,比如我要回放之前的調用情況,我只要拿到我記錄下來的數據就可以進行回放。

      還有性能監控和異常率監控,比如每個接口錯誤率超過30%就會報警,這樣基於日誌就很容易做出來。還有業務異常監控,比如1萬單突然跌到1千單,就可以報警。還有調用鏈路梳理、依賴關係圖、定向問題排查,這些都有相應的定義,也會有相應的支持,包括在問題排查的時候也非常有用,這時候用這種工具回放排查這些問題就非常容易。       這是我們內部全鏈路日誌追蹤的系統,可以精準定位到某一個請求,當時我們返回到輸入。我們還可以查找它的兄弟節點以及下游節點的信息,這樣整個可以在調用鏈路上進行遊走,精準找到問題的請求。

 

四、開源技術棧使用經驗

       最後給大家講一下我們用到的一些開源的技術。在這一年過程中,確實感覺到開源技術給我們帶來的用處非常大,很多都是依賴這些東西,尤其是小公司沒有精力造輪子,往往是踩着別人的輪子。Nacos都講過,是微服務註冊與發現。Sentinel以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。適配大部分主流框架,Dubbo,Spring Cloud,gRPC等等。mongodb是一個數據庫,性能非常好,以及還有kubernetes。我們公司運維基本上沒有人,所以也沒有人專門做這個事情,開發的人也不願意做這些事情,基本上通過開發工具和腳本來解決這些問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章