從 Spring Cloud 開始,聊聊微服務架構實踐之路 原

背景

隨着公司業務量的飛速發展,平臺面臨的挑戰已經遠遠大於業務,需求量不斷增加,技術人員數量增加,面臨的複雜度也大大增加。在這個背景下,平臺的技術架構也完成了從傳統的單體應用到微服務化的演進。

 

 

 

 

系統架構的演進過程

單一應用架構(第一代架構)

這是平臺最開始的情況,當時流量小,爲了節約成本,並將所有應用都打包放到一個應用裏面,採用的架構爲.net+sqlserver:

 

 

 

 

 

表示層位於最外層(最上層),最接近用戶。用於顯示數據和接收用戶輸入的數 據,爲用戶提供一種交互式操作的界面,平臺所使用的是基於.net的web形式。 業務邏輯層業務邏輯層(Business Logic Layer)無疑是系統架構中體現核心價值的部分。它的關注點主要集中在業務規則的制定、業務流程的實現等與業務需求有關的系統設計,也即是說它是與系統所應對的領域(Domain)邏輯有關,很多時候,也將業務邏輯層稱爲領域層。業務邏輯層在體系架構中的位置很關鍵,它處於數據訪問層與表示層中間,起到了數據交換中承上啓下的作用。由於層是一種弱耦合結構,層與層之間的依賴是向下的,底層對於上層而言是“無知”的,改變上層的設計對於其調用的底層而言沒有任何影響。如果在分層設計時,遵循了面向接口設計的思想,那麼這種向下的依賴也應該是一種弱依賴關係。對於數據訪問層而言,它是調用者;對於表示層而言,它卻是被調用者。 數據層數據訪問層:有時候也稱爲是持久層,其功能主要是負責數據庫的訪問,可以訪問數據庫系統、二進制文件、文本文檔或是XML文檔,平臺在這個階段使用的是hibernate.net+sqlserver。

第一代架構看似很簡單,卻支撐了平臺的早期業務發展,滿足了網站用戶訪問量在幾萬規模的處理需求。但是當用戶訪問量呈現大規模增長,問題就暴露出來了:

  • 維護成本不斷增高:當出現故障時,有可能引起故障的原因組合就會比較多,這也會導致分析故障、定位故障、修復故障的成本相應增高,故障的平均修復週期會花費很多時間,並且任何一個模塊出現故障將會影響其它應用模塊;在開發人員對全局功能缺乏深度理解的情況下,修復一個故障,經常引入其他的故障,導致該過程陷入“修復越多,故障越多”的惡性循環。
  • 可伸縮性差:應用程序的所有功能代碼都運行在同一個服務器上,將會導致應用程序的水平擴展非常困難,只能使用垂直擴展。
  • 交付週期變長:應用程序做任何細微的修改以及代碼提交,都會觸發對整個應用程序進行代碼編譯、運行單元測試、代碼檢查、構建並生成部署包、驗證功能等,這也就版本的反饋週期變長,單位時間內構建的效率變得很低。
  • 新人培養週期變長:隨着應用程序的功能越來越多,代碼變得越來越複雜的同時,對於新加入團隊的成員而言,瞭解業務背景、熟悉應用程序、配置本地開發環境,這些看似簡單的任務,卻會花費了更長的時間。

垂直應用架構(第二代架構)

爲了解決第一代架構面臨的問題,團隊制定瞭如下的策略,並形成了第二代應用架構(垂直應用架構)

 

 

 

 

 

  • 應用拆成獨立的應用模塊。
  • 各個應用模塊獨立部署,並在負載均衡通過 session 保持解決應用模塊的水平擴展問題。
Sticky 就是基於 cookie 的一種負載均衡解決方案,通過cookie實現客戶端與後端服務器的會話保持, 在一定條件下可以保證同一個客戶端訪問的都是同一個後端服務器。請求來了,服務器發個cookie,並說:下次來帶上,直接來找我!。在項目中,我們使用了taobao開源的tengine中的session_sticky模塊。
  • 數據庫拆分成不同數據庫,由對應應用訪問。
  • 域名拆分。
  • 動靜分離。

