欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程

 更新時(shí)間:2023年01月26日 12:15:47   作者:春少  
這篇文章主要為大家介紹了go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前話

polaris-server 作為PolarisMesh的控制面,該進(jìn)程主要負(fù)責(zé)服務(wù)數(shù)據(jù)、配置數(shù)據(jù)、治理規(guī)則的管理以及下發(fā)至北極星SDK以及實(shí)現(xiàn)了xDS的客戶端。

polaris-server 是如何同時(shí)對(duì)外提供服務(wù)注冊(cè)發(fā)現(xiàn)、配置管理、服務(wù)治理的功能呢?又是如何同時(shí)支持北極星基于gRPC的私有協(xié)議、兼容eureka協(xié)議以及xDS協(xié)議呢?帶著這些疑問,我們來探究看下polaris-server的啟動(dòng)流程,看看北極星是實(shí)現(xiàn)的。

前期準(zhǔn)備

  • golang 環(huán)境,需要1.17.x +
  • 準(zhǔn)備 vscode 或者 goland
  • 從github中clone一份polaris-server的源碼,這里推薦從release-vx.y.z分支中選擇一個(gè)分支進(jìn)行學(xué)習(xí),以下文章將基于release-v1.12.0分支進(jìn)行研究

正題

polaris-server.yaml 認(rèn)識(shí)

