日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【服务治理】服务治理漫谈

發布時間:2023/11/30 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【服务治理】服务治理漫谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【服務治理】服務治理漫談

0. 前言

本文是服務治理領域專題的第一篇,并不希望也無法大包大攬將所有的點都覆蓋到,更意在從一些更貼近我們實際工作的角度來進行更抽象層次的剖析,更多分享的是我認為重要或者有意思的一些方法論和邏輯推演過程。這能給我們后續無論是業務應用還是基礎技術領域的服務治理提供一些參考。

1. 什么是服務治理

在一切的最開始,我們先來問自己一個問題,什么叫做服務治理?網上有很多關于服務治理的定義,維基百科也有著對應的定義。林林總總,有宏觀的也有細節的。而在本文中,我嘗試為其進行另一個維度上的簡單定義:

服務治理,即以組織、業務和系統三者為核心要素建立連接,在此基礎上實現服務系統的正向打通和逆向反饋。

1.1 三要素

  • 組織
    組織即人。服務不可能獨自存在,我們在進行治理的過程中,往往過度重視面向業務的用戶體驗,而會忽視掉在這個技術生態上另外一個非常重要的服務對象—技術人員。大家往往更專注于如何設計出一個高性能高可擴展的系統,而冷落了技術人員在這之中的訴求。一個良好的服務治理的判斷標準,即要在服務好普通用戶的同時,也需要讓在這生態之上的技術同學得到歸屬感。
  • 業務
    業務即產品。毋庸置疑,技術是為業務服務的。空談技術本身沒有意義。所以我們需要保持對業務敏銳的洞察力和前瞻意識,這樣才能設計出一個演化式的合理服務架構。比如業務流量很低且還處于快速試錯階段,而你卻上了一整套的高并發的解決方案,這就本末倒置了。大部分技術同學天然會有“秀技術肌肉”的沖動,這是正常的,但作為架構師,需要合理控制組織的欲望,結合業務實際進行處理,才能達到一個良好的服務治理的狀態。
  • 系統
    系統層面上,也即我們最常談及服務治理時候會關注的點。如何做一個可靠、高性能、自動化、可擴展且能夠快速迭代的系統出來響應業務的需求呢?良好的服務治理要求我們能夠結合組織和業務實際,進行系統層面的控制。這樣也是下列章節中會重點提及的內容。

如上圖所示,三要素之間會相互影響,良好的服務治理能夠讓三者相互促進優化迭代,不合理的服務治理將導致三者相互拉扯、沖突,乃至降低士氣和效率并影響最后的公司產出。所以服務治理,從來就不單純只是系統、技術的問題,也涵蓋著人和事情的要素。

1.2 系統層面的正向打通和逆向反饋

在系統層面的服務治理的范疇,相關的介紹有很多,比如業內享有盛譽的阿里開源框架 Dubbo(目前已入 Apache)中的相關圖表的呈現:

可以看出在一個復雜的網絡拓撲場景中,我們需要對這個服務網進行各種各樣的治理,來確保這個網在技術層面能夠盡可能地維持健康和有效。但如何去歸納我們到底需要什么樣的服務治理呢?如下圖所示:

在系統層面,我們認為:

服務治理其實是由流量的正向打通和逆向反饋所構成的一個環