可以看到第二代架構解決應用級別的水平擴展擴展,經過優化後,該架構支撐了幾十萬用戶的訪問需求,在這一階段有部分應用已經使用java 完成了mvc架構的重寫。當然也存在一些問題。

  • 應用之間耦合度高,相互依賴嚴重。
  • 應用模塊之間交互複雜,有時直接訪問對方模塊數據庫。
  • 數據庫涉及過多的關聯查詢與慢查詢,數據庫優化困難。
  • 數據庫單點訪問嚴重,出現故障無法恢復。
  • 數據複製問題嚴重,造成大量數據不一致。
我們曾經嘗試使用 sql server AlwaysOn 解決擴展問題,但是實驗發現在複製過程中出現至少10s的延遲,因此放棄了這個方案。
  • 系統擴展困難。
  • 各個開發團隊各自爲戰,開發效率低下。
  • 測試工作量巨大,發佈困難。

微服務化架構(平臺現狀:第三代架構)

爲了解決第一代與第二代架構存在的問題,我們對平臺進行了梳理優化。根據平臺業務需要以及對第一二代架構的總結,我們確定了第三代架構的核心需求:

  • 核心業務抽取出來,作爲獨立的服務對外服務。
  • 服務模塊持續獨立部署,減少版本交付週期。
  • 數據庫按服務分庫分表。
  • 大量使用緩存,提高訪問。
  • 系統間交互使用輕量級的rest協議,摒棄rpc協議。
  • 去.net化,開發語言使用java來實現。

並以此爲基礎進行了平臺的第三代架構的重構工作。

 

 

 

 

 

