<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>

          石墨文檔基于K8S的Go微服務(wù)實(shí)踐(上篇)

          共 8975字,需瀏覽 18分鐘

           ·

          2021-09-18 13:24

          1 架構(gòu)演進(jìn)

          互聯(lián)網(wǎng)的WEB架構(gòu)演進(jìn)可以分為三個(gè)階段:單體應(yīng)用時(shí)期、垂直應(yīng)用時(shí)期、微服務(wù)時(shí)期。


          單體應(yīng)用時(shí)期一般處于一個(gè)公司的創(chuàng)業(yè)初期,他的好處就是運(yùn)維簡單、開發(fā)快速、能夠快速適應(yīng)業(yè)務(wù)需求變化。但是當(dāng)業(yè)務(wù)發(fā)展到一定程度后,會發(fā)現(xiàn)許多業(yè)務(wù)會存在一些莫名奇妙的耦合,例如你修改了一個(gè)支付模塊的函數(shù),結(jié)果登錄功能掛了。為了避免這種耦合,會將一些功能模塊做一個(gè)垂直拆分,進(jìn)行業(yè)務(wù)隔離,彼此之間功能相互不影響。但是在業(yè)務(wù)發(fā)展過程中,會發(fā)現(xiàn)垂直應(yīng)用架構(gòu)有許多相同的功能,需要重復(fù)開發(fā)或者復(fù)制粘貼代碼。所以要解決以上復(fù)用功能的問題,我們可以將同一個(gè)業(yè)務(wù)領(lǐng)域內(nèi)功能抽出來作為一個(gè)單獨(dú)的服務(wù),服務(wù)之間使用RPC進(jìn)行遠(yuǎn)程調(diào)用,這就是我們常所說的微服務(wù)架構(gòu)。


          總的來說,我們可以將這三個(gè)階段總結(jié)為以下幾點(diǎn)。單體應(yīng)用架構(gòu)快速、簡單,但耦合性強(qiáng);垂直應(yīng)用架構(gòu)隔離性、穩(wěn)定性好,但復(fù)制粘貼代碼會比較多;微服務(wù)架構(gòu)可以說是兼顧了垂直應(yīng)用架構(gòu)的隔離性、穩(wěn)定性,并且有很強(qiáng)的復(fù)用性能力。可以說微服務(wù)架構(gòu)是公司發(fā)展壯大后,演進(jìn)到某種階段的必然趨勢。


          但微服務(wù)真的那么美好嗎?我們可以看到一個(gè)單體架構(gòu)和微服務(wù)架構(gòu)的對比圖。在左圖我們可以看到一個(gè)業(yè)務(wù)可以通過Nginx+服務(wù)器+數(shù)據(jù)庫就能實(shí)現(xiàn)業(yè)務(wù)需求。但是在右圖微服務(wù)架構(gòu)中,我們完成一個(gè)業(yè)務(wù)需要引入大量的組件,比如在中間這一塊我們會引入DNS、HPA、ConfigMap等、下面部分引入了存儲組件Redis、MySQL、Mongo等。以前單體應(yīng)用時(shí)期我們可能直接上機(jī)器看日志或上機(jī)器上查看資源負(fù)載監(jiān)控,但是到了微服務(wù)階段,應(yīng)用太多了,肯定不能這么去操作,這個(gè)時(shí)候我們就需要引入ELK、Prometheus、Grafana、Jaeger等各種基礎(chǔ)設(shè)施,來更方便地對我們的服務(wù)進(jìn)行觀測。

          微服務(wù)的組件增多、架構(gòu)復(fù)雜,使得我們運(yùn)維變得更加復(fù)雜。對于大廠而言,人多維護(hù)起來肯定沒什么太大問題,可以自建完整的基礎(chǔ)設(shè)施,但對于小廠而言,研發(fā)資源有限,想自建會相當(dāng)困難。


          不過微服務(wù)的基礎(chǔ)設(shè)施維護(hù)困難的問題在 Kubernetes 出現(xiàn)后逐漸出現(xiàn)了轉(zhuǎn)機(jī)。在2014年6月Google開源了Kubernetes后,經(jīng)過這幾年的發(fā)展,已逐漸成為容器編排領(lǐng)域的事實(shí)標(biāo)準(zhǔn)。同時(shí) Kubernetes 已儼然成為云原生時(shí)代的超級操作系統(tǒng),它使得基礎(chǔ)設(shè)施維護(hù)變得異常簡單。


          在傳統(tǒng)模式下,我們不僅需要關(guān)注應(yīng)用開發(fā)階段存在的問題,同時(shí)還需要關(guān)心應(yīng)用的測試、編譯、部署、觀測等問題,例如程序是使用systemd、supervisor啟動(dòng)、還是寫bash腳本啟動(dòng)?日志是如何記錄、如何采集、如何滾動(dòng)?我們?nèi)绾螌Ψ?wù)進(jìn)行觀測?Metrics 指標(biāo)如何采集?采集后的指標(biāo)如何展示?服務(wù)如何實(shí)現(xiàn)健康檢查、存活檢查?服務(wù)如何滾動(dòng)更新?如何對流量進(jìn)行治理,比如實(shí)現(xiàn)金絲雀發(fā)布、流量鏡像?諸如此類的問題。我們業(yè)務(wù)代碼沒寫幾行,全在考慮和權(quán)衡基礎(chǔ)設(shè)施問題。然而使用Kubernetes后,可以發(fā)現(xiàn)大部分問題都已經(jīng)被Kubernetes或周邊的生態(tài)工具解決了,我們僅僅只需要關(guān)心上層的應(yīng)用開發(fā)和維護(hù)Kubernetes集群即可。

          Kubernetes在微服務(wù)中的作用就如同建高樓的地基,做了很多基礎(chǔ)工作,統(tǒng)一了大量的基礎(chǔ)設(shè)施標(biāo)準(zhǔn),以前我們要實(shí)現(xiàn)服務(wù)的啟動(dòng)、配置、日志采集、探活等功能需要寫很多中間件,現(xiàn)在我們只需要寫寫yaml文件,就可以享受這些基礎(chǔ)設(shè)施的能力。運(yùn)維更加簡單這個(gè)也顯而易見,例如在以前出現(xiàn)流量高峰時(shí)研發(fā)提工單后增加副本數(shù),運(yùn)維處理工單,人肉擴(kuò)縮容,現(xiàn)在我們可以根據(jù)實(shí)際應(yīng)用的負(fù)載能力,合理的配置好副本 CPU、Mem 等資源及 HPA 規(guī)則,在流量高峰時(shí)由 Kubernetes 自動(dòng)擴(kuò)容、流量低谷時(shí)自動(dòng)縮容,省去了大量人工操作。


          同時(shí)在框架層面,傳統(tǒng)模式下基礎(chǔ)設(shè)施組件很多都是自研的,基本上沒有太多標(biāo)準(zhǔn)可言,框架需要做各種switch case對這種基礎(chǔ)設(shè)施組件的適配,并且框架經(jīng)常會為因?yàn)榛A(chǔ)設(shè)施的改變,做一些不兼容的升級。現(xiàn)在只需要適配Kubernetes即可,大大簡化微服務(wù)的框架難度和開發(fā)成本。



          2 微服務(wù)的生命周期

          剛才我們講到Kubernetes的優(yōu)勢非常明顯,在這里會描述下我們自己研發(fā)的微服務(wù)框架Ego怎么和Kubernetes結(jié)合起來的一些有趣實(shí)踐。


          我們將微服務(wù)的生命周期分為以下6個(gè)階段:開發(fā)、測試、部署、啟動(dòng)、調(diào)用、治理。

          2.1 開發(fā)階段

          在開發(fā)階段我們最關(guān)注三個(gè)問題。如何配置、如何對接,如何調(diào)試。


          2.1.1 配置驅(qū)動(dòng)

          大家在使用開源組件的時(shí)候,其實(shí)會發(fā)現(xiàn)每個(gè)開源組件的配置、調(diào)用方式、debug方式、記錄日志方式都不一樣,導(dǎo)致我們需要不停去查看組件的示例、文檔、源碼,才能使用好這個(gè)組件。我們只想開發(fā)一個(gè)功能,卻需要關(guān)心這么多底層實(shí)現(xiàn)細(xì)節(jié),這對我們而言是一個(gè)很大的心智負(fù)擔(dān)。


          所以我們將配置、調(diào)用方式做了統(tǒng)一。可以看到上圖我們所有組件的地址都叫addr,然后在下圖中我們調(diào)用redis、gRPC、MySQL的時(shí)候,只需基于組件的配置Key path去 Load 對應(yīng)的組件配置,通過build方法就可以構(gòu)造一個(gè)組件實(shí)例。可以看到調(diào)用方式完全相同,就算你不懂這個(gè)組件,你只要初始化好了,就可以根據(jù)編輯器代碼提示,調(diào)用這個(gè)組件里的API,大大簡化我們的開發(fā)流程。


          2.1.2  配置補(bǔ)齊

          配置補(bǔ)齊這個(gè)功能,是源于我們在最開始使用一些組件庫的時(shí)候,很容易遺漏配置,例如使用gRPC的客戶端,未設(shè)置連接錯(cuò)誤、導(dǎo)致我們在阻塞模式下連接不上的時(shí)候,沒有報(bào)正確的錯(cuò)誤提示;或者在使用Redis、MySQL沒有超時(shí)配置,導(dǎo)致線上的調(diào)用出現(xiàn)問題,產(chǎn)生雪崩效應(yīng)。這些都是因?yàn)槲覀儗M件的不熟悉,才會遺漏配置。框架要做的是在用戶不配置的情況下,默認(rèn)補(bǔ)齊這些配置,并給出一個(gè)最佳實(shí)踐配置,讓業(yè)務(wù)方的服務(wù)更加穩(wěn)定、高效。

          2.1.3 配置工具

          我們編寫完配置后,需要將配置發(fā)布到測試環(huán)境,我們將配置中心IDE化,能夠非常方便的編寫配置,通過鼠標(biāo)右鍵,就可以插入資源引用,鼠標(biāo)懸停可以看到對應(yīng)的配置信息。通過配置中心,使我們在對比配置版本,發(fā)布,回滾,可以更加方便。

          2.1.4 對接-Proto管理

          我們內(nèi)部系統(tǒng)全部統(tǒng)一采用gRPC協(xié)議和protobuf編解碼。統(tǒng)一的好處在于不需要在做任何協(xié)議、編解碼轉(zhuǎn)換,這樣就可以使我們所有業(yè)務(wù)采用同一個(gè)protobuf倉庫,基于 CI/CD 工具實(shí)現(xiàn)許多自動(dòng)化功能。


          我們要求所有服務(wù)提供者提前在獨(dú)立的路徑下定義好接口和錯(cuò)誤碼的protobuf文件,然后提交到GitLab,我們通過GitLab CI的check階段對變更的protobuf文件做format、lint、breaking 檢查。然后在build階段,會基于 protobuf 文件中的注釋自動(dòng)產(chǎn)生文檔,并推送至內(nèi)部的微服務(wù)管理系統(tǒng)接口平臺中,還會根據(jù)protobuf文件自動(dòng)構(gòu)建  Go/PHP/Node/Java 等多種語言的樁代碼和錯(cuò)誤碼,并推送到指定對應(yīng)的中心化倉庫。

          推送到倉庫后,我們就可以通過各語言的包管理工具拉取客戶端、服務(wù)端的gRPC和錯(cuò)誤碼的依賴,不需要口頭約定對接數(shù)據(jù)的定義,也不需要通過 IM 工具傳遞對接數(shù)據(jù)的定義文件,極大的簡化了對接成本。


          2.1.5 對接-錯(cuò)誤碼管理

          有了以上比較好的protobuf生成流程后,我們可以進(jìn)一步簡化業(yè)務(wù)錯(cuò)誤狀態(tài)碼的對接工作。而我們采用了以下方式:

          • Generate:

            • 編寫protobuf error的插件,生成我們想要的error代碼

            • 根據(jù)go官方要求,實(shí)現(xiàn)errors的interface,他的好處在于可以區(qū)分是我們自定義的error類型,方便斷言。

            • 根據(jù)注解的code信,在錯(cuò)誤碼中生成對應(yīng)的grpc status code,業(yè)務(wù)方使用的時(shí)候少寫一行代碼

            • 確保錯(cuò)誤碼唯一,后續(xù)在API層響應(yīng)用戶數(shù)據(jù)確保唯一錯(cuò)誤碼,例如: 下單失敗(xxx)

            • errors里設(shè)置with message,with metadata,攜帶更多的錯(cuò)誤信息

          • Check:

            • gRPC的error可以理解為遠(yuǎn)程error,他是在另一個(gè)服務(wù)返回的,所以每次error在客戶端是反序列化,new出來的。是無法通過errors.Is判斷其根因。

            • 我們通過工具將gRPC的錯(cuò)誤碼注冊到一起,然后客戶端通過FromError方法,從注冊的錯(cuò)誤碼中,根據(jù)Reason的唯一性,取出對應(yīng)的錯(cuò)誤碼,這個(gè)時(shí)候我們可以使用errors.Is來判斷根因。

            • 最后做到errors.Is的判斷: errors.Is(eerrors.FromError(err), UserErrNotFound())


          2.1.6 對接-調(diào)試

          對接中調(diào)試的第一步是閱讀文檔,我們之前通過protobuf的ci工具里的lint,可以強(qiáng)制讓我們寫好注釋,這可以幫助我們生成非常詳細(xì)的文檔。


          基于 gRPC Reflection 方法,服務(wù)端獲得了暴露自身已注冊的元數(shù)據(jù)能力,第三方可以通過 Reflection 接口獲取服務(wù)端的 Service、Message 定義等數(shù)據(jù)。結(jié)合 Kubernetes API,用戶選擇集群、應(yīng)用、Pod 后,可直接在線進(jìn)行g(shù)RPC接口測試。同時(shí)我們可以對測試用例進(jìn)行存檔,方便其他人來調(diào)試該接口。


          2.1.7 Debug-調(diào)試信息

          我們大部分的時(shí)候都是對接各種組件API,如果我們能夠展示各種組件例如gRPC、HTTP、MySQL、Redis、Kafka的調(diào)試信息,我們就能夠快速的debug。在這里我們定義了一種規(guī)范,我們將配置名、請求URL、請求參數(shù)、響應(yīng)數(shù)據(jù)、耗時(shí)時(shí)間、執(zhí)行行號稱為Debug的六元組信息。


          將這個(gè)Debug的六元組信息打印出來,如下圖所示。我們就可以看到我們的響應(yīng)情況,數(shù)據(jù)結(jié)構(gòu)是否正確,是否有錯(cuò)誤。


          2.1.8 Debug-定位錯(cuò)誤

          Debug里面有個(gè)最重要的一點(diǎn)能夠快速定位錯(cuò)誤問題,所以我們在實(shí)踐的過程中,會遵循Fail Fast理念。將框架中影響功能的核心錯(cuò)誤全部設(shè)置為panic,讓程序盡快的報(bào)錯(cuò),并且將錯(cuò)誤做好高亮,在錯(cuò)誤信息里顯示Panic的錯(cuò)誤碼,組件、配置名、錯(cuò)誤信息,盡快定位錯(cuò)誤根因。這個(gè)圖里面就是我們的錯(cuò)誤示例,他會高亮的顯示出來,你的配置可能不存在,這個(gè)時(shí)候業(yè)務(wù)方在配置文件中需要找到server.grpc這個(gè)配置,設(shè)置一下即可。


          2.2 測試階段

          2.2.1 測試類型

          開發(fā)完成后,我們會進(jìn)入到測試階段。我們測試可以分為四種方式:單元測試、接口測試、性能測試、集成測試。

          我們會通過docker-compose跑本地的一些單元測試,使用GitLab CI跑提交代碼的單元測試。我們接口測試則使用上文所述接口平臺里的測試用例集。性能測試主要是分兩種,一類是benchmark使用GitLab ci。另一類是全鏈路壓測就使用平臺工具。集成測試目前還做的不夠好,之前是用GitLab ci去拉取鏡像,通過 dind(Docker in Docker)跑整個(gè)流程,但之前我們沒有拓?fù)鋱D,所以需要人肉配置yaml,非常繁瑣,目前我們正在結(jié)合配置中心的依賴拓?fù)鋱D,準(zhǔn)備用jekins完成集成測試。


          在這里我主要介紹下單元測試。


          2.2.2 工具生成測試用例

          單元測試優(yōu)勢大家都應(yīng)該很清楚,能夠通過單測代碼保證代碼質(zhì)量。但單測缺點(diǎn)其實(shí)也非常明顯,如果每個(gè)地方都寫單測,會消耗大家大量的精力。


          所以我們首先定義了一個(gè)規(guī)范,業(yè)務(wù)代碼里面不要出現(xiàn)基礎(chǔ)組件代碼,所有組件代碼下層到框架里做單元測試。業(yè)務(wù)代碼里只允許有CRUD的業(yè)務(wù)邏輯,可以大大簡化我們的測試用例數(shù)量。同時(shí)我們的業(yè)務(wù)代碼做好gRPC,HTTP服務(wù)接口級別的單元測試,可以更加簡單、高效。


          然后我們可以通過開發(fā)protobuf工具的插件,拿到gRPC服務(wù)的描述信息,通過他結(jié)合我們的框架,使用指令自動(dòng)生成測試代碼用例。在這里我們框架使用了gRPC中的測試bufconn構(gòu)造一個(gè)listener,這樣就可以在測試中不關(guān)心gRPC服務(wù)的ip port。

          以下是我們通過工具生成的單元測試代碼,我們業(yè)務(wù)人員只需要在紅框內(nèi)填寫好對應(yīng)的斷言內(nèi)容,就可以完成一個(gè)借口的單測。


          2.2.3 簡單高效做單元測試

          目前單元測試大部分的玩法,都是在做解除依賴,例如以下的一些方式

          • 面向接口編程

          • 依賴注入、控制反轉(zhuǎn)

          • 使用Mock

          不可否認(rèn),以上的方法確實(shí)可以使代碼變得更加優(yōu)雅,更加方便測試。但是實(shí)現(xiàn)了以上的代碼,會讓我們的代碼變得更加復(fù)雜、增加更多的開發(fā)工作量,下班更晚。如果我們不方便解除依賴,我們是否可以讓基礎(chǔ)設(shè)施將所有依賴構(gòu)建起來。基礎(chǔ)設(shè)施能做的事情,就不要讓研發(fā)用代碼去實(shí)現(xiàn)。


          以下舉我們一個(gè)實(shí)際場景的MySQL單元測試?yán)印N覀兛梢酝ㄟ^docker-compose.yml,構(gòu)建一個(gè)mysql。然后通過Ego的應(yīng)用執(zhí)行job。

          • 創(chuàng)建數(shù)據(jù)庫的表./app --job=install

          • 初始化數(shù)據(jù)庫表中的數(shù)據(jù) ./app --job=intialize

          • 執(zhí)行g(shù)o test ./...

          可以看到我們可以每次都在干凈的環(huán)境里,構(gòu)建起服務(wù)的依賴項(xiàng)目,跑完全部的測試用例。詳細(xì)example請看https://github.com/gotomicro/go-engineering


          2.3 部署階段

          2.3.1 注入信息

          編譯是微服務(wù)的重要環(huán)節(jié)。我們可以在編譯階段通過-ldflags指令注入必要的信息,例如應(yīng)用名稱、應(yīng)用版本號、框架版本號、編譯機(jī)器 Host Name、編譯時(shí)間。該編譯腳本可以參考https://github.com/gotomicro/ego/blob/master/scripts/build/gobuild.sh

          go build -o bin/hello -ldflags -X "github.com/gotomicro/ego/core/eapp.appName=hello -X github.com/gotomicro/ego/core/eapp.buildVersion=cbf03b73304d7349d3d681d3abd42a90b8ba72b0-dirty -X github.com/gotomicro/ego/core/eapp.buildAppVersion=cbf03b73304d7349d3d681d3abd42a90b8ba72b0-dirty -X github.com/gotomicro/ego/core/eapp.buildStatus=Modified -X github.com/gotomicro/ego/core/eapp.buildTag=v0.6.3-2-gcbf03b7 -X github.com/gotomicro/ego/core/eapp.buildUser=`whoami` -X github.com/gotomicro/ego/core/eapp.buildHost=`hostname -f` -X github.com/gotomicro/ego/core/eapp.buildTime=`date +%Y-%m-%d--%T`"

          通過該方式注入后,編譯完成后,我們可以使用./hello --version ,查看該服務(wù)的基本情況,如下圖所示。


          2.3.2 版本信息

          微服務(wù)還有一個(gè)比較重要的就是能夠知道你的應(yīng)用當(dāng)前線上跑的是哪個(gè)框架版本。我們在程序運(yùn)行時(shí),使用go里面的debug包,讀取到依賴版本信息,匹配到我們的框架,得到這個(gè)版本。

          然后我們就可以在prometheus中或者二進(jìn)制中看到我們框架的版本,如果框架某個(gè)版本真有什么大bug,可以查詢線上運(yùn)行版本,然后找到對應(yīng)的應(yīng)用,讓他們升級。


          2.3.3 發(fā)布版本

          發(fā)布配置版本,我們在沒有Kubernetes的時(shí)候,不得不做個(gè)agent,從遠(yuǎn)端ETCD讀取配置,然后將文件放入到物理機(jī)里,非常的繁瑣。而使用Kubernetes發(fā)布配置,就會非常簡單。我們會在數(shù)據(jù)庫記錄配置版本信息,然后調(diào)用Kubernetes API,將配置寫入到config map里,然后再將配置掛載到應(yīng)用里。


          發(fā)布微服務(wù)應(yīng)用版本,因?yàn)橛辛薑ubernetes就更加簡單,我們只需要發(fā)布系統(tǒng)調(diào)用一下deployment.yml就能實(shí)現(xiàn),應(yīng)用的拉取鏡像、啟動(dòng)服務(wù)、探活、滾動(dòng)更新等功能。


          2.4 啟動(dòng)階段

          2.4.1 啟動(dòng)參數(shù)

          EGO內(nèi)置很多環(huán)境變量,這樣可以很方便的通過基礎(chǔ)設(shè)施將公司內(nèi)部規(guī)范的一些數(shù)據(jù)預(yù)設(shè)在Kubernetes環(huán)境變量內(nèi),業(yè)務(wù)方就可以簡化很多啟動(dòng)參數(shù),在dockerfile里啟動(dòng)項(xiàng)變?yōu)榉浅:唵蔚拿钚校?/span>CMD ["sh", "-c", "./${APP}"]


          2.4.2 加載配置

          我們通過Kubernetes configmap掛載到應(yīng)用pod,通過框架watch該配置。在這里要提醒一點(diǎn),Kubernetes的配置是軟鏈模式,框架要想要監(jiān)聽該配置,必須使用filepath.EvalSymlinks(fp.path)計(jì)算出真正的路徑。然后我們就可以通過配置中心更改配置,通過configmap傳遞到我們的框架內(nèi)部,實(shí)現(xiàn)配置的實(shí)時(shí)更新。

          2.4.3 探活

          探活的概念:

          • livenessProbe:如果檢查失敗,將殺死容器,根據(jù)Pod的restartPolicy來操作

          • readinessProbe:如果檢查失敗,Kubernetes會把Pod從service endpoints中剔除

          轉(zhuǎn)換成我們常見的研發(fā)人話就是,liveness通常是你服務(wù)panic了,進(jìn)程沒了,檢測ip port不存在了,這個(gè)時(shí)候Kubernetes會殺掉你的容器。而readinessProbe則是你服務(wù)可能因?yàn)樨?fù)載問題不響應(yīng)了,但是ip port還是可以連上的,這個(gè)時(shí)候Kubernetes會將你從service endpoints中剔除。


          所以我們liveness Probe設(shè)置一個(gè)tcp檢測 ip port即可,readness我們需要根據(jù)HTTP,gRPC設(shè)置不同的探活策略。

          當(dāng)我們確保服務(wù)接口是readness,這個(gè)時(shí)候流量就會導(dǎo)入進(jìn)來。然后在結(jié)合我們的滾動(dòng)更新,我們服務(wù)可以很優(yōu)雅的啟動(dòng)起來。(liveness、readness必須同時(shí)設(shè)置,而且策略必須有差異,否則會帶來一些問題)


          2.5 調(diào)用階段

          我們在使用Kubernetes的時(shí)候,初期也使用最簡單的dns服務(wù)發(fā)現(xiàn),他的好處就是簡單方便,gRPC中直接內(nèi)置。但是在實(shí)際的使用過程中,發(fā)現(xiàn)gRPC DNS Resolver還是存在一些問題。


          gRPC DNS Resolver使用了rn的channel傳遞事件。當(dāng)客戶端發(fā)現(xiàn)連接有異常,都會執(zhí)行ResolveNow,觸發(fā)客戶端更新服務(wù)端副本的列表。但是當(dāng)K8S增加服務(wù)端副本時(shí),客戶端連接是無法及時(shí)感知的。

          因?yàn)間RPC DNS Resolver存在的問題,我們自己實(shí)現(xiàn)了Kubernetes API Resolver。我們根據(jù)Kubernetes的API,watch服務(wù)的endpoints方式,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)。

          我們再來梳理下微服務(wù)在Kubernetes的注冊與發(fā)現(xiàn)的流程,首先我們服務(wù)啟動(dòng)后,探針會通過ip port檢測我們的端口查看我們是否是活的,如果是活的就說明我們的pod已經(jīng)跑起來了,然后會通過探針訪問我們gRPC服務(wù)的health接口,如果是可用的,這個(gè)時(shí)候Kubernetes會將我們這個(gè)服務(wù)的pod ip注冊到service endpoints,流量就會隨之導(dǎo)入進(jìn)來。然后我們的客戶端會通過Kubernetes API Watch到service endpoints的節(jié)點(diǎn)變化,然后將該節(jié)點(diǎn)添加到它自己的服務(wù)列表里,然后它就可以通過Balancer調(diào)用服務(wù)節(jié)點(diǎn),完成RPC調(diào)用。


          由于篇幅較多,以上介紹了微服務(wù)生命周期的一部分,下期我們在介紹微服務(wù)治理中的監(jiān)控、日志、鏈路、限流熔斷、報(bào)警、微服務(wù)管理等內(nèi)容。以下是ego架構(gòu)圖和研發(fā)生命周期的全景圖。



          3 資料鏈接

          • Ego框架:https://github.com/gotomicro/ego

          • 文檔:https://ego.gocn.vip

          • PPT:https://github.com/gopherchina/meetup/blob/master/XiAn/20210911/%E7%9F%B3%E5%A2%A8%E6%96%87%E6%A1%A3Go%E5%9C%A8K8S%E4%B8%8A%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%AE%9E%E8%B7%B5-%E5%BD%AD%E5%8F%8B%E9%A1%BA.pdf

          • 編譯:https://ego.gocn.vip/micro/chapter1/build.html

          • 鏈路:https://ego.gocn.vip/micro/chapter2/trace.html

          • 限流:https://ego.gocn.vip/frame/client/sentinel.html

          • 日志:https://ego.gocn.vip/frame/core/logger.html

          • docker-compose單元測試,protobuf統(tǒng)一錯(cuò)誤碼:https://github.com/gotomicro/go-engineering

          • proto錯(cuò)誤碼插件:https://github.com/gotomicro/ego/tree/master/cmd/protoc-gen-go-errors

          • proto單元測試插件:https://github.com/gotomicro/ego/tree/master/cmd/protoc-gen-go-test


            GoCN實(shí)戰(zhàn)群

            瀏覽 68
            點(diǎn)贊
            評論
            收藏
            分享

            手機(jī)掃一掃分享

            分享
            舉報(bào)
            評論
            圖片
            表情
            推薦
            點(diǎn)贊
            評論
            收藏
            分享

            手機(jī)掃一掃分享

            分享
            舉報(bào)
            <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>
                    狠狠亚洲天堂 | 骚逼免费看 | 亚洲色婷婷天天看 | 亚洲最大的成人 | 人人舔人人爽 |