正向打通,即如何將流量打通,這也是對于一個服務本身最基本的要求。我們于是需要思考:

  • 如何做跨服務通訊,Rest 還是 Rpc ?序列化用 json 還是 pb ?能支持什么協議?是否支持多協議轉換?
  • 如何做服務注冊/發現,用 Eureka、Zookeeper、etcd、Consul、Nacos?
  • 如何做負載均衡,用軟負載,還是硬負載?負載算法用 RR、Random、一致性哈希?
  • 如何做路由篩選,撈一百個,還是 IDC 優先,還是類似 Envoy 這樣的防恐慌機制或者干脆來個類似 Dubbo 的腳本花活?
  • 如何做授權鑒權,是否需要 TLS,是否需要黑白名單,是否要驗簽,用什么加密算法,機器如何互信?
    ……
  • 逆向反饋,則是代表我們如何基于各種基于流量進來后觀察到的數據,來進行系統性地決策(一般是負反饋)我們的服務網需要做哪些事情才能讓整張網持續處于健康狀態。于是,我們思考,

  • 如何扛住流量洪峰,削峰、限流?怎么限流?信號量、令牌桶、漏桶、固定窗口計數、滑動窗口計數、線程隔離?
  • 如何正確處理異常,及時熔斷?一鍵降級?級聯決策關閉入口?
  • 如何讓系統可觀察,監控、報警、分布式鏈路追蹤?選擇 Cat、Zabbix、Falcon、Prometheus、Zipkin、Skywalking?
  • 如何提升資源效率,采用容器,Kvm?Docker?Swarm?K8s?Mesos?Openstack?
  • 如何定義一個服務的健康度,SLA?RTO?RPO?健康度量模型?
    ……
  • 2. 服務治理的發展史

    我們都知道,服務的發展是由單塊應用,服務水平分層,服務縱向切割,乃至后續微服務思想的興起,**“兩個星期”重構法則和“兩張披薩”**團隊等眼花繚亂的服務拆分方法論充塞你的耳目。這都是些常見的論調,但不是本章節闡述的重點。本章節更關注的是服務治理發展拆分過程中,所必然要面對的一個核心問題—“服務拆分后,之間如何產生聯系?”也即:

    如何形成復雜服務節點的網絡?

    限于篇幅,我們來簡單回顧下針對該問題的幾個重要思潮。

    2.1 Server Proxy

    我姑且稱之為集中式代理階段。該階段也是最樸素的解決方案,多采用集中式的單點服務集群來承擔較多服務治理的功能。比如集中式部署 Lvs、Nginx、Haproxy、Tengine、Mycat、Atlas、Codis等等,就是最常見的方式。這種方式的優勢在于便于功能的集中維護,且語言無關,上手成本低,所以其實在大中小公司特別是創業公司里面擁有大量受眾。但其帶來的問題也很明顯,以最風靡的域名+Http Rest調用 + Nginx組合套裝為例,調用鏈路需要經過 DNS(DNS cache)、KeepAlived、(Lvs)、Nginx 幾層。超長的調用鏈路路和多個單點系統,將會在服務規模上升時引發穩定性和性能問題。在丁丁租房和美團就多次發生類似的單點故障。丁丁租房曾經因為 Nginx、DNS以及 Codis-Proxy故障而導致過大面積的業務影響。美團的 DNS、MGW 等都遭遇過類似問題,其進一步因此而推出去內網Http調用轉為Thrift直連的技術項目。總體來看,其必然有用武之地,其更適合初創公司,或者特別強調跨語言的應用場景,Server Proxy 都可作為一個快速上手的解決方案以供使用。但在使用時候,需要對其缺陷有著清晰認識以便于在后續演化中做出正確決策。

    2.2 Smart Client


    樸素直接的 Server Proxy 帶給我們便利的同時,也帶給我們大量的問題,而這個時候,為了應對這類問題,Smart Client 快速崛起并綻放出其強大的生命力。我們姑且稱之為框架化階段,該階段為了解決 Server Proxy 所存在的單點長鏈路的問題,替代以直連的方式來構建兩個節點之間的聯系。這一步到位地解決了單點長鏈路的問題,且能夠在直連的基礎上,進行更大的性能優化和穩定性的抬升。代表開源產品(服務框架 or Rpc 框架)有比如 Uber 的 Ring-pop、阿里的 Dubbo、螞蟻的 Sofa-Rpc、當當的 Dubbox、微博的 Motan、點評的 Pigeon/Zebra、百度的brpc/Stargate、Grpc、Thrift等。大的思路即兩個:

  • 硬的不行,那就轉為軟的。硬件式的服務治理行不通,那么就轉到軟件式的服務治理。
  • 遠的不行,那就轉為近的。遠端集中式部署的方式行不通,那么就拉到和我應用進程里面部署。
  • 如此一來,Server Proxy思潮中的諸多弊病就被一一化解了。

    鼓吹了很久 Smart Client 的優點,那他不存在問題嗎?必然還是存在的,而且問題也十分明顯和突出。

  • 第一方面,我們知道,微服務領域的氣質是趨向自治的。Smart Client 也被成為富客戶端,而采取這種方式將很嚴重地限制我們在技術棧上的選擇,換一個語言就需要重新實現一遍基本所有的治理能力,及其之后帶來的多套語言下成本增長的維護升級成本,這個對于絕大部分公司來說都是難以承受的負擔。Uber 不得不針對 Ring-pop 推出 node 和 go 版,微博的 Motan 也推出了多個語言版本,Grpc、Thrift也沒能逃出這個命運。而現在大部分的公司都會混合兩種以上的語言進行實際的開發。所以這個問題也必須要進行正視。
  • 第二方面,Smart Client 采用重 SDK 的方式嵌入應用進程進行共存,這將使得服務治理的運維工作和業務應用的維護完全攪到一起。這在現實的工作場景中,給服務治理的運維難度抬升了幾個量級,服務治理團隊不得不被迫面對多個版本并存的架構代碼,以及推行一個版本可能需要半年以上的噩夢。
  • 當然,盡管有以上問題,但是由于目前沒有特別成熟的替代方案,Smart Client 目前仍然在高并發大流量的業務場景中占據著主流地位。如果語言能夠盡可能收斂的場景也可以使用,比如可以采用 Java 版的 Smart Client,并對于不高的Nodejs流量采用Http Rest 加上域名的方式來做折中的服務治理。

    2.3 Local Proxy

    Server Proxy 和 Smart Client 都有著無法回避的問題,那么還有其他的解決方案嗎?為了回應這一個問題,Local Proxy 應運而生,既然集中式部署有單點問題,富客戶端又有耦合的問題,那么為什么不取一個折中呢?這時候的思路就變為:

    就近進行進程級別治理。即采用本地進程級別代理的方式,既可以規避集中式單點部署的問題,又可以回避語言相關和應用耦合的問題。

    這個思路開始逐步風靡,非常多的治理方案也在這個思想下如雨后春筍冒出。
    airbnb 的 SmartStack 采用了四件套完成了整個核心的服務串聯治理過程,是一個樸素解決方案。

    而攜程 OSP 也采用類似方式來進行處理,和 airbnb 的差別主要在于將 Synapse 和 Haproxy 的功能整合為了一個 Proxy 來替代。

    在云領域里面,由于跨語言和運維效率被放在了更為重要的角度來審視,這種思想更是占據了主導的地位,Mesos+Marathon的云架構中,也有類似方案,采用Haproxy進行路由,中控節點會刷新對應的路由信息。

    Google 親兒子 K8s 也是如此,考慮到了 Proxy 的性能問題,進行了折中處理,采用 Iptables 規則注入的方式進行轉發(當然,這種方式也有不可回避的問題)


    這些方式都有其對應的問題,但是最大的一個問題即:

    如何解決其帶來的性能下滑。無論 iptables 或者采用 agent 來進行治理、轉發、通訊,都會面臨著一個繞不過去的問題,在高流量高并發的場景下,其對性能的損耗有多少?相比于眾多已經裝備有富客戶端直連的應用來說,性能的差距有多大?目前已知的部分產品,在高流量下QPS和RT都有著不小的損耗,有的解決方案甚至能夠達到20%的性能損耗,這明顯在很多場景下是無法接受的。

    這時候,Local Proxy 的最后一個殺器 — Servicemesh正式被推上風口浪尖,2018年也被稱為 Servicemesh 元年。我認為,其理念如下:

    1. 犧牲一定的性能和資源,換取服務治理理整體的?高度?自治和可運營
    2. 執?行行和控制分離,數據平?面和控制平?面切割
    3. 虛擬化、標準化、產品化,定義規范。

    Servicemesh 從雜亂無章,百家齊放的 Local Proxy 思潮中解放出來,提出了更系統地思考。本文無意對 Servicemesh 做更多概念性的描述,網上已經有相當多類似的文章,此處限于篇幅不展開。于是,有多家巨頭合作的 Istio(其本來目的是為了幫助應用更好地上云)的珠玉在前,其他公司也紛紛基于/參考Isito做出自己的解決方案:

  • 阿里基于 golang 重寫了 Envoy 并在這基礎上構建了 Sofa-Mosn/Pilot,
  • 下沉了 Istio 中頗受詬病的 Mixer 的限流能力,
  • 騰訊基于 Envoy 進行改造整合內部的 TSF 服務框架,
  • 美團基于 Envoy 改造整合內部的 Octo 服務框架,
  • 微博基于 Motan-Go 研制出 Motan-Mesh,整合了自己的服務治理體系,
  • 華為的 ServiceComb 也是類似的做法, Mixer完全下沉,
  • Twitter推出 Conduit,基于Rust,也將Mixer完成下沉,
  • 貓眼參考了 Envoy/Sofa-Mosn 的架構,自研了Maoyan-Mesh。
    ……
  • 但是,Servicemesh 仍然有幾個問題沒解決,除了仍然繞不開的性能問題外,目前也有越來越多的人在進行mesh反思一個問題:

    控制面板和數據面板切割的標準是什么?是不是過于理想化了?

    這個問題目前見仁見智,此處不展開。雖然 Servicemesh 目前還在起步階段,很多問題也還在摸索中,但是從微服務領域發展的趨勢來看,上文所述的 Servicemesh 的三個理念與其不謀而合,必然是未來的大勢所趨。

    2.4 總結

    這一章回顧了服務治理的發展歷程,經歷了三個大階段的思潮,我們回歸初心,可以看到每個階段的方案其實都有其適用和不適用的場景,沒有最好的方案,只有最合適的方案。我們也可以沿著這三個階段的思考邏輯發現,其實對于服務的治理,也是處于一個反復摸索、糾結,螺旋上升的過程。

    3. 我們需要什么樣的服務治理

    我們了解了什么是服務治理、服務治理是怎么演變發展的,這時候,我們不禁會想,我也要做服務治理!但是,請先停一下,請先問一下自己,我們需要什么樣的服務治理?

    這個問題很好回答,同時也很難回答。簡單來說,這取決于三要素的發展現狀。取決于你的組織、業務和系統的健康度、匹配度和成熟度。但這個形而上的“道”,如何轉換成形而下的“器”,確是需要結合實際場景case by case去思考的,沒有標準答案。

    你可以說 All In One 的巨無霸工程在創業初期短平快的組織結構和業務試錯情況下能夠快速發揮作用,
    也可以說雖然洋蔥架構如此多的層次讓你剝開之后只想哭但是能夠在特定的組織結構下起到微妙的平衡,
    你也可以說你暫時并不需要彈性不需要高性能因為權衡起來性價比不高,
    你甚至可以說不需要微服務因為運維成熟度完全跟不上。
    ……

    發現沒有,所以,這才是對架構師而言有趣而有挑戰的地方,服務治理從廣義上來說,并不是一個技術問題,而是一個有趣的哲學問題。架構師需要利用其前瞻和洞察的能力,引領團隊走向正確的方向,而不是一味糾結于是不是沒有響應好所有的訴求,是不是沒有遵循所謂的最佳實踐。這么考慮一下,如果世界上只有一種顏色,只有一種解法,那未免也太無聊了吧,這個世界的有趣不正在與你養出的那只充滿了“迫不得已”而又“正該如此”的薛定諤的貓嗎?

    4. 應用領域的指導原則

    4.1 四個問題

    網上有很多關于應該怎么拆分服務的文章,更多偏向技術層面。此處不加以贅述,我們討論四個問題,也是經常困擾我們的四個重要問題:

    應該在什么階段進行拆分?
    如前面提及的,考慮下你的業務迭代速度是否會引起系統所有權和使用權的競爭,進一步反向制約迭代的效率;考慮下是不是大應用導致你技術升級優化和資源的使用上困難重重;考慮下公司的運維水平和團隊成員的素質是不是能夠支撐起更細粒度的微服務體系結構。你考慮清楚了這三點,你就知道你是否應該進行拆分了。

    應該按照什么維度來拆?
    大原則上來說,按照業務領域進行拆分即可。在領域之內,進行分層拆解,將接入層、邏輯層和數據層復雜到一定程度的時候進行橫向拆解。《微服務設計》一書中,提到了“限界上下文”的概念來讓系統和業務邊界進行對齊也是類似的道理。

    服務拆分到多小算小?
    有一個說法是“確保兩個星期之內能夠重構”。這和敏捷開發理論中的“重構式迭代”不謀而合,不過我覺得這種理論有待商榷,在大量的實際場景中不是很適用。我比較認同的是另一個說法—“足夠小就行”。沒有唯一的衡量標準,這個取決于你的業務發展速度,業務復雜度,技術棧異構程度。很多人的傾向是,更愿意對一些功能在不明確后續發展的時候,盡量能不拆就不拆。這同樣也是我的建議。另外建議,確保一個服務只有一個團隊在維護,這能避免大量的問題。當你發現有多個團隊在維護的時候,說明你可能需要拆分了。

    微服務團隊需要多大?
    亞馬遜創始人貝佐斯的“兩個披薩”原則基本適用,該原則為“每個內部團隊都應該足夠小,兩個比薩餅就能解決伙食問題”。這樣團隊更容易具備戰斗力和凝聚力,也能擁有更好的效率和對未來的應變能力。

    4.2 組織邊界的兩個原則

    服務治理三大要素中,我認為組織(即人)是最為重要的一個因素,也能夠對其他兩個因素起更顯著影響作用的因素。如下兩個定律在業內鼎鼎大名:

    1. 康威第一定律:組織溝通方式會通過系統設計表達出來。
    2. 咨詢第二定律:不管一開始看起來什么樣,它永遠是人的問題。

    人是復雜的動物,你必然會發現,脫離組織結構來談最佳的系統設計是不切實際的。無論我們的初心多么的純粹,希望兩個組織結構一起協同做一件類似的事情,最后你基本都會發現,會做成兩件事情,或者你將擁有一個跨多團隊的n層洋蔥圈架構。你可以動用行政的方式讓多團隊按照你的設想精密地共同完成一件你畫好藍圖的大系統,但是往往最后的代價就是跌入谷底的效率和員工幸福感。

    所以首當其沖,我們應該倡導組織邊界和系統邊界/業務邊界對齊。比如當你不得不面對分布式異地辦公的服務治理場景時,考慮盡可能地讓每個辦公區的團隊承擔獨立業務的服務系統。這也是 Amazon 和 Netflix 等公司所踐行的原則。

    5. 技術領域的指導原則

    面向技術領域,這個問題比處理上面的問題要更直接而明確,我們挑選其中四個方向來鋪開分析:

  • 可運營
  • 高可用
  • 高性能
  • 自動化與標準化
  • 5.1 可運營

    我們認為可運營的核心在于可觀察,以及在觀察之后的可控制

    5.1.1 可觀察 — 監控報警

    可運營的前提和核心即可觀察,這即進一步要求我們需要有足夠立體的監控報警能力來支撐。這也很大程度決定了我們服務生態體系的想象力。

    一般劃分的維度,我們可以自底向上劃分為:基礎設施級監控、系統級監控、業務級監控、產品級監控。每個層級的監控都有自己的關注核心和邏輯,基礎設施級的監控比如運維層面會更關注機器 CPU、MEM、磁盤 IO、網卡 IO 、CDN 速度、多IDC延時等。系統級監控更關注單應用內,如JVM使用、堆棧、線程情況,拋異常 case、彈性指標、TPS、RT 等,以及跨應用的調用鏈路健康情況。業務級監控更偏業務導向,如下單人數、庫存余量、支付數、退款數、UGC 增量等等和業務直接關聯的指標;而產品級監控則會從產品整體去進行核心產品指標的定義,比如產品留存率、頁面轉化率、營銷支付轉化率、認證人數、認購單數等等。比較常見的監控報警產品有 Falcon、Zabbix、Nagios、Cat、Prometheus 等。

    日志也是監控的一環,業界有開源的解決方案 ELK,但 ELK 本身存在很大的優化空間,所以很多公司都會基于 ELK 或者基于他的采集模型做定制化開發。

    需要特別提到的是,需要正視四個層級的立體式監控情況下可能引發的報警風暴問題,這就需要能夠有決策中樞進行報警的分析、關聯和聚合,并且可以提供對應的ACK機制,這則是一個長期的建設過程。

    5.1.2 可控制 — 指令下發

    除了可觀察外,可運營的另一關鍵就是能夠動態下發指令或配置,這樣才能真正意義上實現可控制的目標。一般來說:

  • 基礎架構/運維層面偏向于使用 puppet、ansible 之類的批量下發工具來進行指令、配置、安裝包之類的動態下發。但 ansible 由于權限過大的問題,使用時候要慎重。
  • 而在中間件層面,更多采用配置中心、注冊中心來進行下發。下發的方式,可以是推、拉或者推拉結合的方式來進行。二者的底層存儲選型其實比較類似的,所以也有一些共性問題需要注意。比如你考慮一下,你做好迎接 Zookeeper 給你帶來的 watch 事件丟失以及重度 SDK 引入潛在風險的挑戰了嗎?你做好 etcd 很難擴展且無法做多中心的心里準備了嗎?你做好接受 Consul 雖然天然支持多中心但是事件監聽弱得讓人無力吐槽的心里準備了嗎?你做好 Eureka 過分強調 AP 而可能帶來的極端情況下各種異常 case 嗎?你甚至,是不是有種想要自己簡單實現配置中心和注冊中心的沖動?那么你想好對 CAP 的權衡,想好幾大核心操作如何實現,想好如何設計推拉模型了嗎?
  • 5.2 高可用

    高可用即如何讓你的服務保持彈性,或者也有文章稱之“反脆弱”。在我看來,高可用出現的目的即為應對故障,沿著故障的生命周期,我們也同樣將高可用的領域劃分為事前治理事后治理兩大階段。

    5.2.1 事前治理

    在故障發生之前,我們能做哪些事情,即稱之為事前治理。我們認為,在這個階段主要的技術上的措施有兩個:

  • 基于經驗的環境重塑-壓測演練。成熟的分布式服務環境,大部分的嚴重問題都會出在高流量的場景下。所以我們最好的方式就是構造這樣的環境,在業務高峰來之前,先進行對應的壓測演練,以進行問題的試探。健全的壓測體系強依賴于分布式鏈路系統在全鏈路中傳遞壓測標,這樣業務、中間件和基礎設施才能識別流量類型,并進行對應的處理,比如 Kafka 可以對壓測標隔離出單獨的 Topic,數據庫中間件可以對壓測標隔離出壓測影子表。
  • 避免失敗的方式就是經常失敗-故障演練。我們知道壓測只是一種基于經驗的環境重塑,希望通過不斷試探系統在高壓下的反應來檢測出潛在的風險。而根據“墨菲定律”我們知道,如果有事情變壞的可能,那它總會發生。特別是在大量節點并存的網狀服務拓撲中,這種概率就會不斷被抬升。避免失敗的方式就是經常失敗,所以我們需要主動模擬各種故障來檢驗我們系統的彈性。Netflix 的“猴子大軍”可以隨機模擬進程故障、機房故障,阿里也基于強弱依賴的理論進行了故障演練的豐富實踐。如果想做一套故障演練系統,那么阿里開源的 Sandbox 就非常適合對Java進程來做這件事情。
  • 5.2.2 事后治理

    在故障發生之后,我們能做些什么呢?歸納來看,最核心的無非就是限流、熔斷、隔離、降級。限流熔斷可以基于線程數控制、信號量控制、固定窗口計數、滑動窗口計數、令牌桶計數、漏桶計數等等的方式來進行流量的限制,單機限流熔斷相對簡單,Google 的 Guava Ratelimiter 就是一種很好的實踐,整合了令牌桶和漏桶的方式,對于需要預熱和不需要預熱的場景都做了充分支持,Hystrix 也提供了數種限流、熔斷和隔離的方式。當然限制之后,如何恢復也是一大問題。是要階梯式恢復,還是時間窗口恢復,還是需要驗證碼恢復,都存在著很多的使用場景,不復贅述。

    但是,如果放在分布式的環境下,這個問題將會變得復雜得多,比如是否要做富 SDK?比如是否要在 SDK 中引入其他中間件比如 Redis?比如采集數據的延時問題可能引發的誤判如何解決?分布式環境下我們能信任什么數據?

    目前比較主流的分布式環境下的限流熔斷仍然采用的富客戶端的方式來實現。貓眼基于自身現狀和訴求,采取的則是輕 SDK + 重 Server 的方式來進行。基本所有的決策都在 Server 端進行。通過這種方式,實現了與業務較大程度上的解耦,并且為以后的聯合決策提供先決條件。

    5.3 高性能

    如何才能讓我們的服務保持高性能狀態?加緩存、做靜態化、預熱、做異步、搞并行、業務優化、服務分級分流、硬件加速之類的就不贅述了。晚上很多類似的文章,而我這邊比較感興趣的,也主要想和大家討論的是,服務治理框架的一大核心—底層通訊層面上,如何才能做到高性能?這就離不開幾個法寶:

    5.3.1 直連

    連接方式上,直連帶來的性能優勢毋庸置疑。大部分的分布式服務框架都會采用直連的方式進行服務間的通訊。

    5.3.2 高性能序列化

    在高并發情況下,序列化有可能會成為你的性能熱點。適當時候考慮下 pb、json、gson 或者自定義的序列化協議。自定義的序列化協議需要考慮如何壓縮空間,并能夠便于框架的提取解析,比如螞蟻金服的 Bolt 協議里約定的魔數、固定頭、變長頭、包體等的方法論就是一個很好的例子。

    5.3.3 Zero-Copy

    Zero-Copy 是一個大殺器,在 Nginx、Netty(不是傳統意義上的 Zero-Copy)、Kafka、RocketMQ 等項目中被使用,在合適的地方利用這個特性,比如磁盤順序讀 + Mmap + sendfile,你的系統性能將瞬間提升幾個數量級。

    5.3.4 Epoll 多路復用

    Epoll相比于自己用宏定義把自己坑死的 select,以及后繼者 poll 來說,在使用限制上以及性能上有著明顯的飛躍。也是目前最主流的 IO 模型。現在各種業內風靡的高性能服務器設計,Epoll 基本都是必然采用的 IO 模型。當然 Netty 也采用過真正意義上的異步 IO - AIO,但是由于 Linux 的AIO目前尚不成熟等原因,最后的效果不好所以并沒有真正推開。

    5.3.5 Reactor線程模型

    基本高性能服務的底層都采用了Reactor模式來實現線程模型。當然,配合線程池/協程池,以及 Reactor 的層次,可以有多種的實現路徑。有類似 Nginx 這樣的一主多子進程 + 單 Reactor 單線程(高版本提供了線程池機制)的模型,evio 和 Envoy 利用“單 Reactor 協程池(線程池)”, Netty 采用多級 Reactor + 多級線程池。

    5.3.6 字節重用

    我們習慣于對每個請求去新創建一個他所需要的空間來存放一些信息。但是當并發量上來后,這樣的空間分配將會導致較大的性能開銷和回收壓力。所以基于伙伴算法或者Slab算法或其他的方式,進行一個字節內存使用的分配管理,將會讓你收益良多。比如 Netty 由于申請了堆外內存而采用了伙伴算法,Nginx 則采用了 Slab 機制,Mosn 在 Golang 分配機制的基礎上引入多級容量加 sync.Pool 機制的緩存來進行優化。

    5.3.7 本地通訊優化

    如果你的服務通訊是采用的 Servicemesh 之類的 Local Proxy 來進行轉發,那么應用服務和 Proxy 之間的通訊鏈路可以基于本地進程通訊的特性進行優化。比如利用 mmap 進行進程間的通信,可以減少內核切換次數,這能讓你獲得意想不到的收益。traffic-shm 是一個異步無鎖的IPC框架,能夠輕松支撐百萬 TPS,其就采用了 mmap 來進行通訊。

    5.3.8 內存對齊

    操作系統按照頁進行內存管理。如果你直接操作內存地址進行數據傳輸(比如用 mmap)的話,那么如果沒有內存對齊,將會導致你拉取到并不需要的內存空間,且會有內存移動拼接的額外開銷,這將會直接導致你性能的下滑。高性能內存隊列 Disruptor 也是采用了內存對齊的方式進行優化。

    5.3.9 無鎖化

    通訊的第一反應即需要處理并發安全的問題,很多時候你可能不得不通過鎖的方式來保障安全。這個時候,考慮下通過利用硬件層面的CAS操作來替代常規的鎖操作,也可以采取類似 Redis 這樣單線程處理的方式,或者 Envoy 這樣雖然采用了線程池,但是連接會進行單個線程的綁定操作來規避并發問題。

    5.3.10 池化

    線程資源是很寶貴的,加上線程本身不可能申請幾千上萬個出來,所以線程池是默認的標配。這邊要談的是,比如你用了協程技術,雖然協程被神化為輕量級線程,性能非常高且可以輕松開出幾萬個而面不改色。但是你需要知道,這也會很嚴重地影響你實際的處理性能,并且由于 golang 本身的協程分配原理,協程的一些元數據并不會在使用后被回收,這是由于 golang 開發者的理念是“一旦到達過這樣的流量,就說明系統有可能再次面臨這樣的洪峰,那么就提前做好準備”。所以我們對于協程,仍然需要考慮池化的問題。Motan-Go 和 Thrift 的 golang 版本中目前并沒有這方面的考慮,而 Sofa-Mosn 已經做了對應的池化處理。

    5.4 標準化與自動化

    如在前面章節中提到的:

    犧牲一定的性能和資源,換取服務治理理整體的高度自治和可運營

    我認為在未來的成熟服務治理中,比起絕對的性能表現,我們更關注應用服務拓撲是否能夠真正成熟到可以“自動化”甚至“自治”的程度。盡可能地解放人力操作,將其進化為機器語言。比如我們提倡自動化部署、自動化壓測、自動化故障演練,自動化系統測試,自動化限流熔斷,自動伸縮等等,都是在各個領域應用自動化解放人的雙手的很好示例。
    但,服務治理上,如何才能實現更高效的自動化呢?我認為:

    自動化是治理的高級形態,而標準化是規模化治理的前提。

    只有標準化,才能簡化復雜服務世界的問題,將各種異構場景盡量同構建模,如此才有可能用可控成本完成規模化的服務治理,進一步完成大規模的自動化。 標準化,意味著你要考慮的差異性越少,你治理的成本越低,你能自動化的程度就越高。
    你可以認為:

  • Docker 其實就是部署級別的標準化,通過它可以很好地標準化環境,也可以提供標準化部署運維的手段,甚至我們可以通過容器來標準化服務治理的核心設施,通過容器對我們應用的改造和適配,我們就可以輕松完成大規模的自動化部署和彈性伸縮。
  • Servicemesh 領軍項目 Istio 的控制平面,也很好詮釋了什么叫標準化,Pilot 標準化了異構的配置下發能力和注冊中心,Mixer 標準化了遙測和限流的能力(當然,這在業內有一定的爭議)。
  • 阿里的 Sandbox 標準化了 AOP 切面的編織過程和完整的生命周期,讓使用者相比于傳統的方式節省了非常多的成本。
  • 你甚至可以認為,大多數的框架,本身就是一個標準化的過程。
  • 這時候的你,是不是認為,標準化其實無處不在?是的,沒錯。介紹一個有意思的“奶牛和寵物理論”,大致意思是:

    你不應該老是想區分哪些服務是奶牛,哪些服務是寵物。生了病就殺掉它而不要去想區分出哪些是寵物并治好它。

    是的,區分得越少,你的系統將越可靠,你的煩惱就越少。回到初心,其實都是一樣的。
    記得關注自己構建的系統生態之上的研發同學,如果他們終日忙碌,那么請抽時間和他們一起停下腳步審視下系統標準化和自動化的進展,或許你會有意想不到的收獲。

    6. 結語與展望

    我們來回顧一下,在第一章,我們講述了什么是服務治理,認為服務治理即治理三要素和服務環,第二章,介紹了服務治理的發展演變,簡單介紹了三個階段的思潮和演變的邏輯,讓我們對于目前服務治理大發展方向和未來的發展趨勢可以有一個初步的預測。在步入實際一些實踐雜談之前,我們需要先問清楚自己一個問題,我們需要什么樣的服務治理,第三章我闡述了我個人的理解,這其實是一個哲學問題。之后的兩張,則從業務應用層面,以及從底層基礎技術領域,挑出了幾個我認為比較有意思而重要的思考和實踐來與大家進行討論。當然,限于篇幅,我無法展開的論證每一個點,也由于自身能力和實踐的限制,多少會有一些謬誤的地方,也歡迎大家隨時指出。

    如標題所示,這只是服務治理整體的漫談,偏重于從整體視角來理解服務治理的內核,并對一些很重要但很少被系統性談及的部分進行進一步的解讀。后續我會進行服務治理每一重要層次和環節的剖析,我們不僅希望結合實際生產實踐來分析具體的系統架構,也希望通過對架構的剖析能進一步地去洞察設計者的意圖和思考邏輯,知其然而知其所以然,這是我認為架構師領域非常重要的一個技能,也歡迎大家持續關注。

    總結

    以上是生活随笔為你收集整理的【服务治理】服务治理漫谈的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。