看第三代架構裏面的組成,主要分爲八個部分:

  • CDN:CDN 系統負責實時地根據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近的服務節點上。其目的是使用戶可就近取得所需內容,解決 Internet 網絡擁擠的狀況,提高用戶訪問網站的響應速度。
  • 平臺在選擇 CDN 廠商時,需要考慮經營時間長短,是否有可擴充的帶寬資源、靈活的流量和帶寬選擇、穩定的節點、性價比;綜合前面幾個因素平臺採用了七牛的 CDN 服務。
  • LB層:平臺包括很多個業務域,不同的業務域有不同的集羣,LB層(Load Balancer)是對多臺業務服務器進行流量分發的負載均衡服務,通過流量分發擴展應用系統對外的服務能力,並消除單點故障提升了應用系統的可用性。
  • 選擇哪種負載,需要綜合考慮各種因素(是否滿足高併發高性能,Session保持如何解決,負載均衡的算法如何,支持壓縮,緩存的內存消耗),主要分爲以下兩種:
  • LVS:工作在4層,Linux實現的高性能高併發、可伸縮性、可靠的的負載均衡器,支持多種轉發方式(NAT、DR、IP Tunneling),其中DR模式支持通過廣域網進行負載均衡。支持雙機熱備(Keepalived或者Heartbeat)。對網絡環境的依賴性比較高。
  • Nginx:工作在7層,事件驅動的、異步非阻塞的架構、支持多進程的高併發的負載均衡器/反向代理軟件。可以針對域名、目錄結構、正則規則針對 http 做一些分流。
  • 通過端口檢測到服務器內部的故障,比如根據服務器處理網頁返回的狀態碼、超時等等,並且會把返回錯誤的請求重新提交到另一個節點,不過其中缺點就是不支持url來檢測。
  • 對於session sticky,我們通過基於 cookie 的擴展 nginx-sticky-module 來實現。這種也是平臺目前所採用的方案。
  • 業務層:代表平臺某一領域的業務提供的服務,對於平臺而言,有商品、會員、直播、訂單、財務、論壇等系統,不同的系統提供不同的領域服務。
  • 網關與註冊中心:提供了統一的底層微服務 api 入口與註冊管理。封裝了內部的系統架構並向每個客戶端提供 Rest API,同時實現了監控、負載均衡、緩存、服務降級、限流等職責。目前平臺採用 nginx+consul 來實現。
  • 服務層:該層爲一些協同工作的小而自治的服務,平臺根據業務的邊界來確定了服務的邊界,每個服務只專注自己邊界之內。該層基於 spring cloud 來構建。
  • 基礎設施層:該層爲上層服務提供基礎設施服務,主要爲以下幾類:
  • redis 集羣:以高響應速度、內存操作爲上層提供緩存服務。
  • mongodb 集羣:由於 mongodb 具有靈活文檔模型 、高可用複製集 、可擴展分片集羣等特性,平臺基於此爲上層提供如文章、帖子、鏈路日誌等存儲服務。mongodb 集羣採用了複製+分片的架構解決可用性與擴展性問題。
  • MySQL 集羣:存儲會員、商品、訂單等具有事務性要求的數據。
  • Kafka:支撐了平臺的所有的消息服務。
  • ES(elasticsearch):提供了平臺的商品、會員、訂單、日誌等搜索服務。
  • 集成層:這個特點是整個平臺中的最大亮點,包括實踐持續集成CI、持續交付CD、DevOps文化,讓每個人都參與交付,在規範的流程和標準的交付下,完成一個服務的自動部署發佈,進而提高了版本交付鏈路的整體效率。
  • 監控層:將系統拆分爲更小的、細粒度的微服務給平臺帶來了很多好處,但是,它也增加了平臺系統的運維複雜性。
  • 給最終用戶提供的任務服務都是有大量的微服務配合完成,一個初始調用最終會觸發多個下游的服務調用,如何才能重建請求流,以重現與解決這個問題?
  • 爲此部署開源的 open-falcon 平臺提供應用級以上監控、使用ELK提供應用日誌的分析、使用自建服務提供鏈路日誌跟蹤以及基於spring config server實踐統一配置服務。

微服務團隊的工作方式

康威定律:任何組織在設計一套系統時,所交付的設計方案在結構上都與該組織的溝通結構保持一致。

工作方式

在實踐第三代架構時,我們對團隊組織做了幾個調整:

  • 按照業務邊界進行了劃分,在一個團隊內全棧,讓團隊自治,按照這樣的方式組建,將溝通的成本維持在系統內部,每個子系統就會更加內聚,彼此的依賴耦合能變弱,跨系統的溝通成本也就能降低。

 

 

 

 

 

  • 專門建立了一個架構師部門來負責第三代架構的推行工作。通常對於一個的架構師團隊有系統架構、應用架構、運維、DBA、敏捷專家五個角色組成是一個比較合理的結構。那麼又如何控制好架構組的產出,保證架構工作的順利推行呢?
  • 首先:打造持續改進的自組織文化是實施微服務的關鍵基石。只有持續改進,持續學習和反饋,持續打造這樣一個文化氛圍和團隊,微服務架構才能持續發展下去,保持新鮮的生命力,從而實現我們的初衷。
  • 其次:架構組的產品要經過嚴格的流程,因爲架構組推行的是通用的解決方案,爲了保證方案的質量,我們從方案調研到評審再到實施都有一個嚴格的閉環。

 

 

 

 

 

再談談整個團隊的交付流程與開發模式,如果沒有預先定義好,則很難讓微服務架構發揮出真正的價值,下面我們先來看看微服務架構的交付流程。

 

 

 

 

 

使用微服務架構開發應用程序,我們實際上是針對一個個微服務進行設計、開發、測試、部署,因爲每個服務之間是沒有彼此依賴的,大概的交付流程就像上圖這樣。

設計階段:

架構組將產品功能拆分爲若干微服務,爲每個微服務設計 API 接口(例如 REST API),需要給出 API 文檔,包括 API 的名稱、版本、請求參數、響應結果、錯誤代碼等信息。

在開發階段,開發工程師去實現 API 接口,也包括完成 API 的單元測試工作,在此期間,前端工程師會並行開發 Web UI 部分,可根據 API 文檔造出一些假數據(我們稱爲“mock 數據”),這樣一來,前端工程師就不必等待後端 API 全部開發完畢,才能開始自己的工作了,實現了前後端並行開發。

測試階段:

這一階段過程全自動化過程,開發人員提交代碼到代碼服務器,代碼服務器觸發持續集成構建、測試,如果測試通過則會自動通過 Ansible 腳本推送到模擬環境;

在實踐中對於線上環境則是先要走審覈流程,通過之後才能推送到生產環境。提高工作效率,並且控制了部分可能因爲測試不充分而導致的線上不穩定。

開發模式

在以上交付流程中,開發、測試、部署這三個階段可能都會涉及到對代碼行爲的控制,我們還需要制定相關開發模式,以確保多人能夠良好地協作。

  • 實踐”絞殺者模式”:

 

 

 

 

 

由於第三代架構跨度較大,並且面臨了無法修改的 .net 遺留系統,我們採用絞殺者模式,在遺留系統外面增加新的 Proxy 代理微服務,並且在 LB 控制 upstream 的方式,而不是直接修改原有系統,逐步的實現對老系統的替換。

  • 開發規範

 

 

 

 

 

經驗表明,我們需要善用代碼版本控制系統,我曾經遇到一個開發團隊,由於分支沒有規範,最後一個小版本上線合代碼居然化了幾個小時,最後開發人員自己都不知道合到哪個分支。

拿 Gitlab 來說,它很好地支持了多分支代碼版本,我們需要利用這個特性來提高開發效率,上圖就是我們目前的分支管理規範。

最穩定的代碼放在 master 分支上,我們不要直接在 master 分支上提交代碼,只能在該分支上進行代碼合併操作,例如將其它分支的代碼合併到 master 分支上。

我們日常開發中的代碼需要從 master 分支拉一條 develop 分支出來,該分支所有人都能訪問,但一般情況下,我們也不會直接在該分支上提交代碼,代碼同樣是從其它分支合併到 develop 分支上去。

當我們需要開發某個特性時,需要從 develop 分支拉出一條 feature 分支,例如 feature-1 與 feature-2,在這些分支上並行地開發具體特性。

當特性開發完畢後,我們決定需要發佈某個版本了,此時需要從 develop 分支上拉出一條 release 分支,例如 release-1.0.0,並將需要發佈的特性從相關 feature 分支一同合併到 release 分支上,隨後將針對 release 分支推送到測試環境,測試工程師在該分支上做功能測試,開發工程師在該分支上修改 bug。

待測試工程師無法找到任何 bug 時,我們可將該 release 分支部署到預發環境,再次驗證以後,均無任何 bug,此時可將 release 分支部署到生產環境。

待上線完成後,將 release 分支上的代碼同時合併到 develop 分支與 master 分支,並在 master 分支上打一個 tag,例如 v1.0.0。

當生產環境發現 bug 時,我們需要從對應的 tag 上(例如 v1.0.0)拉出一條 hotfix 分支(例如 hotfix-1.0.1),並在該分支上做 bug 修復。待 bug 完全修復後,需將 hotfix 分支上的代碼同時合併到 develop 分支與 master 分支。

對於版本號我們也有要求,格式爲:x.y.z,其中,x 用於有重大重構時纔會升級,y 用於有新的特性發布時纔會升級,z 用於修改了某個 bug 後纔會升級。針對每個微服務,我們都需要嚴格按照以上開發模式來執行。

微服務開發體系

我們已經對微服務團隊的架構、交付流程、開發模式進行了描述,下面我們聊聊歸納一下微服務開發體系。

