国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

go語言:騰訊終于開源trpc框架——對trpc-go源碼分析

這篇具有很好參考價值的文章主要介紹了go語言:騰訊終于開源trpc框架——對trpc-go源碼分析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

在看下面時,我們先來 分析下入口方法,trpc.NewServer都做了拿一些事情
1.讀取配置文件,這里會讀取用戶設(shè)置的配置文件路徑在(./trpc_go.yaml)和設(shè)置默認配置(網(wǎng)絡(luò)類型tcp,協(xié)議類型trpc),然后設(shè)置到Config對象中
2.把配置通過localstore的方式設(shè)置到全局變量中
3.開始設(shè)置用戶自定義插件,亮點功能
4.初始化服務(wù)和rpc連接的最大并發(fā)數(shù)
5.關(guān)閉插件方法,前提是插件必須實現(xiàn)了closes接口
  • 根據(jù)以上,我們對trpc框架進行三個方面的講解
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

1.trpc框架配置文件加載方式

trpc配置文件采用yaml格式,文件默認目錄在 ./trpc_go.yaml下,所有自定義配置都需要寫在這個yaml文件中,所有支持用戶自定義的配置都可以參考結(jié)構(gòu)體config

// Config is the configuration for trpc, which can be divided into 4 parts:
// 1. Global config.
// 2. Server config.
// 3. Client config.
// 4. Plugins config.
type Config struct {
	Global struct {
		Namespace     string `yaml:"namespace"`      // Namespace for the configuration.
		EnvName       string `yaml:"env_name"`       // Environment name.
		ContainerName string `yaml:"container_name"` // Container name.
		LocalIP       string `yaml:"local_ip"`       // Local IP address.
		EnableSet     string `yaml:"enable_set"`     // Y/N. Whether to enable Set. Default is N.
		// Full set name with the format: [set name].[set region].[set group name].
		FullSetName string `yaml:"full_set_name"`
		// Size of the read buffer in bytes. <=0 means read buffer disabled. Default value will be used if not set.
		ReadBufferSize *int `yaml:"read_buffer_size,omitempty"`
	}
	Server struct {
		App      string `yaml:"app"`       // Application name.
		Server   string `yaml:"server"`    // Server name.
		BinPath  string `yaml:"bin_path"`  // Binary file path.
		DataPath string `yaml:"data_path"` // Data file path.
		ConfPath string `yaml:"conf_path"` // Configuration file path.
		Admin    struct {
			IP           string      `yaml:"ip"`            // NIC IP to bind, e.g., 127.0.0.1.
			Nic          string      `yaml:"nic"`           // NIC to bind.
			Port         uint16      `yaml:"port"`          // Port to bind, e.g., 80. Default is 9028.
			ReadTimeout  int         `yaml:"read_timeout"`  // Read timeout in milliseconds for admin HTTP server.
			WriteTimeout int         `yaml:"write_timeout"` // Write timeout in milliseconds for admin HTTP server.
			EnableTLS    bool        `yaml:"enable_tls"`    // Whether to enable TLS.
			RPCZ         *RPCZConfig `yaml:"rpcz"`          // RPCZ configuration.
		}
		Transport    string           `yaml:"transport"`     // Transport type.
		Network      string           `yaml:"network"`       // Network type for all services. Default is tcp.
		Protocol     string           `yaml:"protocol"`      // Protocol type for all services. Default is trpc.
		Filter       []string         `yaml:"filter"`        // Filters for all services.
		StreamFilter []string         `yaml:"stream_filter"` // Stream filters for all services.
		Service      []*ServiceConfig `yaml:"service"`       // Configuration for each individual service.
		// Minimum waiting time in milliseconds when closing the server to wait for deregister finish.
		CloseWaitTime int `yaml:"close_wait_time"`
		// Maximum waiting time in milliseconds when closing the server to wait for requests to finish.
		MaxCloseWaitTime int `yaml:"max_close_wait_time"`
		Timeout          int `yaml:"timeout"` // Timeout in milliseconds.
	}
	Client  ClientConfig  `yaml:"client"`  // Client configuration.
	Plugins plugin.Config `yaml:"plugins"` // Plugins configuration.
}

1.1 trpc配置文件加載流程和干了哪些事情