# server啟動(dòng)引導(dǎo)配置
bootstrap:
  # 全局日志
  logger:
    ${日志scope名稱,主要支持 config/auth/store/naming/cache/xdsv3/default}:
      rotateOutputPath: ${日志文件位置}
      errorRotateOutputPath: ${專門記錄error級(jí)別的錯(cuò)誤日志文件}
      rotationMaxSize: ${單個(gè)日志文件大小最大值, 默認(rèn) 100, 單位為 mb}
      rotationMaxBackups: ${最大保存多少個(gè)日志文件, 默認(rèn) 10}
      rotationMaxAge: ${單個(gè)日志文件最大保存天數(shù), 默認(rèn) 7}
      outputLevel: ${日志輸出級(jí)別,debug/info/warn/error}
  # 按順序啟動(dòng)server
  startInOrder:
    open: true # 是否開啟,默認(rèn)是關(guān)閉
    key: sz # 全局鎖,鎖的名稱,根據(jù)鎖名稱進(jìn)行互斥啟動(dòng)
  # 注冊(cè)為北極星服務(wù)
  polaris_service:
    probe_address: ${北極星探測(cè)地址,用于獲取當(dāng)前北極星server自身對(duì)外的IP, 默認(rèn)為 ##DB_ADDR##}
    enable_register: ${是否允許當(dāng)前北極星進(jìn)程進(jìn)行自注冊(cè),即將自身的系統(tǒng)級(jí)服務(wù)注冊(cè)通過北極星的服務(wù)注冊(cè)能力進(jìn)行注冊(cè),默認(rèn)為 true}
    isolated: ${注冊(cè)的實(shí)例是否需要處理隔離狀態(tài),默認(rèn)為 false}
    services:
      - name: polaris.checker # 北極星健康檢查需要的系統(tǒng)級(jí)服務(wù),根據(jù)該服務(wù)下的實(shí)例,進(jìn)行健康檢查任務(wù)的 hash 責(zé)任劃分
        protocols: # 注冊(cè)的實(shí)例需要暴露的協(xié)議,即注冊(cè)端口號(hào)
          - service-grpc
# apiserver,北極星對(duì)外協(xié)議實(shí)現(xiàn)層
apiservers:
  - name: service-eureka # 北極星支持 eureka 協(xié)議的協(xié)議層插件
    option:
      listenIP: "0.0.0.0"          # tcp server 的監(jiān)聽 ip
      listenPort: 8761             # tcp server 的監(jiān)聽端口
      namespace: default           # 設(shè)置 eureka 服務(wù)默認(rèn)歸屬的北極星命名空間
      refreshInterval: 10          # 定期從北極星的cache模塊中拉取數(shù)據(jù),刷新 eureka 協(xié)議中的數(shù)據(jù)緩存
      deltaExpireInterval: 60      # 增量緩存過期周期
      unhealthyExpireInterval: 180 # 不健康實(shí)例過期周期
      connLimit:                   # 鏈接限制配置
        openConnLimit: false       # 是否開啟鏈接限制功能,默認(rèn) false
        maxConnPerHost: 1024       # 每個(gè)IP最多的連接數(shù)
        maxConnLimit: 10240        # 當(dāng)前l(fā)istener最大的連接數(shù)限制
        whiteList: 127.0.0.1       # 該 apiserver 的白名單 IP 列表,英文逗號(hào)分隔
        purgeCounterInterval: 10s  # 清理鏈接行為的周期
        purgeCounterExpired: 5s    # 清理多久不活躍的鏈接
  - name: api-http                 # 北極星自身 OpenAPI 協(xié)議層
    option:
      listenIP: "0.0.0.0"          # tcp server 的監(jiān)聽 ip
      listenPort: 8090             # tcp server 的監(jiān)聽端口
      enablePprof: true            # 是否開啟 golang 的 debug/pprof 的數(shù)據(jù)采集
      enableSwagger: true          # 是否開啟 swagger OpenAPI doc 文檔數(shù)據(jù)生成
    api:                           # 設(shè)置允許開放的 api 接口類型
      admin:                       # 運(yùn)維管理 OpenAPI 接口
        enable: true
      console:                     # 北極星控制臺(tái) OpenAPI 接口
        enable: true
        include: [default]         # 需要暴露的 OpenAPI 分組
      client:                      # 北極星客戶端相關(guān) OpenAPI 接口
        enable: true
        include: [discover, register, healthcheck]
      config:                      # 北極星配置中心相關(guān) OpenAPI 接口
        enable: true
        include: [default]
  - name: service-grpc             # 北極星基于 gRPC 協(xié)議的客戶端通信協(xié)議層,用于注冊(cè)發(fā)現(xiàn)、服務(wù)治理
    option:
      listenIP: "0.0.0.0"
      listenPort: 8091
      enableCacheProto: true       # 是否開啟 protobuf 解析緩存,對(duì)于內(nèi)容一樣的protobuf減少序列化
      sizeCacheProto: 128          # protobuf 緩存大小
      tls:                         # 協(xié)議層支持 tls 的配置
        certFile: ""
        keyFile: ""
        trustedCAFile: ""
    api:
      client:
        enable: true
        include: [discover, register, healthcheck]
  - name: config-grpc              # 北極星基于 gRPC 協(xié)議的客戶端通信協(xié)議層,用于配置中心
    option:
      listenIP: "0.0.0.0"
      listenPort: 8093
      connLimit:
        openConnLimit: false
        maxConnPerHost: 128
        maxConnLimit: 5120
    api:
      client:
        enable: true
  - name: xds-v3                   # 北極星實(shí)現(xiàn)的 xDSv3 協(xié)議層
    option:
      listenIP: "0.0.0.0"
      listenPort: 15010
      connLimit:
        openConnLimit: false
        maxConnPerHost: 128
        maxConnLimit: 10240
# 核心邏輯的配置
auth:
  # 鑒權(quán)插件
  name: defaultAuth
  option:
    # token 加密的 salt,鑒權(quán)解析 token 時(shí)需要依靠這個(gè) salt 去解密 token 的信息
    # salt 的長(zhǎng)度需要滿足以下任意一個(gè):len(salt) in [16, 24, 32]
    salt: polarismesh@2021
    # 控制臺(tái)鑒權(quán)能力開關(guān),默認(rèn)開啟
    consoleOpen: true
    # 客戶端鑒權(quán)能力開關(guān), 默認(rèn)關(guān)閉
    clientOpen: false
namespace:
  # 是否允許自動(dòng)創(chuàng)建命名空間
  autoCreate: true
naming:
  auth:
    open: false
  # 批量控制器
  batch:
    ${批量控制器配置,支持 register/deregister/clientRegister/clientDeregister}:
      open: true                 # 是否開啟該批量控制器
      queueSize: 10240           # 暫存任務(wù)數(shù)量
      waitTime: 32ms             # 任務(wù)未滿單次 Batch 數(shù)量的最大等待時(shí)間,時(shí)間到直接強(qiáng)制發(fā)起 Batch 操作
      maxBatchCount: 128         # 單次 Batch 數(shù)量
      concurrency: 128           # 處于批任務(wù)的 worker 協(xié)程數(shù)量
      dropExpireTask: true       # 是否開啟丟棄過期任務(wù),僅用于 register 類型的批量控制器
      taskLife: 30s              # 任務(wù)最大有效期,超過有效期則任務(wù)不執(zhí)行,僅用于 register 類型的批量控制器
# 健康檢查的配置
healthcheck:
  open: true                     # 是否開啟健康檢查功能模塊
  service: polaris.checker       # 參與健康檢查任務(wù)的實(shí)例所在的服務(wù)
  slotNum: 30                    # 時(shí)間輪參數(shù)
  minCheckInterval: 1s           # 用于調(diào)整實(shí)例健康檢查任務(wù)在時(shí)間輪內(nèi)的下一次執(zhí)行時(shí)間,限制最小檢查周期
  maxCheckInterval: 30s          # 用于調(diào)整實(shí)例健康檢查任務(wù)在時(shí)間輪內(nèi)的下一次執(zhí)行時(shí)間,限制最大檢查周期
  clientReportInterval: 120s     # 用于調(diào)整SDK上報(bào)實(shí)例健康檢查任務(wù)在時(shí)間輪內(nèi)的下一次執(zhí)行時(shí)間
  batch:                         # 健康檢查數(shù)據(jù)的批量寫控制器
    heartbeat:
      open: true
      queueSize: 10240
      waitTime: 32ms
      maxBatchCount: 32
      concurrency: 64
  checkers:                      # 健康檢查啟用插件列表,當(dāng)前支持 heartbeatMemory/heartbeatRedis,由于二者屬于同一類型健康檢查插件,因此只能啟用一個(gè)
    - name: heartbeatMemory      # 基于本機(jī)內(nèi)存實(shí)現(xiàn)的健康檢查插件,僅適用于單機(jī)版本
    - name: heartbeatRedis       # 基于 redis 實(shí)現(xiàn)的健康檢查插件,適用于單機(jī)版本以及集群版本
      option:
        kvAddr: ##REDIS_ADDR##   # redis 地址,IP:PORT 格式
        # ACL user from redis v6.0, remove it if ACL is not available
        kvUser: ##REDIS_USER#    # 如果redis版本低于6.0,請(qǐng)直接移除該配置項(xiàng)
        kvPasswd: ##REDIS_PWD##  # redis 密碼
        poolSize: 200            # redis 鏈接池大小
        minIdleConns: 30         # 最小空閑鏈接數(shù)量
        idleTimeout: 120s        # 認(rèn)為空閑鏈接的時(shí)間
        connectTimeout: 200ms    # 鏈接超時(shí)時(shí)間
        msgTimeout: 200ms        # redis的讀寫操作超時(shí)時(shí)間
        concurrency: 200         # 操作redis的worker協(xié)程數(shù)量
        withTLS: false
# 配置中心模塊啟動(dòng)配置
config:
  # 是否啟動(dòng)配置模塊
  open: true
  cache:
    #配置文件緩存過期時(shí)間,單位s
    expireTimeAfterWrite: 3600
# 緩存配置
cache:
  open: true
  resources:
    - name: service # 加載服務(wù)數(shù)據(jù)
      option:
        disableBusiness: false # 不加載業(yè)務(wù)服務(wù)
        needMeta: true # 加載服務(wù)元數(shù)據(jù)
    - name: instance # 加載實(shí)例數(shù)據(jù)
      option:
        disableBusiness: false # 不加載業(yè)務(wù)服務(wù)實(shí)例
        needMeta: true # 加載實(shí)例元數(shù)據(jù)
    - name: routingConfig # 加載路由數(shù)據(jù)
    - name: rateLimitConfig # 加載限流數(shù)據(jù)
    - name: circuitBreakerConfig # 加載熔斷數(shù)據(jù)
    - name: users # 加載用戶、用戶組數(shù)據(jù)
    - name: strategyRule # 加載鑒權(quán)規(guī)則數(shù)據(jù)
    - name: namespace # 加載命名空間數(shù)據(jù)
    - name: client # 加載 SDK 數(shù)據(jù)
# 存儲(chǔ)配置
store:
  # 單機(jī)文件存儲(chǔ)插件
  name: boltdbStore
  option:
    path: ./polaris.bolt
  ## 數(shù)據(jù)庫存儲(chǔ)插件
  # name: defaultStore
  # option:
  #   master:                                     # 主庫配置, 如果要配置 slave 的話,就把 master 替換為 slave 即可
  #     dbType: mysql                             # 數(shù)據(jù)庫存儲(chǔ)類型
  #     dbName: polaris_server                    # schema 名稱
  #     dbUser: ##DB_USER##                       # 數(shù)據(jù)庫用戶
  #     dbPwd: ##DB_PWD##                         # 數(shù)據(jù)庫用戶密碼
  #     dbAddr: ##DB_ADDR##                       # 數(shù)據(jù)庫連接地址,HOST:PORT 格式
  #     maxOpenConns: 300                         # 最大數(shù)據(jù)庫連接數(shù)
  #     maxIdleConns: 50                          # 最大空閑數(shù)據(jù)庫連接數(shù)
  #     connMaxLifetime: 300 # 單位秒              # 連接的最大存活時(shí)間,超過改時(shí)間空閑連接將會(huì)唄釋放
  #     txIsolationLevel: 2 #LevelReadCommitted
# 插件配置
plugin: # 本次暫不涉及,后續(xù)文章在詳細(xì)說明

源碼組織

我們先來看下,北極星服務(wù)端源碼的組織形式

?  polaris-server git:(release-v1.12.0) tree -L 1
.
├── apiserver                  # 北極星對(duì)外協(xié)議實(shí)現(xiàn)層
├── auth                       # 北極星的資源鑒權(quán)層
├── bootstrap                  # 負(fù)責(zé)將北極星各個(gè)功能模塊初始化、逐個(gè)啟動(dòng)
├── cache                      # 北極星的資源緩存層,對(duì)于弱一致性讀接口進(jìn)行加速
├── cmd                        # 簡(jiǎn)單實(shí)現(xiàn)幾個(gè) command 命令,start:?jiǎn)?dòng)北極星,version: 查詢當(dāng)前北極星進(jìn)程版本
├── common                     # 公共模塊,放置api接口對(duì)象定義、功能模塊的工具函數(shù)
├── config                     # 北極星的配置中心
├── main.go                    # main 函數(shù)所在文件,polaris-server 進(jìn)程啟動(dòng)的入口
├── maintain                   # 北極星自身運(yùn)維能力模塊
├── namespace                  # 北極星命名空間模塊,主要用于服務(wù)注冊(cè)發(fā)現(xiàn)以及配置中心
├── plugin                     # 北極星小功能插件模塊,主要集中了各個(gè)旁路能力的默認(rèn)插件實(shí)現(xiàn)
├── plugin.go                  # 北極星的插件注冊(cè)文件,利用 golang 的 init 機(jī)制
├── polaris-server.yaml        # polaris-server 進(jìn)程啟動(dòng)所需要的配置文件
├── service                    # 北極星的服務(wù)注冊(cè)發(fā)現(xiàn)中心、治理規(guī)則中心
├── store                      # 北極星的存儲(chǔ)層,已插件化,存在兩個(gè)默認(rèn)實(shí)現(xiàn)插件,一個(gè)是基于boltdb實(shí)現(xiàn)的單機(jī)存儲(chǔ)插件,一個(gè)是基于MySQL實(shí)現(xiàn)的集群存儲(chǔ)插件
├── tool                       # 北極星的相關(guān)腳本,包含啟動(dòng)、關(guān)閉
└── version                    # 編譯期間注入版本信息

從源碼的組織中可以看出,北極星各個(gè)功能模塊的劃分還是很清晰的,其核心的模塊主要是以下六個(gè)

  • apiserver
  • bootstrap
  • cache
  • namespace
  • config
  • service

我們先來看看,是如何在bootstrap中完成對(duì)北極星各個(gè)功能模塊的初始化以及逐個(gè)啟動(dòng)的

Bootstrap

先看看 bootstrap 下的源碼文件組織

?  bootstrap git:(release-v1.12.0) tree -L 1
.
├── config                 # bootstrap 在 polaris-server.yaml 中對(duì)應(yīng)的配置對(duì)象
├── run_darwin.go          # 用于 drawin 內(nèi)核,阻塞 polaris-server 主協(xié)程不退出,并監(jiān)聽相應(yīng)的os.Signal
├── run_linux.go           # 用于 linux 內(nèi)核,阻塞 polaris-server 主協(xié)程不退出,并監(jiān)聽相應(yīng)的os.Signal
├── run_windows.go         # 用于 window 內(nèi)核,阻塞 polaris-server 主協(xié)程不退出,并監(jiān)聽相應(yīng)的os.Signal
├── self_checker.go        # 北極星服務(wù)端自身的心跳上報(bào)流程,保持自身注冊(cè)的相關(guān)內(nèi)置服務(wù)實(shí)例的健康
└── server.go              # 北極星啟動(dòng)核心邏輯文件

既然 server.go 是服務(wù)端進(jìn)程啟動(dòng)核心邏輯所在的文件,那我們就直接從他入手。

來到 server.go 文件中,立馬就看到一個(gè) Start(configFilePath string) 方法,毋庸置疑,這肯定就是北極星服務(wù)端啟動(dòng)的核心入口。我們來簡(jiǎn)單看看,server.go#Start(configFilePath string) 主要做了哪些事情

func Start(configFilePath string) {
	// 根據(jù)所給定的配置文件路徑信息,加載對(duì)應(yīng)的配置文件內(nèi)容, 這里指的就是 polaris-server.yaml 中的內(nèi)容
	cfg, err := boot_config.Load(configFilePath)
        ...
	// 根據(jù)配置文件內(nèi)容中對(duì)于日志模塊的配置, 初始化日志模塊
	err = log.Configure(cfg.Bootstrap.Logger)
        // 初始化相關(guān)指標(biāo)收集器
	metrics.InitMetrics()
	// 設(shè)置插件配置
	plugin.SetPluginConfig(&cfg.Plugin)
	// 初始化存儲(chǔ)層
	store.SetStoreConfig(&cfg.Store)
	// 開啟進(jìn)入啟動(dòng)流程,初始化插件,加載數(shù)據(jù)等
	var tx store.Transaction
        // 根據(jù) ${bootstrap.startInOrder.key} 從存儲(chǔ)層獲取一把鎖,如果鎖獲取成功,則繼續(xù)執(zhí)行
	tx, err = StartBootstrapInOrder(s, cfg)
	if err != nil {
		// 多次嘗試加鎖失敗
		fmt.Printf("[ERROR] bootstrap fail: %v\n", err)
		return
	}
        // 啟動(dòng)北極星服務(wù)端的功能模塊(服務(wù)發(fā)現(xiàn)、服務(wù)治理、配置中心等等)
	err = StartComponents(ctx, cfg)
	...
	// 啟動(dòng)北極星的 apiserver 插件,對(duì)于 polaris-server.yaml 中配置的 apiserver 均會(huì)進(jìn)行啟動(dòng)
	servers, err := StartServers(ctx, cfg, errCh)
        // 北極星服務(wù)端自注冊(cè)邏輯,方便其他節(jié)點(diǎn)感知到自己的存在
	if err := polarisServiceRegister(&cfg.Bootstrap.PolarisService, cfg.APIServers); err != nil {
		fmt.Printf("[ERROR] register polaris service fail: %v\n", err)
		return
	}
        // 服務(wù)端啟動(dòng)完成,發(fā)起請(qǐng)求到存儲(chǔ)層,釋放名為${bootstrap.startInOrder.key}的鎖
        // 其他北極星節(jié)點(diǎn)便可以獲取到鎖之后繼續(xù)完成自己的啟動(dòng)邏輯
	_ = FinishBootstrapOrder(tx)
	fmt.Println("finish starting server")
        // 簡(jiǎn)單的死循環(huán)邏輯,監(jiān)聽 os.Signal 完成 apiserver 重啟、服務(wù)端優(yōu)雅下線邏輯
	RunMainLoop(servers, errCh)
}

簡(jiǎn)單的梳理 server.go#Start(configFilePath string) 中邏輯,主要就是做了這么幾個(gè)事情

  • 配置文件加載識(shí)別、初始化相關(guān)功能模塊配置
  • 從存儲(chǔ)層申請(qǐng)用于進(jìn)程啟動(dòng)的分布式鎖
  • 啟動(dòng)服務(wù)端功能模塊
  • 釋放自身對(duì)于啟動(dòng)分布式鎖的占用
  • 啟動(dòng) apiserver

接著我們來看下功能模塊是如何逐個(gè)開啟的。

功能模塊啟用

北極星的功能模塊主要有三個(gè)

  • APIServer
  • 命名空間
  • 服務(wù)注冊(cè)發(fā)現(xiàn)、服務(wù)治理
  • 配置中心

北極星的旁路功能模塊則為

  • 數(shù)據(jù)存儲(chǔ)層
  • 資源鑒權(quán)
  • 數(shù)據(jù)緩存
  • 運(yùn)維模塊

APIServer 模塊初始化

北極星的 APIServer 層,通過插件化的設(shè)計(jì),將北極星的能力通過各個(gè)協(xié)議對(duì)外提供,以及對(duì)其他注冊(cè)中心組件的協(xié)議兼容。APIServer 的定義如下

type Apiserver interface {
	// GetProtocol API協(xié)議名
	GetProtocol() string
	// GetPort API的監(jiān)聽端口
	GetPort() uint32
	// Initialize API初始化邏輯
	Initialize(ctx context.Context, option map[string]interface{}, api map[string]APIConfig) error
	// Run API服務(wù)的主邏輯循環(huán)
	Run(errCh chan error)
	// Stop 停止API端口監(jiān)聽
	Stop()
	// Restart 重啟API
	Restart(option map[string]interface{}, api map[string]APIConfig, errCh chan error) error
}

可以看到,APIServer interface 只是定義了 APIServer 插件的相關(guān)生命周期定義,并沒有具體限制 APIServer 改如何處理數(shù)據(jù)請(qǐng)求,因此使得 APIServer 相關(guān)插件實(shí)現(xiàn),即可以將北極星的能力通過 gRPC、HTTP 協(xié)議對(duì)外提供,同時(shí)也可以通過 APIServer 插件對(duì) eureka、xds 等第三方協(xié)議進(jìn)行適配,將其轉(zhuǎn)換為北極星的相關(guān)能力接口以及數(shù)據(jù)模型。 當(dāng)前北極星 APIServer 已有的插件列表如下

  • httpserver: 通過 HTTP 協(xié)議對(duì)外提供北極星服務(wù)端的 OpenAPI 以及和客戶端進(jìn)行數(shù)據(jù)通信的 ClientAPI
  • grpcserver: 通過 gRPC 協(xié)議提供北極星和客戶端進(jìn)行數(shù)據(jù)通信
  • eurekaserver: 通過 HTTP 協(xié)議,將 eureka 的能力適配成北極星的相關(guān)能力接口,以及將 eureka 數(shù)據(jù)模型映射為北極星的數(shù)據(jù)模型
  • xdsv3server: 根據(jù) xds control plane 的協(xié)議標(biāo)準(zhǔn),將北極星的服務(wù)模型、治理模型轉(zhuǎn)為 xds 模型,對(duì)外提供 xds 的能力,使得北極星可以對(duì)接 envoy 等相關(guān)基于 xds 實(shí)現(xiàn)的數(shù)據(jù)面

數(shù)據(jù)緩存模塊初始化

// StartComponents start health check and naming components
func StartComponents(ctx context.Context, cfg *boot_config.Config) error {
    var err error
    ...
    // 初始化緩存模塊
    if err := cache.Initialize(ctx, &cfg.Cache, s); err != nil {
        return err
    }
}

緩存層模塊初始化的觸發(fā)在 StartComponents 流程中,在初始化過程中,會(huì)根據(jù) polaris-server.yaml 配置文件中關(guān)于 cache 配置的 resources 列表,按需啟動(dòng)相關(guān)資源的 cache 實(shí)現(xiàn)

// 構(gòu)建 CacheManager 對(duì)象實(shí)例,并構(gòu)造所有資源的 Cache 接口實(shí)現(xiàn)實(shí)例
func newCacheManager(_ context.Context, cacheOpt *Config, storage store.Store) (*CacheManager, error) {
	SetCacheConfig(cacheOpt)
	mgr := &CacheManager{
		storage:       storage,
		caches:        make([]Cache, CacheLast),
		comRevisionCh: make(chan *revisionNotify, RevisionChanCount),
		revisions:     map[string]string{},
	}
        // 構(gòu)建服務(wù)實(shí)例緩存 cache
	ic := newInstanceCache(storage, mgr.comRevisionCh)
        // 構(gòu)建服務(wù)緩存 cache
	sc := newServiceCache(storage, mgr.comRevisionCh, ic)
	mgr.caches[CacheService] = sc
	mgr.caches[CacheInstance] = ic
        // 構(gòu)建路由規(guī)則緩存 cache
	mgr.caches[CacheRoutingConfig] = newRoutingConfigCache(storage, sc)
	// 構(gòu)建限流規(guī)則緩存 cache
	mgr.caches[CacheRateLimit] = newRateLimitCache(storage)
        // 構(gòu)建熔斷規(guī)則緩存 cache
	mgr.caches[CacheCircuitBreaker] = newCircuitBreakerCache(storage)
	notify := make(chan interface{}, 8)
        // 構(gòu)建用戶列表緩存 cache
	mgr.caches[CacheUser] = newUserCache(storage, notify)
        // 構(gòu)建鑒權(quán)策略緩存 cache
	mgr.caches[CacheAuthStrategy] = newStrategyCache(storage, notify, mgr.caches[CacheUser].(UserCache))
        // 構(gòu)建命名空間緩存 cache
	mgr.caches[CacheNamespace] = newNamespaceCache(storage)
        // 構(gòu)建SDK實(shí)例信息緩存 cache
	mgr.caches[CacheClient] = newClientCache(storage)
	if len(mgr.caches) != CacheLast {
		return nil, errors.New("some Cache implement not loaded into CacheManager")
	}
	...
        // 根據(jù) polaris-server.yaml 配置完成最終的緩存模塊啟動(dòng)
	if err := mgr.initialize(); err != nil {
		return nil, err
	}
	return mgr, nil
}
// initialize 緩存對(duì)象初始化
func (nc *CacheManager) initialize() error {
	for _, obj := range nc.caches {
		var option map[string]interface{}
                // 根據(jù)配置文件中的 resource 列表,按需啟動(dòng)相關(guān)的 cache
		for _, entry := range config.Resources {
			if obj.name() == entry.Name {
				option = entry.Option
				break
			}
		}
		if err := obj.initialize(option); err != nil {
			return err
		}
	}
	return nil
}

資源鑒權(quán)模塊初始化

// StartComponents start health check and naming components
func StartComponents(ctx context.Context, cfg *boot_config.Config) error {
	...
	cacheMgn, err := cache.GetCacheManager()
	if err != nil {
		return err
	}
	// 初始化鑒權(quán)層
	if err = auth.Initialize(ctx, &cfg.Auth, s, cacheMgn); err != nil {
		return err
	}
}

資源鑒權(quán)模塊初始化的觸發(fā)在 StartComponents 流程中,由于資源鑒權(quán)模塊主要任務(wù)是根據(jù)配置的鑒權(quán)規(guī)則,針對(duì)每次請(qǐng)求都進(jìn)行一次策略計(jì)算,因此為了節(jié)省查詢相關(guān)規(guī)則的時(shí)間,以及鑒權(quán)規(guī)則信息、用戶信息變化不頻繁的假定之下,資源鑒權(quán)模塊默認(rèn)從資源緩存模塊中獲取相關(guān)對(duì)象,執(zhí)行計(jì)算并返回最終的資源鑒權(quán)結(jié)果。

命名空間模塊模塊初始化

// StartComponents start health check and naming components
func StartComponents(ctx context.Context, cfg *boot_config.Config) error {
        ...
	// 初始化命名空間模塊
	if err := namespace.Initialize(ctx, &cfg.Namespace, s, cacheMgn); err != nil {
		return err
	}
}

命名空間模塊初始化的觸發(fā)在 StartComponents 流程中,polaris 的服務(wù)注冊(cè)發(fā)現(xiàn)、配置中心的模型設(shè)計(jì)中都依賴命名空間,因此將命名空間相關(guān)能力獨(dú)立出來。 命名空間模塊相關(guān)的數(shù)據(jù)操作不是非常頻繁,數(shù)據(jù)操作都是直接和數(shù)據(jù)存儲(chǔ)層進(jìn)行交互,而依賴緩存模塊則是為了解決在創(chuàng)建服務(wù)、配置時(shí)觸發(fā)的命名空間自動(dòng)創(chuàng)建動(dòng)作,為了減少對(duì)數(shù)據(jù)存儲(chǔ)層的調(diào)用,通過緩存存在性判斷以及 singleflight.Group 組件來實(shí)現(xiàn)。

服務(wù)注冊(cè)發(fā)現(xiàn)、服務(wù)治理模塊初始化

// StartComponents start health check and naming components
func StartComponents(ctx context.Context, cfg *boot_config.Config) error {
        ...
	// 初始化服務(wù)發(fā)現(xiàn)模塊相關(guān)功能
	if err := StartDiscoverComponents(ctx, cfg, s, cacheMgn, authMgn); err != nil {
		return err
	}
}

服務(wù)注冊(cè)發(fā)現(xiàn)、服務(wù)治理模塊初始化的觸發(fā)在 StartComponents 流程中的 StartDiscoverComponents 方法。StartDiscoverComponents 具體做的事情如下

  • 創(chuàng)建注冊(cè)、反注冊(cè)批量控制器
    • 為了提高服務(wù)端注冊(cè)、反注冊(cè)的TPS,這里做了一個(gè)數(shù)據(jù)寫操作的Batch優(yōu)化,盡可能將一段時(shí)間內(nèi)一定量的數(shù)據(jù)寫操作合并成一個(gè)大的數(shù)據(jù)寫操作發(fā)往數(shù)據(jù)存儲(chǔ)層,減少對(duì)于數(shù)據(jù)存儲(chǔ)層的調(diào)用次數(shù)以及帶來的額外網(wǎng)絡(luò)開銷,提升整體服務(wù)端的請(qǐng)求吞吐量
  • 創(chuàng)建服務(wù)實(shí)例健康檢查組件
    • 對(duì)于服務(wù)實(shí)例的健康狀態(tài)檢查,有專門的 HealthCheckerServer 進(jìn)行處理,該模塊會(huì)監(jiān)聽緩存模塊中的InstanceCache的數(shù)據(jù)變化事件,從中選擇開啟了健康檢查的實(shí)例,將其納入健康檢查任務(wù)的TimeWheel中進(jìn)行周期性調(diào)度檢查
    • 實(shí)例的健康檢查機(jī)制,當(dāng)前 polaris 服務(wù)端做了插件化設(shè)計(jì),默認(rèn) HealthCheck 插件實(shí)現(xiàn)為檢查實(shí)例的心跳上報(bào)周期,該實(shí)現(xiàn)有兩種具體的實(shí)現(xiàn)方式,針對(duì)單機(jī)模式來說具體實(shí)現(xiàn)為 heartbeatMemory,即實(shí)例的心跳數(shù)據(jù)存儲(chǔ)在服務(wù)端內(nèi)部中;針對(duì)集群模式來說具體實(shí)現(xiàn)為 heartbeatRedis,即實(shí)例的心跳數(shù)據(jù)存儲(chǔ)在 redis 集群中,從而各個(gè)服務(wù)端節(jié)點(diǎn)都可以獲取到任意實(shí)例的上次心跳上報(bào)時(shí)間。
  • 創(chuàng)建 naming.Service 接口實(shí)例,完成服務(wù)注冊(cè)發(fā)現(xiàn)、服務(wù)治理模塊的初始化
  • 創(chuàng)建帶 auth 能力的 naming.Service 接口實(shí)例,注入資源權(quán)限檢查能力。

配置中心模塊初始化

// StartComponents start health check and naming components
func StartComponents(ctx context.Context, cfg *boot_config.Config) error {
        ...
	// 初始化配置中心模塊相關(guān)功能
	if err := StartConfigCenterComponents(ctx, cfg, s, cacheMgn, authMgn); err != nil {
		return err
	}
}

配置中心模塊初始化的觸發(fā)在 StartComponents 流程中的 StartConfigCenterComponents 方法。StartConfigCenterComponents 具體做的事情如下

  • 創(chuàng)建配置文件緩存組件,加速客戶端讀取配置文件,減少和存儲(chǔ)層的交互次數(shù)
  • 創(chuàng)建 Watch 客戶端鏈接管理組件,管理每條鏈接上感興趣的配置文件列表。
  • 創(chuàng)建配置發(fā)布事件中心,通過配置發(fā)布事件以及 Watch 客戶端連接管理組件,將相關(guān)配置變更事件通知給相關(guān)的客戶端,實(shí)現(xiàn)配置監(jiān)聽能力

以上就是go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程的詳細(xì)內(nèi)容,更多關(guān)于go PolarisMesh服務(wù)端啟動(dòng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于Go語言中的IO操作詳解

    關(guān)于Go語言中的IO操作詳解

    在現(xiàn)代軟件開發(fā)中,高效的輸入輸出(I/O)操作是提高程序性能的關(guān)鍵之一,Go語言提供了豐富的I/O操作接口,使得文件讀寫、網(wǎng)絡(luò)通信等任務(wù)變得簡(jiǎn)單而高效,本文介紹了關(guān)于Go語言中的IO操作,需要的朋友可以參考下
    2024-10-10
  • 使用Singleflight實(shí)現(xiàn)Golang代碼優(yōu)化

    使用Singleflight實(shí)現(xiàn)Golang代碼優(yōu)化

    有許多方法可以優(yōu)化代碼以提高效率,減少運(yùn)行進(jìn)程就是其中之一,本文我們就來學(xué)習(xí)一下如何通過使用一個(gè)Go包Singleflight來減少重復(fù)進(jìn)程,從而優(yōu)化Go代碼吧
    2023-09-09
  • 如何利用Golang解析讀取Mysql備份文件

    如何利用Golang解析讀取Mysql備份文件

    這篇文章主要給大家介紹了關(guān)于如何利用Golang解析讀取Mysql備份文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • golang-gorm自動(dòng)建表問題

    golang-gorm自動(dòng)建表問題

    這篇文章主要介紹了golang-gorm自動(dòng)建表問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Go中g(shù)in框架的*gin.Context參數(shù)常見實(shí)用方法

    Go中g(shù)in框架的*gin.Context參數(shù)常見實(shí)用方法

    *gin.Context是處理HTTP請(qǐng)求的核心,ctx代表"context"(上下文),它包含了處理請(qǐng)求所需的所有信息和方法,例如請(qǐng)求數(shù)據(jù)、響應(yīng)構(gòu)建器、路由參數(shù)等,這篇文章主要介紹了Go中g(shù)in框架的*gin.Context參數(shù)常見實(shí)用方法,需要的朋友可以參考下
    2024-07-07
  • Go并發(fā)編程之sync.Once使用實(shí)例詳解

    Go并發(fā)編程之sync.Once使用實(shí)例詳解

    sync.Once使用起來很簡(jiǎn)單, 下面是一個(gè)簡(jiǎn)單的使用案例,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法

    Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法

    本文主要介紹了Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Golang中的路由使用詳解

    Golang中的路由使用詳解

    這篇文章主要介紹了Golang中的路由使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • Golang如何調(diào)用windows下的dll動(dòng)態(tài)庫中的函數(shù)

    Golang如何調(diào)用windows下的dll動(dòng)態(tài)庫中的函數(shù)

    這篇文章主要介紹了Golang如何調(diào)用windows下的dll動(dòng)態(tài)庫中的函數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang線程池與協(xié)程池的使用

    Golang線程池與協(xié)程池的使用

    在Golang中,線程池和協(xié)程池是非常常見且重要的概念,它們可以提高應(yīng)用程序的并發(fā)處理能力和性能,減少資源的浪費(fèi),本文就來介紹一下Golang線程池與協(xié)程池的使用,感興趣的可以了解一下
    2024-04-04

最新評(píng)論