什麼是微服務架構

Martin Flower的定義:In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies

簡單的說,微服務是軟件系統架構上的一個設計風格,它倡導將一個原本獨立的系統分成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間通過基於 HTTP 的 RESTful 輕量級 API 進行通信協作。

被拆分的每個微服務圍繞系統中的某項或一些耦合度較高的業務進行構建,並且每個服務都維護着自身的數據存儲、業務開發、自動化測試案例以及獨立部署機制。由於有了輕量級通信機制,這些微服務間可以使用不通的語言來編寫。

微服務的拆分粒度

微服務到底拆分到一個多大的粒度,更多時候是需要在粒度與團隊之間找到一個平衡點,微服務越小,微服務獨立性帶來的好處就越多。但是管理大量微服務也會越複雜。基本上拆分需要遵循以下幾個原則:

  • 單一職責原則:即”把因相同原因而變化的東西聚合到一起,把因不同原因而變化的東西分離開來”。通過這個原則確定微服務邊界。
  • 團隊自主原則:團隊越大,溝通與協助成本就會越高,我們在實踐中一個團隊不會超過8人,團隊內全棧,是一個全功能團隊。
  • 先分數據庫、後分服務:數據模型能否徹底分開,決定了微服務的邊界功能是否徹底劃清,實踐中我們先討論數據模型邊界,數據模型的邊界映射了業務的邊界,進而從底向上完成服務拆分。

如何搭建微服務架構

爲了搭建好微服務架構,技術選型是一個非常重要的階段,只有選擇合適的”演員”,才能把這臺戲演好。

 

 

 

 

 

我們使用 Spring Cloud 作爲微服務開發框架,Spring Boot 擁有嵌入式 Tomcat,可直接運行一個 jar 包來發布微服務,此外它還提供了一系列“開箱即用”的插件。

例如:配置中心,服務註冊與發現,熔斷器,路由,代理,控制總線,一次性令牌,全局鎖,leader 選舉,分佈式 會話,集羣狀態等,可大量提高我們的開發效率。

 

 

 

工程結構規範

 

 

 

 

 

上圖是我們實踐中每個服務應該具有的項目組成結構。

其中:

  1. 微服務名 + service:
  2. 爲對內其它微服務提供服務調用。服務名 +api 模塊爲服務間定義的接口規範,使用 swagger+rest 接口定義。服務名 +server 模塊包含了能直接啓動該服務的應用與配置。
  3. 微服務名 + web:
  4. 供上層 web 應用請求的入口,該服務中一般會調用底層微服務完成請求。

API 網關實踐

 

 

 

 

 

API網關作爲後端所有微服務和API的訪問入口, 對微服務和API進行審計,流控, 監控,計費等。常用的API網關解決方案有:

  • 應用層方案
  • 最有名的當然是 Netflix 的 zuul, 但這不意味着這種方案就最適合你, 比如Netfilx 是因爲使用 AWS,對基礎設施把控有限, 所以纔不得不在應用層做了 zuul 這樣的方案,如果通盤考慮, 這種方案不是最合適或者說最有的方案。
  • 但如果自己的團隊對整體技術設施把控有限,且團隊結構不完善,應用層方案也可能是最適合你的最佳方案。
  • nginx + lua 方案
  • 也是我們採用並認爲最合適的方案,OpenResty 和 Kong 是比較成熟的可選方案, 不過 Kong 使用 Postgres 或者 Cassandra, 國內公司估計選擇這倆貨的不多,但 Kong 的 HTTP API 設計還是很不錯的。
  • 我們的方案
  • 使用 nginx+lua+consul 組合方案,雖然我們團隊大多是 java,選擇 zookeeper 會是更加自然的選擇,但作爲新銳派,對壓測結果進行了分析, 我們最終選擇使用 consul。
  • 良好的 HTTP API 支持, 可以動態管理 upstreams, 這也意味着我們可以通過發佈平臺或者膠水系統無縫的實現服務註冊和發現, 對服務的訪問方透明。

 

 

 

 

 