簡單來說干了以下幾件事情

  • 1.獲取配置文件的默認目錄,并且解析目錄到 ServerConfigPath 中
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 2.讀取yaml文件,把用戶自定義配置讀取到config結(jié)構(gòu)體對象中,用于后續(xù)的使用和初始化
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 3.初始化用戶配置

 1.讀取配置文件中的ip地址,如果是網(wǎng)卡名稱,則獲取網(wǎng)卡對應(yīng)的ip地址,然后設(shè)置成服務(wù)的ip地址
 2.讀取用戶自定義配置 設(shè)置網(wǎng)絡(luò)協(xié)議類型和ip:prot地址,設(shè)置連接最大存活時間和請求超時時間
 3.讀取自定義客戶端網(wǎng)絡(luò)配置,并且設(shè)置到config對象中

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 4.采用atomic,Value的local store 寫時復制技術(shù)(線程安全)把config配置文件加載到全局對象 globalConfig 之中
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

2.插件化實現(xiàn)原理和簡單demo

 trpc-go實現(xiàn)插件化簡單來說就分為三步
 1.加載插件,設(shè)置一個插件隊列,按照用戶自定義的順序去加載讀取插件,并且把插件默認狀態(tài)變成不可用,使用方法 loadPlugins()
 2.從插件隊列中取出插件,進行啟動,使用方法setupPlugins()
 2.1.首先判斷插件的依賴關(guān)系,把先依賴的插件先啟動
 2.2.一個一個的去啟動插件并且執(zhí)行,然后把插件狀態(tài)變成可用
 3.執(zhí)行插件執(zhí)行結(jié)束關(guān)閉方法,onFinish() 如果你不想插件結(jié)束可以不用實現(xiàn)這個方法,該方法不是必選

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

2.1 加載插件方法分析 loadPlugins

1.首先設(shè)置默認支持最大插件個數(shù)1000、初始化channel插件隊列,設(shè)置插件默認狀態(tài)為false
2.讀取用戶配置文件,獲取到用戶自定義插件配置
3.通過用戶配置的yaml文件,在factory中獲取到具體初始化完成的插件
4.把初始化完成的插件狀態(tài)變成 false

注意:根據(jù)代碼可以分析出來 可以注冊多個類型的插件,每個類型又可以綁定多個插件,最小唯獨是插件類型+插件名稱,也就是一個具體的插件

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

2.2 插件啟動和插件啟動校驗 setupPlugins()

1.按照順序讀取插件隊列中的插件,插件隊列是利用channel實現(xiàn)的,先進先出隊列
2.檢查當前插件依賴的插件是否已經(jīng)初始化完成,如果沒有完成,則會把當前插件取出來放在channel隊尾	
如果想自定義依賴實現(xiàn)接口 Depender 即可,注意這里分為強依賴和弱依賴
   強依賴:如果插件a強依賴插件b,那么插件[]b們必須存在,插件a會在插件b初始化完成后再初始化
   弱依賴:如果插件a弱依賴插件[]b們,只需要有一個插件存在就可以
3.如果插件檢查完畢通過后,trpc會調(diào)用 插件實現(xiàn)的 setup()方法去運行插件,而且把用戶自定義的配置信息傳遞過去
4.最后檢驗插件是否初始化和執(zhí)行完畢
 如果沒有完畢,會返回一個錯誤 cycle depends, not plugin is setup,服務(wù)將不會啟動
 如果完畢,則會返回插件隊列和插件關(guān)閉函數(shù),前提是插件實現(xiàn)了插件關(guān)閉函數(shù)

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

2.3. 如果插件執(zhí)行完畢,實現(xiàn) OnFinish()方法,關(guān)閉插件;當然這個方法可以不用實現(xiàn)

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

2.4 流程總結(jié)

2.1 首先實現(xiàn) trpc提供的 Factory接口,完成自定義插件設(shè)計
2.2  插件中init() 方法里面調(diào)用 trpc提供的 plugins,Register() 方法 把插件注冊到 局部變量 var plugins = make(map[string]map[string]Factory)中
2.3 trpc框架在程序啟動的時候會調(diào)用 loadPlugins()方法和plugins中的 get()方法,把插件從factory中獲取出來 
  • 1.首先實現(xiàn) trpc提供的 Factory接口,完成自定義插件設(shè)計
      Factory接口有兩個方法 Type()和SetUp()
      Type()的作用是設(shè)置插件的類型,也就是插件的名稱,要保持唯一
      SetUp()的作用是實現(xiàn)插件具體的業(yè)務(wù)邏輯,trpc框架會進行調(diào)用
  • 2.在插件的init()方法中調(diào)用 trpc提供的 plugins,Register() 方法 把插件注冊到 局部變量 var plugins = make(map[string]map[string]Factory)中
  • 3.trpc框架在程序啟動的時候會調(diào)用 loadPlugins()方法和plugins中的 get()方法,把插件從factory中獲取出來,放入到channel隊列中依次執(zhí)行

