9月23日,數人云&又拍雲在北京聯合舉辦了將微服務進行到底的線下沙龍活動,數人云產品總監了哥(邱戈川)作了高併發微服務平臺實踐的分享,從微服務的優點出發進行了深刻探討,如下是本次分享的實錄。前端
說到微服務,在和你們討論時發現最大的問題是,是否要落地實踐微服務?由於不少企業並無達到所需的規模,因此,在準備實踐微服務以前須要考量的幾個問題是:數據庫
若以上問題都不存在,建議仍是以三層結構的模式,不要給本身挖坑跳不出來,並不是全部企業度適合微服務。後端
若是以傳統的RPC結果去應對大規模互聯網架構,對於一些企業並不適用,不少RPC結構並不是爲了高吞吐而是爲了快速響應,由於不少時候須要先後端的資源一致,不過一些企業有歷史包袱,前端接受請求和後端的服務資源不能徹底匹配,因此此時,不能用簡單的RPC方式去解決。多線程
業界作微服務一般容易忘了比較重要的一件事:服務治理,用SpringCloud或Dubbo多數用的是一個開發框架將客戶端和服務端調通,基本上是人爲經過服務註冊發現的方式找到服務以後再完成調用,一個很大的誤區是,認爲這就是微服務了。架構
另外不少企業不但願丟消息,也並不須要很高的快速響應,來了客戶請求,寧願等一下也是能夠的,如果這種請求,RPC也並不必定徹底適合。併發
業務邏輯是否須要每次都進行更改,互聯網腳骨裏面很重要的一點是業務開發一直在持續迭代,但傳統企業很難作到,由於有預算資金、業務規劃等方面的約束,並且還須要保留以前已經作好的系統。框架
微服務其實很是複雜,並非全部的人、企業均可以搞定,入坑以前必定要進行完整的考慮。運維
傳統企業最容易面臨的問題首先是業務模式上的變化,一些企業原有的模式是人和人打完交道後人爲在系統進行操做錄入然後走相關流程,不少業務模式都是基於這種方式去走,但問題是一些系統在開發時就已經肯定了用戶的訪問規模,併發程度等,若系統是這種條件下,其實一個簡單的Tomcat就能夠搞定,哪怕用兩個或三個,也能夠。異步
但有的企業在這種情景下,搞了一堆小型機,這是比較要命的問題,所以在這種條件下,不要去作微服務,但若是業務開發模式發生改變,要向互聯網轉型,一些出口要往互聯網開,不管是電腦端或移動端,只要往互聯網開放,就要去考慮是否須要走互聯網機構或微服務架構的問題了。數據庫設計
不要把原有的系統直接放出去,須要在中間環節考慮保護性和吞吐性的問題,這是業務模式的變化,當業務模式沒有變換前不要輕易地去改變架構,並非說微服務要將原來的體系所有推翻,這是不合理的。
〓 業務開發的變化
還有一點是業務開發的變化,以前提過,不少傳統企業須要半年或一年的規劃,但如今是兩週一個迭代上線,一些公司如豆瓣等,一天變三四次都有,因此須要看總體變化規模有多快,若沒有這個變化,慢慢作均可以,也不必定須要微服務了。
〓 用戶行爲的變化
最重要的一點是整個用戶行爲的變化,不少時候,舊系統訪問行爲是在很窄的範圍內,例如,某個普通系統一般美妙十幾二十個TPS,咱們看到不少文章都提到一天的訪問量是幾百萬次,會以爲組ode很大,但去算一下,若24小時按照每秒是多少次?實際上不多,一天幾百萬次並不表明訪問量很高,另外,互聯網模式下,用戶規模和訪問時間都發生了變化,因此訪問的次數分佈也會發生很大的變化,特別是將出口開到互聯網後,一些業務性的攻擊也會來臨,這些是不少傳統企業沒法應對的。
〓 業務對原有架構的衝擊
上圖是一個簡單的傳統三層架構,從Nginx或F5這些負載金恆進來,一些大型企業都是買的硬件F5,中間件走的是Weblogic或Websphere,而後再到數據庫,只要是這樣的架構,即使買來很好的WEB服務系統,但訪問模式變了,最容易掛掉的地方是數據庫,曾經有個合做夥伴作了一次店慶促銷就是這樣,互聯網公司作促銷都是先作幾天預熱,而後再去開賣,但在預熱階段就已經掛掉了,由於預熱要派卷,數量有限同一時間用戶去搶卷,併發量就會突增,這是傳統架構比較難處理的地方。
〓 對運維形成的衝擊
給運維帶來比較大的衝擊是:曾經運維管理都是有特定的時間段,但如今須要24小時全天候值守,所以帶來的問題是在線升級,傳統的運維方式是停機、換包、改配置、從新上線,發現問題後須要從新下線反覆上一個循環,如今須要所有在線滾動升級、灰度測試等,另一個給團隊帶來的衝擊是一些公司依賴於外包,以前咱們的客戶有不少狀況是一個供應商拿着SpringCloud作開發,另一個拿着Dubbo作開發,最後運維不知道該如何去統一運營,由於兩種模式不同,最後出維內託的時候抓包對包都不知道如何去作。
如今愈來愈多的公司要求在大的層面統一基礎框架也是這個緣由。
〓 水平擴展是否可行
業界不少容器公司都說能夠幫助應對大規模的攻擊,其實主要就作了一件事:作水平擴展。Weblogic、Websphere打包方進容器,須要時就擴展,但擴展的越多,死的越快,由於數據庫的強一致性依賴,前面接受更多請求數據庫更加頂不住,因此在互聯網架構下,任何一個公司都不敢直接將數據庫強關聯的系統對外暴露出去,因此去IOE的概念是把數據庫用的愈來愈弱,在互聯網架構裏數據庫設計的幾個範式是要被打破掉的,互聯網機構裏面是有很大的冗餘度,例如先後端都有用戶信息,另外就是這種架構下業務是一個總體性,變更起來會很麻煩。
〓 微服務體系
提及微服務,上圖是從Microservice.io截過來的,核心的概念是將系統拆分,每一個組件都有本身的庫,只要將庫拆了,庫與庫之間可能要作相關的一致性同步處理,限於時間問題,今天不作擴展。
〓 微服務與RPC
SpringCloud也好,Dubbo也好,實際上只有Client和Service兩層架構,中間的Service Mesh是由Google和IBM推出的最近比較流行的一個概念,實際上已經有不少互聯網公司已經在應用這個概念,它們只是將其抽出做爲獨立的概念,而後推到了CNCF,比較熱門開源的有Istio、Linkerd等。
原來Client到Service端的微服務架構有個較大的問題是將不少的服務治理放到客戶端,客戶端要作服務治理升級,全部的客戶端都須要進行升級,帶來的運維複雜度和錯誤率方面提高,因此Service Mesh核心思想是將不少服務治理抽到中間去作,所以微服務治理愈來愈多作中間化處理,並非在客戶端和服務端作治理,如今這個概念比較流行,但也暫時不去作擴展。
微服務架構是否等於作RPC架構?這是一個值得討論的問題。
〓 微服務是一個體系
須要注意的是,微服務是一個體系,這也是爲何前文和你們說不要過多地去考慮微服務的緣由,由於很難有公司能自主構建出如此龐大的體系,不少大型的互聯網公司都要花費兩到三年的時間才能將整個體系構建的比較完整,讓業務開展順暢裏面有太多的東西須要去作,雖然一般只看到一個開發框架和服務註冊和發現,但後面有不少的東西實際上都沒有去作。
〓 微服務後的開發方式轉變
微服務後整個開發模式會發生變化,不要認爲微服務只是架構上的變化,這是一個很大的誤區,微服務進來之後,不僅僅只是架構上的變化,更多地是組織和流程都發生了改變,CI/CD和DevOps最近兩年比較火其實和微服務有很大的關係,這個概念已經有近十年的時間了, 但不少事情都沒有用,道了微服務纔去考慮這個問題,由於服務數量持續增大痛點纔會出現,團隊的構建不像之前那種傳統的有開發部門、運維部門。測試部門等,如今越多傾向多功能團隊的緣由就是由於須要快速迭代、測試開發、以及產品、運營做爲一個總體團隊來作業務開發。
〓 開發團隊的適應
上圖是團隊混搭的模式,必定要作到全功能集合,不可能再去作某個只能劃分,這對不少公司是一個挑戰,由於這樣的設計,不知道公司部門領導什麼設置,是設成開發部去領導仍是測試部去領導,不少公司不肯改變跟這個也有必定的關係。
〓 傳統企業微服務如何起步
前面講得比較傳統,阿里提的Dubbo有5年以上了,體系都比較大,雖然開發模式比較簡單,但總體體系很是龐大的後果是迭代速度不必定徹底適合中小型企業,由於應對場景不一樣,但願在微服務理念下能構建一個更小的體系,去應對吞吐這個主流的場景,特別是搶紅包或者一些優惠券的場景,而不但願去用一個大的完整的體系,由於沒法快速構建出來。
須要將架構構建的更簡單一些,不須要太多的東西,架構上面前端沒有變化是F5或其餘的軟LB的方式,從前臺、中臺、後臺的概念來講,前臺基本用Tomcat去頂,這個沒有太好的方式,由於你們都知道,每個需求對於Java體系來講,一個請求就是一個線程,因此要支撐足夠的併發和吞吐,就要有足夠的線程,因此只能用更多的Tomcat去頂這個線程數,若是是容器化的方法,就打開足夠多的Tomcat容器實例便可,因此容器不少適合你們用的就是它這一點,快速開足夠多的實例數。
但不可能將全部的流量如RPC那樣直接傳到到後端,因傳統系統是頂不住的,一些企業很難去改造傳統的業務系統,好比下面有財務或帳務處理等不可能改變,大的互聯網企業在進行微服務架構改造時,是一整套系統所有概念的,這是很傷筋動骨的事情,可是沒有更好的辦法,惟一可以作的就是在中間層加一層消息,好處是不須要前端那麼多的實例數,後端能夠用更少的實例數,慢慢去消費最後將信息反饋出去,這樣能夠保護好下面傳統的系統,特別是保護好數據庫,這也是一個比較容易考慮的架構。
然後,微服務體系裏面須要考慮如何作動態的管理,一些監控的體系,而後與容器作結合,將操做流程作的更簡單,因此將架構簡單化時會這樣去考慮。
〓 微服務支持高併發平臺的願景
實際上須要構建的是這樣的一個系統:將開發作的簡單一點,有幾個接口傑克,你們用SpringCloud的目標其實只是認爲那是比較好開發的框架, 不須要考慮不少通訊上的問題。另外能夠作到高可用,支持更多的併發,同事是一個平臺作統一配置、監控和管理,儘量作高吞吐數據儘量地不丟棄而且能跟容器作結合從而輕鬆運維。
〓 基於消息的微服務架構
咱們將這個系統構建出來,實際框圖就比較簡單了,中間須要一個消息隊列,須要一個Kafka、它能夠去頂高吞吐的事情,Kafka剛發佈了0.1的版本,能夠做爲所謂的Exactly Once,一個消息只執行一次,客戶端和服務端提供服務無註冊和服務發現,這和RPC是一樣的道理,可是這裏的服務發現作了改變,通常的RPC微服務都死將IP和端口註冊上去,而後再把IP和端口列表拿回來隨機的分發,可是消息微服務不關心IP和端口,關心的只是服務名稱對應的消息Topic,發給消息給一個服務,經過服務名稱發現服務的Topic,而後發送消息到這個Topic便可。
〓 服務高可用
前文提到,高可用是一個很簡單的事情,一般作法是本身有調度器,會箭筒Zookeeper節點,全部的服務運行起來時都會註冊到Zookeeper的這個節點上,調度器就可知道Zookeeper這個服務已經有兩個實例,它會統治這兩個實例跑哪些任務。
當掉線時Zookeper上面的這個實例的臨時節點會被清掉,這時調度系統就能知道有節點掉線,將它所有遷移到沒有掉線的街上,這樣比較容易作高可用,高可用的機制大體如此,因此想作高可用,就須要引用一個協調的集羣如Zookeeper、Etcd等來作。
〓 動態治理控制
另外要作一些動態性的治理,最容易考慮的問題是要不要作多級別的超時,一般一個客戶端設定默認超時便可,但客戶端調A服務和B服務的超時是不同的,這樣多級別的設置不可能放到配置文件裏面去,能夠作的事情所有經過統一的平臺動態去作,而後實時下發,這也是一個很重要的概念,全部的服務治理都是動態化,配置界面針對客戶端調用某一個服務單獨去配超時,全部更新會實時生效,由於全部的協調集羣均可以作到動態推送。
〓 客戶端禁用
還能夠作服務的禁用管理,不少微服務的客戶端將接受的請求直接打到後面將後面的服務沖垮,此時要緊急停某個客戶端才能夠,早前的反射弧是要找到機器而後想辦法登陸機器將服務刪掉,如今用了框架以後,只要發送一個指令,每次發消息判斷哪一個指令說是否是禁用,若禁用就不調用服務,全部的消息在客戶端報錯出去,這樣能夠實時保護客戶端的東西,在整個平臺裏若開了API,就能作緊急預案,若是發現某個緊急狀況,能將客戶端全部的請求屏蔽掉,作降級必定要考慮這樣的問題,不少公司不知道降級如何作,其實降級就是在什麼條件下,將哪些服務關掉,而後可以有首段能夠動態將某些服務逐步恢復過來這就是所謂的降級預案的作法。
〓 客戶端按照比重路由
既然能夠管控發送,也能夠協調客戶端往哪一個服務端發送的比例,按照比重去發送,這是比較常見的概念,按比重發送通常在生產環境用的比較少,不少時候作在線壓測用,在線流量不必定可以壓到某一臺機器上,因此須要將全部的流量都導入到那臺機器,這也才能知道在線系統可以支撐多大量,由於不少開發環境單獨行壓測是很難支撐這個測試。
〓 自身管理Dashboard
作Java要考慮的問題是包依賴的衝突,在架構裏將架構依賴和業務依賴脫離開,這是須要考慮的問題。
將不少東西統一在一塊兒,不想搞那麼多的事情,就須要作不少的Dashboard,愈來愈重要一點是考慮每一作一個業務都要想一想業務有多少指標,這些指標是什麼樣子,而後將指標彙總畫圖,因此你們作系統必定要考慮這個事情,Dashboard是愈來愈重要的概念儘管可能會花費一些力氣,但當出現問題時能及時發現,若沒有就等同於瞎子和聾子。
〓 兼容Prometheus的Metrics
固然自行作是一方面,可能作圖形等會比較麻煩,其實不少中後段的同事並不肯意作話題的事,有個更好的方式是按Prometheus的方式將全部的東西都吐出來將全部的指標全部的數據所有吐出去,吐完以後再用Grafana畫,能夠節約不少事情,因此要梳理好指標,將全部的東西所有吐出去,如今比較好的是Prometheus在整個中小型規模裏面比較容易接受,愈來愈成爲一個事實的規範。
〓 服務依賴拓撲
當談到微服務比較容易談到的一點是,必定要作APM,但消息量化比較大,須要一一對應日誌分析後才能把依賴找出來,這樣的複雜度相對高,但用消息作的好處是經過消息配置找到全部服務的依賴,根本不須要作任何的分析就把服務依賴找到了,這樣出問題便可很容易發現,因此這種服務依賴比較容易作,但想真正作調用鏈,將調用鏈日誌找出來就要單獨考慮上APM的事情,因此係統到了哪一個規模再去考慮其對應的問題,不可能如今沒有這個規模就一下將龐大系統搭建起來,由於可能一天下來就是一百屢次調用,出問題時找下日誌就能夠搞定的問題,但上一個APM沒有經驗那就可能將本身搞死了,因此就是說如今也是這樣的方式簡單的依賴方式,但作APM這個事情也能夠考慮要把釦子留給APM,後面對接到APM便可。
中國人開源APM並很少,如今基本上能看得見的中國人作的APM開源系統就是Skywalking,你們能夠搜一下,同時支持SpringCloud和Dubbo,是Opentracing的標準。
〓 系統無侵入性擴展架構
接下來,要考慮怎麼作無侵入擴展,若你們用傳統的RPC的方式作微服務,最大的問題是若是出現業務的變化都要作什麼事情呢?通常都是增長接口重構系統,增長某個環節,但對於不少企業很難的緣由是下面有不少的系統都是一個固有系統,不可能扔掉重來,互聯網公司喜歡扔掉再重來一次,可是傳統企業很難作到,因此考慮用消息作微服務時,能不可以作到能夠無侵入插入一些額外的邏輯?
如今都在談大數據,不管是否有需求,一天十萬行數據也要作大數據,都已經到了這個程度,這時玩大數據就須要作大數據的採集,有不少種手段,包括用Java Agent插入,強行插進去代碼作也能夠,但用消息有一個好處,將不一樣邏輯的處理模塊都掛在消息集羣下面,只要把消息都在這些模塊中流轉一次便可。
〓 擴展機制:Filter Chain
咱們提出一個概念叫FilterChain,意思是每一個Filter都被認爲是消息服務,消息服務啓動時會註冊上系統,當註冊上來系統就知道這個Filter已經掛載上來,在配置上高速哪一個客戶端發到服務端時要通過那些Fitler,把這個配置配置好,就把它通知到客戶端的SDK裏面,開發商仍是從客戶端發送到服務端,但框架發消息會看這個Filter Chain到底往哪裏走,而後將消息按照這個規則往下一層一層傳遞,傳遞的過程當中也會把下一級的規則一直往下傳,最後沒有Filter了再發到服務端。
傳遞的每個環節是能夠並行或串行的,舉個例子,若是發到下一個環節只是作數據收集,根本不關心數據包是否合法,這個時候數據採集環節是能夠將消息並行直接轉到下一個環節處理的,若是要作審計,看看那個包是否合法,實際必定要等那個結果才能往下傳,這時要作串行,所以是一個比較好的概念,但要是RPC的方式實現這個理念,仍是比較麻煩的。
〓 消息流轉
消息流轉是比較簡單的,首先配置怎麼作這個事情,剩下的事情SDK根據Filter Chain的順序一層層往下走便可,代碼實現並不複雜。
〓 三種調用模式
既然提到開發上會不會很複雜這個問題,咱們的作法是從新封裝消息的交互,咱們是想作到開發是阻塞應答的模式,下面是消息異步傳遞,但實際上更好的方式是開發也是異步回調,這樣的方式處理消息,會節約不少線程的資源。
〓 更多
固然還能夠作更多的事情,包括有統一的平臺能夠逐漸擴展這些功能,IDC的問題,像是這裏面多IDC處理反而更簡單,根據配置將消息發送到不一樣的IDC的Kafka集羣便可,無需作特別的處理。
〓 爲何要容器化
另外須要考慮容器化,如今容器化部署能提供更多的靈活性和彈性,簡化運維等,一年前談容器化都在觀望,而如今都已經開始作了。
〓 自動調度理念
這個框架還有一個好處,將容器資源調整和消息系統兩邊一塊兒作伸縮調度,衆所周知,若是用Kafka,吞吐量是靠它的分區概念去作的,能夠把Topic分不少的區供更多的消費者調用,容器是靠增長實例的方式去作擴容,因此想調度每個服務擴容時,會同步調整Kafka的分區和容器實例。
〓 問題思考
因此回到最後一個問題,不要認爲一作微服務就要經過RPC的方式作,經過消息的方式也能夠,另外要更多考慮吞吐的問題,由於把系統放出互聯網以後,容易遇到整個數據庫頂不住的問題,由於之前的作法一般爲了保護下面系統,RPC一般開一個限流,一限流至關於把前端也限住了,因此消息服務也是跟RPC不同的地方,由於有了消息能夠緩衝,消息接受就能夠不停,你們知道Kafka的消息都是羅盤的,而後再往下走。
其實消息微服務最好的地方,是能夠中間插入邏輯不影響已經開發好的服務,這個對於企業應用是很關鍵。
一體化異步微服務平臺基於容器雲平臺打造,支持同步和異步模式,具備高可用、高併發、無入侵性擴展業務、服務依賴實時跟蹤以及自動伸縮等特性,無縫融合物理機、虛擬機及容器,從而實現微服務統一管理、配置、監控。
以上內容整理自了哥(邱戈川)在9月23日Meetup上分享的分享,但願對想採用微服務架構的企業有所幫助。
注:一些圖片來自於互聯網。