在以上的方案裏:

consul 作爲狀態存儲或者說配置中心(主要使用 consul 的 KV 存儲功能);nginx 作爲API網關, 根據 consul 中 upstreams 的相關配置,動態分發流量到配置的 upstreams 結點;

nginx 根據配置項, 連接到 consul 集羣;

啓動的 API 或者微服務實例, 通過手工/命令行/發佈部署平臺, 將實例信息註冊/寫入 consul;

nginx 獲取到相應的 upstreams 信息更新, 則動態變更 nginx 內部的 upstreams 分發配置,從而將流量路由和分發到對應的 API 和微服務實例結點;

將以上註冊和發現邏輯通過腳本或者統一的發佈部署平臺固化後,就可以實現透明的服務訪問和擴展。

鏈路監控實踐

我們發現,以前在單應用下的日誌監控很簡單,在微服務架構下卻成爲了一個大問題,如果無法跟蹤業務流,無法定位問題,我們將耗費大量的時間來查找和定位問題,在複雜的微服務交互關係中,我們就會非常被動,此時分佈式鏈路監控應運而生,其核心就是調用鏈。

通過一個全局的ID將分佈在各個服務節點上的同一次請求串聯起來,還原原有的調用關係、追蹤系統問題、分析調用數據、統計系統指標。

分佈式鏈路跟蹤最早見於2010年Google發表的一篇論文《dapper》。

那麼我們先來看一下什麼是調用鏈,調用鏈其實就是將一次分佈式請求還原成調用鏈路。顯式的在後端查看一次分佈式請求的調用情況,比如各個節點上的耗時、請求具體打到了哪臺機器上、每個服務節點的請求狀態,等等。

它能反映出一次請求中經歷了多少個服務以及服務層級等信息(比如你的系統A調用B,B調用C,那麼這次請求的層級就是3),如果你發現有些請求層級大於10,那這個服務很有可能需要優化了

常見的解決方案有:

  • Pinpoint
github地址:GitHub - naver/pinpoint: Pinpoint is an open source APM (Application Performance Management) tool for large-scale distributed systems written in Java.
  • 對 APM 有興趣的朋友都應該看看這個開源項目,這個是一個韓國團隊開源出來的,通過 JavaAgent 的機制來做字節碼代碼植入(探針),實現加入 traceid 和抓取性能數據的目的。
  • NewRelic、Oneapm 之類的工具在 java 平臺上的性能分析也是類似的機制。
  • Zipkin
官網:OpenZipkin · A distributed tracing systemgithub地址:GitHub - openzipkin/zipkin: Zipkin is a distributed tracing system
  • 這個是 twitter 開源出來的,也是參考 Dapper 的體系來做的。
  • Zipkin 的 java 應用端是通過一個叫 Brave 的組件來實現對應用內部的性能分析數據採集。
Brave 的 github 地址:https://github.com/openzipkin/brave

這個組件通過實現一系列的 java 攔截器,來做到對 http/servlet 請求、數據庫訪問的調用過程跟蹤。然後通過在 spring 之類的配置文件里加入這些攔截器,完成對 java 應用的性能數據採集。

  • CAT
github地址:GitHub - dianping/cat: Central Application Tracking
  • 這個是大衆點評開源出來的,實現的功能也還是蠻豐富的,國內也有一些公司在用了。不過 CAT 實現跟蹤的手段,是要在代碼裏硬編碼寫一些“埋點”,也就是侵入式的。
  • 這樣做有利有弊,好處是可以在自己需要的地方加埋點,比較有針對性;壞處是必須改動現有系統,很多開發團隊不願意。
  • 前面三個工具裏面,如果不想重複造輪子,我推薦的順序依次是 Pinpoint—>Zipkin—>CAT。原因很簡單,就是這三個工具對於程序源代碼和配置文件的侵入性,是依次遞增的。
  • 我們的解決方案
  • 針對於微服務,我們在 spring cloud 基礎上,對微服務架構進行了擴展,基於 Google Dapper 的概念,設計了一套基於微服務架構的分佈式跟蹤系統(WeAPM)。

 

 

 

 

 