2.5 實現(xiàn)插件demo,這里拿日志上報插件舉例子

插件demo

package main

import (
	"context"
	"trpc.group/trpc-go/trpc-go"
	"trpc.group/trpc-go/trpc-go/filter"
	"trpc.group/trpc-go/trpc-go/plugin"
)

const (
	pluginName = "metric_log"
	pluginType = "tracing"
)

// Config 插件配置
type MetricLogConfig struct {
	ServiceName string `yaml:"service_name"`
}

var metricLogConfigPluginCfg = MetricLogConfig{}

func init() {
	plugin.Register(pluginName, &MetricLogPlugin{})
}

// EduTracingPlugin
type MetricLogPlugin struct {
}

// PluginType 返回插件類型
func (e *MetricLogPlugin) Type() string {
	return pluginType
}

// Setup 裝載tracer實現(xiàn)
func (e *MetricLogPlugin) Setup(name string, decoder plugin.Decoder) error {
	cfg := MetricLogConfig{}
	//1。解析在trpc.yaml中自定義的插件配置文件
	if err := decoder.Decode(&cfg); err != nil {
		return err
	}

	//2.設(shè)置插件相關(guān)的配置參數(shù)和網(wǎng)絡(luò)類型
	if cfg.ServiceName == "" {
		cfg.ServiceName = pluginName
	}

	metricLogConfigPluginCfg = cfg
	//3.創(chuàng)建攔截器ServerFilterRaw 和ClientFilterRaw,攔截rpc請求,然后注冊到trpc攔截器中
	filter.Register(name, ServerFilterRaw(e), ClientFilterRaw(e))
	return nil
}
func ServerFilterRaw(e *MetricLogPlugin) filter.ServerFilter {
	return func(ctx context.Context, req interface{}, handler filter.ServerHandleFunc) (rsp interface{}, err error) {

		// 設(shè)置日志中的上下文處理.
		msg := trpc.Message(ctx)

		// 業(yè)務(wù)處理.
		rsp, err = handler(ctx, req)

		// 日志上報
		UploadLog(ctx, msg)

		return rsp, err
	}
}
func ClientFilterRaw(e *MetricLogPlugin) filter.Filter {
	return func(ctx context.Context, req, rsp interface{}, handler filter.HandleFunc) (err error) {
		msg := trpc.Message(ctx)

		// 業(yè)務(wù)處理.
		err = handler(ctx, req, rsp)

		// 日志上報
		UploadLog(ctx, msg)

		return err
	}
}

使用方式在自己服務(wù)的main,go中引入即可

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

3.trpc-go rpc注冊、調(diào)用流程

  trpc-go rpc 分成了三個部分
  1.在 trpc.NewServer()中調(diào)用 NewServerWithConfig()方法,把用戶自定義服務(wù)端配置加載到service對象中
  2.調(diào)用trpc工具生成的pb文件 如	pb.RegisterGoTrpcTestService(s.Service("trpc.test.svr"), service)把服務(wù)名稱和服務(wù)隊員的rpc方法注冊到server中
  3.調(diào)用s.serve()方法,創(chuàng)建tpc連接進行 rpc方法調(diào)用

3.1 初始化sevice NewServerWithConfig()

 1.讀取用戶自定義攔截器,進行攔截器去重
 攔截器支持普通攔截器Filter和流式攔截器StreamFilter

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego
2. 把網(wǎng)絡(luò)相關(guān)、攔截器相關(guān)等參數(shù)設(shè)置到service中

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

3.初始化Transport和ServeOptions對象
1.這里特別注意下 Transport對象,
該對象如果用戶在配置文件中沒有自定義,那么trpc框架會給他一個默認值,后續(xù)會使用該默認值進行rpc調(diào)用
2.這里特別注意下 s.opts.ServeOptions
把serve中的handler地址給了s.opts.ServeOptions,當在進行rpc方法注冊時,也會在s.opts.ServeOptions中注冊一份rpc方法表

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

