<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          連流量染色都沒有,你說要搞微服務(wù)?

          共 3639字,需瀏覽 8分鐘

           ·

          2022-08-08 20:26

          一、序言


          在當(dāng)下盛行的微服務(wù)架構(gòu)下,服務(wù)數(shù)量多導(dǎo)致的依賴問題經(jīng)常會成為開發(fā)過程中的絆腳石。也經(jīng)常會在各種技術(shù)交流會上聽到類似的話題,大家都在積極的討論這種問題如何去解決。于是決定給大家介紹下流量染色的原理以及能解決微服務(wù)架構(gòu)下開發(fā)過程中的哪些問題。


          二、流量染色的概念


          流量染色說白了就是為對請求的流量打上標簽進行染色,然后這個請求在整個鏈路中都會攜帶這個標簽信息,可以通過標簽進行流量的調(diào)度等功能。


          基于流量染色可以實現(xiàn)很多功能,比如灰度邏輯,藍綠部署,泳道隔離等。


          這里簡單講下流量染色跟微服務(wù)的關(guān)系,免得大家覺得這是一篇標題黨的文章。試想一下,如果是一個單體應(yīng)用,還能有流量染色的應(yīng)用場景嗎?請求的大致流程就是App -> 負載均衡 -> 應(yīng)用,整個鏈路就很簡單,流量染色在這個場景下完全無用武之地。只有在服務(wù)數(shù)量眾多的情況下,一個業(yè)務(wù)功能涉及到N個服務(wù),才需要對流量進行染色控制來解決我們開發(fā),測試等過程中遇到的問題。


          三、基于流量染色的應(yīng)用


          測試環(huán)境多套部署的痛點,只需增量部署


          目前,我們的測試環(huán)境除了經(jīng)常用的T環(huán)境,還有很多MF環(huán)境。而MF環(huán)境基本上是在獨立的需求中會用到,正常的版本迭代都是走T環(huán)境。


          • 問題一:各環(huán)境配置不同


          這樣就會導(dǎo)致一個問題,很多功能是在T環(huán)境進行測試的,當(dāng)有獨立需求需要在MF環(huán)境中測試時,就需要部署對應(yīng)的服務(wù),部署過程中經(jīng)常會碰到各種配置的缺失或者錯誤的情況,導(dǎo)致應(yīng)用無法啟動。


          • 問題二:沒有改動的服務(wù)也要部署


          有一個需求需要在MF環(huán)境測試,服務(wù)也部署好了,聯(lián)調(diào)的時候卻發(fā)現(xiàn)依賴的下游服務(wù)都沒有部署。但這些服務(wù)在這個需求是沒有改動的,依賴的接口也是已經(jīng)上線了的功能。


          如果沒有在對應(yīng)的環(huán)境部署,整個鏈路就無法調(diào)通。所以這個時候又要去找對應(yīng)的下游,讓下游去部署這些服務(wù),下游部署的時候可能也會出現(xiàn)各環(huán)境配置不同的問題,導(dǎo)致整個聯(lián)調(diào)前期的耗時較長,影響項目進度。


          • 流量染色如何解決上述問題?


          比如說當(dāng)前在開發(fā)一個需求,然后會在要改動的應(yīng)用中配置一個版本,這個版本信息會存儲在注冊中心的元數(shù)據(jù)里面。


          然后就去創(chuàng)建一個屬于這個需求的泳道(獨立環(huán)境)進行部署,只需要部署這個需求改動的應(yīng)用即可。這個應(yīng)用依賴的下游應(yīng)用不需要部署,在當(dāng)前環(huán)境找不到對應(yīng)的服務(wù)提供者就去路由到穩(wěn)定環(huán)境,如果穩(wěn)定環(huán)境中也沒有就報錯。



          研發(fā)本地啟動隨意注冊問題


          研發(fā)有的時候會在本地啟動服務(wù),主要是用來調(diào)試某個問題,好處就是能夠快速復(fù)現(xiàn)測試環(huán)境的問題,及時發(fā)現(xiàn)問題代碼。


          由于本地啟動的服務(wù)也會注冊到注冊中心里面,這樣測試環(huán)境的請求就有可能會路由到研發(fā)本地啟動的這個服務(wù)上,研發(fā)本地的這個服務(wù)代碼有可能不是最新的,導(dǎo)致調(diào)用異常。


          這個問題目前常用的解決方案是通過在本地啟動時屏蔽掉服務(wù)的注冊功能,也就是不注冊上去,這樣就不會被正常的測試請求路由到。


          如果有了流量染色的功能,研發(fā)本地啟動服務(wù)的時候指定一個屬于自己的版本號,只要不跟正常測試的版本一致即可。正常測試的請求就不會路由到研發(fā)注冊的這個實例上。


          應(yīng)用級別的灰度


          針對接口級別的灰度,目前都是在應(yīng)用內(nèi)進行灰度控制。但是應(yīng)用級別的,目前沒有特別好的方式來控制灰度。比如有一個技改需求,需要將Redis的Client從Lettuce換成Jedis,這種場景的灰度就是應(yīng)用級別的,目前的做法就是發(fā)布一個節(jié)點,然后結(jié)束發(fā)布流程,具體能被灰度到的量是由服務(wù)實例的總數(shù)量來決定的,沒辦法靈活控制。


          如果有流量染色,可以新發(fā)一個節(jié)點,這個節(jié)點的版本升級一下,比如之前的版本是V1,那么新發(fā)的就是V2版本。首先V1版本肯定是承載生產(chǎn)所有流量的,可以通過網(wǎng)關(guān)進行控制讓流量按某種方式轉(zhuǎn)發(fā)到V2版本,比如用戶白名單,地區(qū),用戶比例等等。有問題也可以隨時將流量切回V1,非常方便。



          服務(wù)的優(yōu)雅下線


          服務(wù)要想無損進行優(yōu)雅下線,還是需要做很多工作的,比如目前發(fā)布時會先將要發(fā)布的服務(wù)從注冊中心注銷掉,但是應(yīng)用內(nèi)部還是會有服務(wù)實例信息的緩存,需要等到一定的時間緩存完成清除后,對應(yīng)的目標實例才不會被請求到。


          如果基于染色去實現(xiàn)的話,將需要下線的實例信息(IP:PORT)通過配置中心推送給網(wǎng)關(guān)進行染色處理,染色信息跟隨著請求貫穿整個鏈路,應(yīng)用內(nèi)的負載均衡組件,MQ等中間件會對要下線的目標實例信息進行過濾,這樣就不會有流量到要下線的實例上去。


          生產(chǎn)環(huán)境發(fā)布提速


          目前,主流的發(fā)布都是滾動部署,滾動發(fā)布的好處是成本低,不用額外增加部署的資源,一個蘿卜一個坑,慢慢替換就是。不好的點在于發(fā)布時間長,全鏈路依賴太嚴重,如果發(fā)布之前依賴關(guān)系錯亂了,那就是一個線上故障。


          要解決這個發(fā)布速度的問題,可以基于流量染色來實現(xiàn)藍綠部署。也就是在發(fā)布的時候重新部署一個V2的版本,這個V2版本的實例數(shù)量跟V1保持一致,由于這個V2版本是沒有流量的,所以不存在依賴關(guān)系,大家可以同時發(fā)布,等到全部發(fā)完之后,就可以通過網(wǎng)關(guān)進行流量分發(fā)了,先分發(fā)一點點流量到V2版本進行驗證,如果沒有問題就可以慢慢放大流量,然后將V1版本的容器釋放掉。


          發(fā)布速度確實提升了,可是問題在于藍綠部署的成本太高了,資源成本要翻倍,雖然發(fā)布后老的資源就回收了,但是你總的資源池還是得容納下這2個版本并行才行。


          那有沒有折中的方式,既能提高發(fā)布效率又能不增加資源成本呢?


          可以在發(fā)布的時候采用替換的形式,先發(fā)布一半的實例,這一半的實例就是我們的V2版本,發(fā)布時是沒有流量的,所以還是可以并行的去發(fā)布。


          發(fā)布完成后,開始放量到V2版本,然后驗證。驗證之后就可以發(fā)布另一半的實例了,這樣的方式總的資源是沒有變化的,但是有一個比較嚴重的問題就是直接停掉了一半的實例,剩下的實例能不能支撐當(dāng)前的流量,因為交易內(nèi)的應(yīng)用都是面向C端用戶的,流量很有可能在短時間內(nèi)達到很高的量。


          全鏈路壓測


          全鏈路壓測對于電商業(yè)務(wù)來說必不可少,每年有N次大促,都需要提前進行壓測來確保大促的穩(wěn)定。其中全鏈路壓測最核心的一點就是流量的區(qū)分,需要區(qū)分流量是正常的用戶請求還是壓測平臺的壓測流量。


          只有區(qū)分了流量,才能將壓測流量進行對應(yīng)的路由,比如數(shù)據(jù)庫,Redis等流量需要路由到影子庫中。基于流量染色就很容易給流量打標,從而區(qū)分流量的類型。


          四、流量染色的實現(xiàn)


          應(yīng)用要有版本的概念


          每個應(yīng)用都需要有版本的概念,其實就跟每次迭代綁定即可。只不過是要將這個版本信息放入項目中的配置文件里面,項目啟動的時候會將這個版本信息跟自身的實例信息一起注冊到注冊中心里面,這些信息一般稱之為元數(shù)據(jù)(Metadata)。


          有了Metadata,在控制流量路由的時候才可以根據(jù)染色的信息進行對應(yīng)的匹配,比如某個請求指定了對訂單的調(diào)用要走V2版本,那么在路由的時候怎么匹配出V2版本的實例信息呢?就需要依賴Metadata。


          染色信息全鏈路透傳


          染色信息全鏈路透傳這個很關(guān)鍵,如果不能全鏈路透傳就沒辦法在所有節(jié)點進行流量的路由控制。這個染色信息的透傳其實跟分布式鏈路跟蹤是一樣的原理。


          目前主流支持分布式鏈路跟蹤的有Skywalking,Jaeger等等,基本上都借鑒了Google Dapper的思想。每次請求都會在入口處生成一個唯一的TraceId,通過這個TraceId就可以將整個鏈路關(guān)聯(lián)起來,這個TraceId就需要在整個鏈路中進行傳遞,流量染色的信息也是一樣需要全鏈路傳遞。


          傳遞的手段一般分為兩種,一種是在獨立的Agent包中進行傳遞,一種是在基礎(chǔ)框架中進行埋點傳遞。如果內(nèi)網(wǎng)之間采用Http進行接口的調(diào)用,那么就在請求頭中將信息進行傳遞。如果是用RPC的方式,則可以用RpcContext進行傳遞。


          信息傳遞到了應(yīng)用中,在這個應(yīng)用中還會繼續(xù)調(diào)用其他下游的接口,這個時候要繼續(xù)透傳,一般都是將信息放入到ThreadLocal中,然后在發(fā)起接口調(diào)用的時候繼續(xù)透傳。這里需要注意的就是用ThreadLocal要防止出現(xiàn)線程池切換的場景,否則ThreadLocal中的信息會丟失。當(dāng)然也有一些手段來解決ThreadLocal異步場景下的信息傳遞問題,比如使用transmittable-thread-local。


          流量路由控制


          當(dāng)流量有了標簽信息,剩下的工作就是要根據(jù)標簽信息將請求路由到正確的實例上。如果內(nèi)部框架是Spring Cloud體系,可以通過Ribbon去控制路由。如果是Dubbo體系,可以通過繼承Dubbo的AbstractRouter重新制定路由邏輯。如果是內(nèi)部自研的RPC框架,肯定留有對應(yīng)的擴展去控制路由。


          五、總結(jié)


          流量染色總體來說還是非常有用的,但這也是一個大的技術(shù)改造。除了在基礎(chǔ)框架層面要打通染色信息的傳遞,更為重要的是各業(yè)務(wù)方的配合,當(dāng)然如果是Agent方式的接入就更好了,不然每個業(yè)務(wù)方還要去升級包,確實有點煩。


          -------------  END  -------------
          掃描下方二維碼,加入技術(shù)群。暗號:加群


          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋麻豆电影 | 中日韩特黄A片免费视频 | 毛片1| 最近中文字幕免费MV第一季歌词十 | 看黄色免费片 |