如上圖所示,我們可以通過服務名、時間、日誌類型、方法名、異常級別、接口耗時等參數查詢響應的日誌。在得到的 TrackID 可以查詢到該請求的整個鏈路日誌,爲重現問題、分析日誌提供了極大方便。

 

 

 

 

 

斷路器實踐

在微服務架構中,我們將系統拆分成了一個個的微服務,這樣就有可能因爲網絡原因或是依賴服務自身問題出現調用故障或延遲,而這些問題會直接導致調用方的對外服務也出現延遲。

若此時調用方的請求不斷增加,最後就會出現因等待出現故障的依賴方響應而形成任務積壓,最終導致自身服務的癱瘓。爲了解決這樣的問題,因此產生了斷路器模式

 

 

 

 

 

我們在實踐中使用了 Hystrix 來實現斷路器的功能。Hystrix 是 Netflix 開源的微服務框架套件之一,該框架目標在於通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。

Hystrix 具備擁有回退機制和斷路器功能的線程和信號隔離,請求緩存和請求打包,以及監控和配置等功能。

斷路器的使用流程如下:

啓用斷路器

   @SpringBootApplication
    @EnableCircuitBreaker
    public class Application {
    public static void main(String[] args) {
        SpringApplication.run(DVoiceWebApplication.class, args);
        }
    }

代用使用方式

   @Component
    public class StoreIntegration {
    @HystrixCommand(fallbackMethod = "defaultStores")
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }
    public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
        }
    }

配置文件

 

 

 

 

 

資源控制實踐

聊到資源控制,估計很多小夥伴會聯繫到 docker,docker 確實是一個實現資源控制很不錯的解決方案,我們前期做調研時也對是否使用 docker 進行了評審,但是最終選擇放棄,而使用 linux 的 libcgroup 腳本控制,原因如下:

  • docker 更適合大內存做資源控制、容器化,但是我們線上服務器一般都是32G左右,使用docker會有資源浪費。
  • 使用 docker 會使運維複雜、來自業務的壓力會很大。

爲什麼要有 cgroup?

Linux 系統中經常有個需求就是希望能限制某個或者某些進程的分配資源。也就是能完成一組容器的概念,在這個容器中,有分配好的特定比例的 cpu 時間,IO時間,可用內存大小等。

於是就出現了cgroup的概念,cgroup就是controller group,最初由 google 的工程師提出,後來被整合進Linux內核中,docker也是基於此來實現。

libcgroup 使用流程:

安裝

   yum install libcgroup

啓動服務

   service cgconfig start

配置文件模板(以memory爲例):

   cat /etc/cgconfig.conf

 

 

 

 

 

看到 memory 子系統是掛載在目錄 /sys/fs/cgroup/memory 下,進入這個目錄創建一個文件夾,就創建了一個 control group 了。

   mkdir test
    echo "服務進程號">>  tasks(tasks是test目錄下的一個文件)

這樣就將當前這個終端進程加入到了內存限制的 cgroup 中了。

總結

總結一下,本文從我們微服務實踐的背景聊起,介紹了微服務實踐的工作方式,技術選型,以及相關的一些微服務技術。

包括:API網關、註冊中心、斷路器等。相信這些技術會給大家在實踐中帶來一些新的思路。

當然整個微服務實踐之路內容繁多,一篇文章不可能全部包括,大家有興趣可以在chat中提出來。

歡迎工作一到五年的Java工程師朋友們加入Java程序員開發: 854393687
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!
 

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