3.2 注冊服務(wù)名稱和服務(wù)對應(yīng)的rpc方法到server中 service.Register()方法

Register(serviceDesc interface{}, serviceImpl interface{})

  • 1.register方法有兩個入?yún)?shù),一個是serviceDesc代表注冊的服務(wù)名稱,一個是serviceImpl代表服務(wù)的rpc方法列表

  • 2.register方法邏輯,主要就是初始化攔截器和注冊rpc方法到handler中

  • 2.1 首先初始化流式攔截器
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 2.2 然后把serviceImpl中的方法依次注冊到server的Handlers中,注意這一步也會把對象注冊到service的opts.ServeOptions中
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 2.3 初始化普通攔截器
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

3.3 建立rpc連接,進行rpc方法調(diào)用 s.serve()


建立rpc連接,也是按照傳統(tǒng)的net包進行的,分別分為
1.創(chuàng)建監(jiān)聽器
2.等待客戶端連接
3.調(diào)用rpc方法處理數(shù)據(jù),然后把數(shù)據(jù)寫入到連接中
4.關(guān)閉連接


  • 1.獲取初始化時的sevice對象,建立tcp連接,一個對象單獨建立一個連接
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego
    1. 調(diào)用第一步初始化 Transport對象的ListenAndServe()方法,如果沒有設(shè)置默認的listener,就會根據(jù)用戶設(shè)置的networker類型來創(chuàng)建監(jiān)聽器

trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

    1. 創(chuàng)建一個tcp的監(jiān)聽器,內(nèi)部用的就是net包的listne方法
      trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego
    1. 監(jiān)聽客戶端連接,如果沒有客戶端連接,Accept方法會阻塞
      trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego
  • 5.把rpc方法列表從opts.ServeOptions設(shè)置到conn.handler中去
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego

  • 6.調(diào)用rpc方法處理請求,然后再把數(shù)據(jù)通過conn連接寫會到客戶端,寫完后關(guān)閉連接,整個流程結(jié)束
    trpc-go,golang,開源,開發(fā)語言,rpc,后端,beego文章來源地址http://www.zghlxwxcb.cn/news/detail-771135.html

