<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • .Net微服務實戰之技術選型篇

    王者榮耀 

      去年我有幸被老領導邀請以系統架構師與技術負責人的角色帶技術團隊,并對公司項目以微服務進行了實施。無論是技術團隊還是技術架構都是由我親自的從0到1的選型與招聘成型的,此過程讓我受益良多,因此也希望在接下來的系列博文盡可能的與大家分享我的經驗。

      古人有云:將軍難打無兵之仗。想要把微服務很好的實施也并非能一個人可以完成的事,一來需要有出色的運維提供支持,二來需要花時間做技術選型與攻關,三來還要開發兄弟們配合實施。因此,這次能順利實施并不是一個人的王者,而是團隊的榮耀。

      框架源碼:https://github.com/SkyChenSky/Sikiro (文末有說明)

    工欲善其事,必先利其器

      以上是我們公司的技術棧(點擊圖片可在瀏覽器打開),除了統一配置中心沒有服務器資源和Hangfire還沒場景使用外,其他都已經上線使用了。  

      俗話說得好:工欲善其事,必先利其器。一個優秀的工程師應該善于使用框架和工具,在微服務這一塊的技術棧選型并非一蹴而就,也是我多次對比驗證后,并良好的集成到公司項目然后落地實施。這系列框架單純這么去用其實是可以無縫集成的,但是在落實項目的時候,我為了集成得更加友好和使用上更加便利,在基礎上做了擴展,例如SkyWalking添加Request和Response,CAP與Chloe.ORM的集成等,下文我會逐個分享。

      有需要的朋友可以參照我這套去實施,這樣大家就可以花更多的時間把精力放在業務、調優、拆分、設計等方面。

      此外大家看得出,我所有的技術棧基本上找的都是開源社區的比較出名的項目,沒有一個屬于自研的。這樣做的原因:

    •   快速搭建
    •   降低成本
    •   社區支持維護
    •   利于人才引進

      其實可以看出.Net不缺優秀的開源項目,那么實施這么久讓我唯一覺得深刻的印象是:缺少整合。

      之前我也跟不少同行討論過甚至在面試的時候,他們覺得應該自己造一個輪子,原因各種各樣,但唯獨缺少了希望在開源項目基礎上完善下這個原因。我也理解他們的心理,因為“優秀”的工程師應該自己寫一套證明下自己。其實我認為這也許是包容心的在作祟,我們應當求同存異,學會接受已經檢驗過的輪子,在基礎上完善您的需要,有必要還可以給社區做貢獻,雙贏。

    原則

      我做技術選型的時候,堅持著三大原則,簡單、適合、運維優先

      在滿足需求的情況下,優先選擇輕量級的框架,因為輕量級總比重量級的易學習,易于擴展,易于理解源碼。試想一下,有個框架什么都很齊全,但是學習曲線高,在寫一個demo的時候各種踩“坑”找原因,還有可能出了問題不知道怎么解決,除了開始你初認識該框架覺得他很厲害之外,后面使用每走一步都是阻礙和吐槽。

      在有限的資源、人力、時間,我們更新技術的同時還要保證業務的正常開展,我會優先選擇我比較熟悉的技術,我會將他們進行封裝、優化、集成,盡可能的減少開發人員對技術細節的認知負擔,盡可能以他們最熟悉的使用方式提供。此外,我們團隊是有運維崗,如果問題由運維解決更快、更方便則優先交給運維,盡可能讓開發關注數據流轉與業務流程。

      PS:我選型的時候不是一蹴而就的,下文可能我會提到某些框架工具我沒有去選擇原因,并不是否認它們存在的價值,而絕大問題是這些不適用于我們團隊。最后我向偉大的開源項目與其作者致敬。

      

    微服務

     

      有一條盛傳于我們行業的公式:軟件 = 程序 + 軟件工程

      程序就是我們經常產出的算法、數據結構、腳本、框架、架構等。

      為什么稱之為軟件工程?因為這是具有科學方法論引導的、多人協作、有明確目標、有階段性的。從以前瀑布開發再到10年前盛行的敏捷開發最后到最近幾年流行的DevOps,可見開發模式也隨著技術架構更新也不停的演進。我們團隊選用了原型模式+DevOps模式來應對我們的微服務架構的開發。

      書本的教條主義我就不多說了,我對微服務的理解分為服務

      如何微?微到什么程度?我借助兩樣東西,合理的系統架構分層DDD思想,兩者分別管理架構的橫向拆分縱向拆分

      架構分層,我采用了前后端分離+多層架構,自頂向下的依賴,各司其職。

      DDD在最近幾年非常流行,然而這并非新的技術,十幾年前就已經它的出現了。隨著微服務盛行,DDD的劃分域的化繁為簡的思想與微服務的本質-不謀而合,因此DDD也隨之熱門起來。

      下面是我們的架構圖,這個話題在下一篇《.Net微服務實戰之技術架構分層篇》重點再討論。

    服務

      我接下來用一段話總結一下微服務的基本需要。首先,開發人員得知道如何調用服務,那么可以從注冊中心發現已注冊的服務的IP地址、端口的列表,這就是服務的注冊與發現;接著,我們需要知道服務下接口路徑、請求與響應的格式,因此我們需要服務描述。滿足前面兩個條件后,我們就可以進行調用服務了,因此我們需要RPC框架進行服務通信。當服務運作后,因為服務是跨進程調用的,出問題的時候不容易定位,因此我們需要服務跟蹤進行問題定位。最后,服務拆分后是獨立的,因此我們要整合起來統一提供給外部調用,于是API網關作為服務的整合與網絡環境的隔離

      由上述可見組件主要包括以下6點:

    •   API網關
    •   服務描述
    •   服務注冊中心
    •   RPC框架
    •   服務監控
    •   分布式鏈路跟蹤

    API網關

      API網關主要起到了隔離內外網、身份驗證、路由、限流等作用。我用一個生活的例子搭地鐵比喻來描述下:過閘前我們需要經過安檢保證客流的安全性,上下班高峰期還會排隊進行限流,我們還可以通過看指示牌或者詢問工作人員了解到應該往什么方向走,這就是路由。

      我們團隊選型了Kong和KongA作為我們的API網關,Kong是一個在Nginx運行的Lua應用程序,由lua-nginx-module實現。Kong和OpenResty一起打包發行,其中已經包含了lua-nginx-module。基本功能有路由、負載均衡、基本認證、限流、跨域、日志等功能,其他功能例如jwt認證可以通過插件進行擴展。

      有人會問為什么不用Ocelot?回答這個問題之前,我首先聲明我尊敬Ocelot項目與其開發者。

      1.易用性。需要二次開發,雖然對.Net開發者來說能接受,但不利于運維。

      2.性能。社區很多測試數據,據我了解就是kong 11K,Ocelot 3.5K,四舍五入3倍性能差,作為流量的入口,性能這塊我還是比較注重的。

      3.可擴展性,Kong很多功能可以通過插件式按需使用與開發。

     

    服務描述

      我們團隊采用了Swagger,以此來銜接前后端開發的接口對接,省去了編寫接口文檔的成本,此外也支持接口調試,讓開發效率提高不少。我們的服務都是以HTTP協議提供,對外API用RESTful風格,對內統一以POST的RPC風格提供。

    服務注冊中心

      服務注冊,服務在發布后自動把IP地址與端口注冊進服務中心;服務發現,通過調用服務中心的接口獲取到某服務IP地址與端口的列表。我們團隊選用Consul+Consul Tamplate+nginx,Consul是基于GO語言開發的開源工具,主要面向分布式,服務化的系統提供服務注冊、服務發現和配置管理的功能。Consul的核心功能包括:服務注冊/發現、健康檢查、Key/Value存儲、多數據中心和分布式一致性保證等特性。

      Consul作為服務注冊中心的存在,但是我們服務發現只能拿到IP列表,我們使用RPC調用時還是得做負載均衡算法,于是使用了Consul Tamplate把服務列表同步到nginx的配置,那么RPC框架就無需集成負載均衡算法經過nginx路由。

      開始選型我并沒有選擇Consul Tamplate,而是選擇了fabio的這個中間件。fabio是一個應用于Consul的輕量級、零配置負載均衡路由器,開始用的時候部署起來很方便、很簡單。后來上了Skywalking分布式鏈路跟蹤系統,只要經過fabio路由的都無法把調用鏈串起來,雖然將就的用是沒什么問題,但是Skywalking的調用鏈日志無法很好的展示出來就會影響日后的問題排查。我當時花了兩天時間研究與issue提問,并沒有很好的結果,所以最后另外選擇了Consul Tamplate+nginx。

    服務通信

      RPC框架主要三大核心,序列化、通信細節隱藏、代理。協議支持分TCP和HTTP,當然還有兩者兼容+集成MQ的。我們選擇了WebApiClient做客戶端,服務端仍是.Net Core WebAPI,主要考慮到WebAPIClient的輕量、易用,而且和Skywalking、Consul集成方便。我當時用的時候時.Net Core 2.2版本,gRPC并沒有集成進來。

      此外我也選擇過ServiceStack,ServiceStack的技術棧很全,缺點是依賴得很深,當時試用的時候,它所以依賴的一個底層包ServiceStack.Common的某個類與WebAPI沖突了,所以對于不熟悉該框架的我斷定存在依賴污染,無論我需要還是不需要都統統依賴進來了,然而我只是希望要一個簡單的RPC框架。此外還需要破解。

      Surging也作為我當時選型的目標,開始也是我抱著最大希望的,因為描述得很牛逼,什么都是全得。然而深入去用的時候,沒有一個完整的文檔,入門demo也不友好,說實話我駕馭不住只能放棄。

    服務跟蹤

      市面上的分布式鏈路跟蹤系統基本上都是根據谷歌的dapper論文實現的,基本上都分三大塊,UI、收集器、代理(探針),原理大概是把涉及的服務鏈路的RequestID串起來。

      我們團隊選擇了SkyWalking作為了項目的分布式鏈路跟蹤系統,原因很簡單:易用,無侵入,集成良好。

      實施到我們項目的時候我做了點擴展,把Reqeust、Response、Header、異常給記錄了下來,并過濾了部分不需要記錄的路徑。

    分布式事務

      只要在分布式系統,分布式事務必不可缺。

    分布式事務
    分類 理論 案例 中間件
    強一致性 ACID 二階段提交 msdtc
    最終一致性 BASE 本地消息表 CAP

     

     

     

     

      本地消息表是eBay在N年前提出的方案,而CAP以該思想實現的一門框架,原理大概是,本地業務表與消息憑據表作為一個事務持久化,通過各種補償手段保證MQ消息的可靠性,包括MQ正常發布與消費。

      我花了多天的時間專門測試了該框架可靠性,的確有保證。然而有個地方我認為可以優化,Retry的查詢語句條件可以更加嚴謹點,只需要負責相應的Group進行Retry就好,沒必要全部都查詢出來,因為這個問題我在測試環境與本地環境共同調試時,剛好兩個環境的Group不一致,導致會Retry失敗的問題。

    限流與熔斷

      我的架構圖有兩個網關:入站API網關 出站API網關

      限流是針對外部流量的控制,保護了下游服務避免了流量沖擊后雪崩,可以通過入站API網關的限流開關與策略控制。

      熔斷是保護上游服務避免因為下游的異常而且拖垮,更多是針對不可控的第三方依賴,例如微信、支付寶等。可以通過出站API網關的熔斷開關與策略控制。

    框架源碼

      寫到這里,本篇的分享差不多要結束了,我將開源我們公司的工具庫,有需要的朋友可以去使用。

    •   Sikiro.Tookits -公共基礎庫
    •   Sikiro.Nosql.Redis-StackExchange.Redis的基本封裝
    •   Sikiro.Nosql.Mongo-mongodb驅動封裝更新、排序等支持lambda
    •   Sikiro.MicroService.Extension-RPC注冊,微服務框架-服務注冊,終端跟蹤忽略
    •   Sikiro.Chloe.Extension-支持多數據、事務封裝、分頁、IOC
    •   Sikiro.Chloe.Cap-把Chloe,ORM與CAP整合
    •        SkyApm.Diagnostics.AspNetCore|SkyApm.Diagnostics.HttpClient  修改了兩個庫的-XXXXXTracingDiagnosticProcessor的代碼,主要增加request、response、header的記錄。

      額外說明下DotNetCore.CAP.MySql,這個是我從CAP源碼拷貝過來然后改了MySql.Data的依賴,原本CAP.MySql是用的MySqlConnector,和我的Chloe.ORM沖突了。

      開源項目的庫使用:保證包名不修改的前提下,增加版本號引入項目就可以覆蓋。

      

    posted @ 2020-03-25 14:37  陳珙  閱讀(25017)  評論(155編輯  收藏  舉報
    国产美女a做受大片观看