1. 程式人生 > >基於OpenResty和Node.js的微服務架構實踐

基於OpenResty和Node.js的微服務架構實踐

復雜 直接 簡單 暴露 zookeep 投放 維護 升級 回滾

什麽是微服務?

傳統的單體服務架構是單獨服務包,共享代碼與數據,開發成本較高,可維護性、伸縮性較差,技術轉型、跨語言配合相對困難。而微服務架構強調一個服務負責一項業務,服務可以單獨部署,獨立進行技術選型和開發,服務間松耦合,服務依賴的數據也獨立維護管理。雖然微服務存在部署復雜、運維難度較大、分布式事務控制難、容錯要求高等缺點,但總體而言,微服務的優點遠大於其復雜性。

技術分享圖片

微服務架構需要註意哪些問題?

微服務架構,首先考慮客戶端與服務端之間的通信問題。有兩種解決辦法,一是客戶端與多個服務端直接進行通信,但存在對外暴露接口細節、眾多接口協議無法統一、客戶端的代碼復

雜、服務端升級相對困難等問題。二是客戶端訪問統一的API網關,由API網關調用眾多服務接口,易實現統一通信協議,降低客戶端和服務端代碼耦合,也可以達到統一的鑒權和流控,然而此方式存在延時增加的風險,可能使API網關成為系統發展的瓶頸。

技術分享圖片

微服務架構是分布式服務架構,如何進行服務的註冊和發現也是需要解決的問題。一種是通過客戶端發現,調用方需要知道所有依賴服務的地址,開發成本較高,協議升級比較困難。另一種是通過統一網關發現具體服務的地址,對客戶端來說實現比較簡單,能夠在網關進行統一鑒權和流控,要求網關高度可用性。

技術分享圖片

調用微服務盡可能做到有序,避免相互調用,杜絕循環調用。服務間要有清晰的層次關系,上層服務可以依賴下層服務,如果遇到下層服務需要同步消息給上層調用方的情況,可以考慮通過消息隊列異步解耦,比如訂單/審核系統在創建訂單或者改變訂單狀態時,可以考慮使用雙寫(即寫入數據庫後,同時在消息隊列也寫一份),異構系統(比如訂單執行系統)可以通過訂閱消息保存異構數據。

個推在微服務上有哪些實踐?

個推的服務場景主要有三種。其一是個推推送場景,通過Java語言開發,SOA的架構方式來實現,保證信息推送的實時性與高並發性,這塊微服務改造比較困難;其二是廣告交易平臺,比如投放平臺、DMP數據管理,以Java為主進行開發,對並發數要求較高,我們在逐步進行基於Java的微服務框架的微服務化嘗試;其三是web業務系統,它為前端提供無狀態的業務API接口,是典型的request/response方式,同時,這是我們目前微服務實踐最多的場景。

技術分享圖片

隨著業務快速發展,公司web相關的業務系統開發需求不斷增加,這些系統都涉及到用戶管理,後臺管理,權限管理等。為進一步提高團隊開發效率,我們對服務進行平臺化、模塊化改造,選擇了如上的技術選型。

技術分享圖片

個推的整體架構如上圖所示。請求先經過LVS/HaProxy,到達基於OpenResty實現的API網關,API網關會根據請求將流量upstream到服務單元。服務單元作為一個整體,支持通過Lua、Node.js、Java等語言實現業務邏輯,啟動時向Zookeeper註冊,API網關會從Zookeeper獲取服務單元部署信息。

技術分享圖片

服務單元如上圖所示。它由Openresty統一對外暴露服務端,Openresty內置了lua語言,可以在weblua框架中通過編寫lua程序來進行業務邏輯處理。Openresty通過proxy_pass,upstream將請求轉給webnode處理,也可以在Openresty中通過配置處理Java業務邏輯。服務單元就像一個抽屜櫃,具體的業務(app)就像一個抽屜,只要尺寸符合抽屜櫃的要求,就能將抽屜推入到抽屜櫃中,抽屜所用的語言不作要求。

技術分享圖片

Openresty集成了lua腳本作為編程語言,使用Zookeeper服務註冊。為了解決lua與Zookeeper不適配問題,在Openresty啟動時啟動websocket服務,Node.js進程啟動時同步啟動websocket的client,這樣每個Node.js進程會和Openresty保持長連接和心跳,Openresty會選擇一個Node.js進程,啟動Zookeeperclient完成服務註冊。API網關也是基於服務單元通過類似的方式實現完成服務註冊的。

技術分享圖片

服務單元在Openresty層完成了統一鑒權,不會產生額外的性能開銷。

我們可以用“通道化”來闡述服務間的調用問題。我們將微服務之間的調用比喻成水管,從水管的一端流進去的是請求信息,那麽從另一端流出來的也應該是請求信息,我們只要求流入流出的信息保持一致,而不關心這些信息在傳輸過程中經過了轉換或其他過程。如上圖,A、B之間的調用通過進程內require就能實現,而A、C間的調用是通過服務單元內的http完成的。

Q&A

Q:微服務架構在運維部署是否會很麻煩?

A:隨著微服務的不斷推進,服務數量勢必會越來越多,這就需要考慮DEVOPS。比如代碼提交之後通過Jenkins自動觸發打包編譯,自動生成版本號,進而觸發自動測試部署和自動化測試,測試通過後進行一鍵部署升級、支持升級失敗自動回滾等。我們目前已經實現了自動打包和測試部署,後續環節正在推進。

Q:Openresty裏對Session管理進行了處理,開發人員會不會覺得不方便?

A:在引入微服務框架之前,公司有很多獨立業務服務,每個服務都有自己的賬號系統實現登錄驗證邏輯。雖然有現成的代碼模塊可以用,但每次都需要重新測試驗證。如今,具體的業務服務都可以通過Openresty完成鑒權並統一對外,對開發和測試人員來說,反而減少了一定的工作量。

基於OpenResty和Node.js的微服務架構實踐