到了這里,關(guān)于go語言:騰訊終于開源trpc框架——對trpc-go源碼分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 騰訊開源的深度學習框架 Clara —— 簡潔而有力的解決方案

    作者:禪與計算機程序設(shè)計藝術(shù) 深度學習(Deep Learning)是一種基于神經(jīng)網(wǎng)絡(luò)的機器學習方法,它可以對輸入數(shù)據(jù)進行高效、準確地分析、預測和分類,尤其在圖像識別、自然語言處理、生物信息學等領(lǐng)域都取得了突破性的進步。 機器學習(Machine Learning)是一類計算機科學研

    2024年02月07日
    瀏覽(26)
  • android 五大應(yīng)用開發(fā)框架(1),騰訊竟然又偷偷開源了一套Android原生UI框架

    android 五大應(yīng)用開發(fā)框架(1),騰訊竟然又偷偷開源了一套Android原生UI框架

    2、Android Runtime Android包含一個核心庫的集合,提供大部分在Java編程語言核心類庫中可用的功能。每一個Android應(yīng)用程序是Dalvik虛擬機中的實例,運行在他們自己的進程中。Dalvik虛擬機設(shè)計成,在一個設(shè)備可以高效地運行多個虛擬機。Dalvik虛擬機可執(zhí)行文件格式是.dex,dex格式是

    2024年04月09日
    瀏覽(97)
  • 安卓開發(fā)面試問題回答技巧,騰訊竟然又偷偷開源了一套Android原生UI框架

    安卓開發(fā)面試問題回答技巧,騰訊竟然又偷偷開源了一套Android原生UI框架

    偶然看到知乎的內(nèi)推帖,投了個簡歷,下午hr姐姐call我,安排面試選在3天后,然而又要筆試阿里,所以沒怎么復習。 8點起床,9點過比較緊張的去了創(chuàng)業(yè)園,感覺知乎氛圍很好,在那等了一小會,有前臺大叔給你倒水。 應(yīng)該是個參加工作不久的研究僧師兄,出了一道算法題

    2024年03月12日
    瀏覽(89)
  • Go開源世界主流成熟ORM框架gorm實踐分享

    Go開源世界主流成熟ORM框架gorm實踐分享

    @ 目錄 概述 定義 核心功能 聲明模型與約定 gorm.Model 字段級權(quán)限 時間慣例 嵌入結(jié)構(gòu) 字段標簽 使用 安裝 數(shù)據(jù)庫鏈接 連接池 CRUD 接口 創(chuàng)建 查詢 高級查詢 修改 刪除 原始SQL 事務(wù) 轉(zhuǎn)換 分片 序列化 GORM 官網(wǎng)地址 https://gorm.io/ 最新版本v1.25.1 GORM 官網(wǎng)文檔地址 https://gorm.io/docs/ G

    2024年02月05日
    瀏覽(75)
  • Go 開源庫運行時依賴注入框架 Dependency injection

    一個Go編程語言的運行依賴注入庫。依賴注入是更廣泛的控制反轉(zhuǎn)技術(shù)的一種形式。它用于增加程序的模塊化并使其具有可擴展性。 依賴注入是更廣泛的控制反轉(zhuǎn)技術(shù)的一種形式。它用于增加程序的模塊化并使其具有可擴展性。 Providing Extraction Invocation Lazy-loading Interfaces Gro

    2024年02月07日
    瀏覽(30)
  • 【go 定時調(diào)度框架】你知道幾種go語言定時調(diào)度框架?

    Go語言中有很多類似Python apscheduler 的定時調(diào)度框架,其中比較流行的有以下幾個: cron: 一個基于Cron表達式的定時任務(wù)庫,可以精確到秒級。它提供了簡單易用的API來定義和管理定時任務(wù),支持任務(wù)暫停、恢復、刪除等操作,同時還能夠在多個節(jié)點之間共享狀態(tài)信息。 官方網(wǎng)

    2024年02月15日
    瀏覽(23)
  • GO編程語言:簡潔、高效、強大的開源編程語言

    GO編程語言:簡潔、高效、強大的開源編程語言

    在現(xiàn)代軟件開發(fā)領(lǐng)域,隨著應(yīng)用復雜度的不斷提升,開發(fā)人員對編程語言的需求也日益增長。GO編程語言,作為一種簡潔、高效且具備強大并發(fā)能力的新型開源編程語言,逐漸成為了許多開發(fā)者的首選。本文將詳細介紹GO語言在哪些項目開發(fā)中表現(xiàn)出色,以及為什么許多開發(fā)者

    2024年02月02日
    瀏覽(174)
  • Go語言五大主流web框架

    1. Gin (69.7K) 項目簡介:Gin 是一個用 Go (Golang) 編寫的 HTTP Web 框架。 它具有類似 Martini 的 API,但性能比 Martini 快 40 倍。 倉庫地址: https://github.com/gin-gonic/gin https://github.com/gin-gonic/gin 官方文檔地址: 文檔 | Gin Web Framework Gin 是什么?Gin 是一個用 Go (Golang) 編寫的 HTTP Web 框架

    2024年02月11日
    瀏覽(18)
  • Go語言web框架——Gin

    Go語言web框架——Gin

    Gin是一個go語言寫的Web框架 客戶機通過TCP/IP協(xié)議建立到服務(wù)器的TCP連接 客戶端向服務(wù)器發(fā)送HTTP協(xié)議請求 Request GET /url ,請求服務(wù)器里的資源文檔 服務(wù)器向客戶機發(fā)送HTTP協(xié)議應(yīng)答Response,如果請求的資源包含有動態(tài)語言的內(nèi)容,那么服務(wù)器會調(diào)用動態(tài)語言的解釋引擎負責處理

    2023年04月14日
    瀏覽(24)
  • GO語言篇之發(fā)布開源軟件包

    GO語言篇之發(fā)布開源軟件包

    我們寫GO語言程序的時候難免會引用第三方的軟件包,那么你知道別人是怎么發(fā)布自己的軟件包嗎,別急,這篇博客教你怎么做 至此,少年你已經(jīng)發(fā)布了第一個屬于自己的GO語言開源軟件包

    2024年02月09日
    瀏覽(57)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包