最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go-micro開發(fā)RPC服務(wù)以及運(yùn)行原理介紹

 更新時間:2022年07月04日 10:00:13   作者:波斯馬  
這篇文章介紹了go-micro開發(fā)RPC服務(wù)的方法及其運(yùn)行原理,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

go-micro是一個知名的golang微服務(wù)框架,最新版本是v4,這篇文章將介紹go-micro v4開發(fā)RPC服務(wù)的方法及其運(yùn)作原理。

基本概念

go-micro有幾個重要的概念,后邊開發(fā)RPC服務(wù)和介紹其運(yùn)行原理的時候會用到,這里先熟悉下:

  • Service:代表一個go-micro應(yīng)用程序,Service中包括:Server、Client、Broker、Transport、Registry、Config、Store、Cache等程序運(yùn)行所需的各個模塊。
  • Server:代表一個go-micro服務(wù)器,主要函數(shù)包括:Start、Stop、Handle、Subscribe。默認(rèn)創(chuàng)建的Server是 rpcServer。
  • Broker:用于處理異步消息,主要的函數(shù)包括:Connect、Publish、Subscribe。默認(rèn)的Broker是httpBroker。
  • Router:用于消息處理的路由,內(nèi)部包括兩種路由方式:RPC服務(wù)映射serviceMap和消息訂閱器subscribers。
  • Codec:用于消息的編解碼,主要函數(shù)包括:Marshal、Unmarshal默認(rèn)的Codec是json.Marshaler,是基于jsonpb的。RPC服務(wù)是根據(jù)請求頭中的Content-Type自動創(chuàng)建的。
  • Registry:用于服務(wù)發(fā)現(xiàn),主要函數(shù)包括:Register、Deregister、GetService、ListServices、Watch。默認(rèn)的Registry是mdns。
  • Selector: 用于從同一個服務(wù)的多個實例之中選擇一個,支持緩存,有隨機(jī)和輪詢兩種策略。
  • Transport:用于同步通信,主要函數(shù)包括:Dial、Listen。它的底層基于Socket的send、recv語義,有多種實現(xiàn),包括http、grpc、quic等。默認(rèn)的Transport是httpTransport。

開發(fā)RPC服務(wù)

RPC全稱是Remote Procedure Call,翻譯過來是就是:遠(yuǎn)程過程調(diào)用,中心思想是:像調(diào)用本地函數(shù)一樣調(diào)用遠(yuǎn)程函數(shù)。常見的Dubbo、Spring Cloud都可以稱為RPC框架,還有最近很流行的gRPC。

使用go-micro創(chuàng)建一個RPC服務(wù)很簡單,共分三步走:

1、編寫proto協(xié)議文件

這個服務(wù)提供的功能很簡單,名字為Hello,提供一個方法名字為Say,需要傳入一個字符串Name,然后返回一個字符串Message。這個文件我命名為 hello.proto,放到了項目中的 proto 文件夾中。

syntax = "proto3";

option go_package="/proto";

package Business;

service Hello {
  rpc Say (SayRequest) returns (SayResponse);
}

message SayResponse {
  string Message = 1;
}

message SayRequest {
  string Name = 1;
}

2、生成go-micro服務(wù)端代理

需要首先安裝protoc和兩個代碼生成插件。

protoc下載地址:https://github.com/protocolbuffers/protobuf/releases,保存到GO PATH/bin目錄中。同時建議將 GOPATH/bin 添加到環(huán)境變量 PATH 中,方便直接執(zhí)行相關(guān)命令。

兩個插件直接通過命令即可安裝:

go install google.golang.org/protobuf/cmd/protoc-gen-go
go install go-micro.dev/v4/cmd/protoc-gen-micro@v4

然后在項目的目錄下執(zhí)行命令:

protoc --go_out=. --go_opt=paths=source_relative --micro_out=. --micro_opt=paths=source_relative proto/hello.proto

然后會在proto文件夾中生成兩個文件:hello.pb.go 和 hello.pb.micro.go 。

下個步驟中就要使用它們來創(chuàng)建RPC服務(wù)。

3、編寫go-micro服務(wù)

這里先把代碼貼出來,然后再做一個簡要說明:

package main

import (
	"context"
	"fmt"
	"log"
	"rpchello/proto"

	"go-micro.dev/v4"
	"go-micro.dev/v4/server"
)

type Hello struct{}

func (s *Hello) Say(ctx context.Context, req *proto.SayRequest, rsp *proto.SayResponse) error {
	fmt.Println("request:", req.Name)
	rsp.Message = "Hello " + req.Name
	return nil
}

func main() {
	rpcServer := server.NewServer(
		server.Name("rpchello.service"),
		server.Address("0.0.0.0:8001"),
	)

	proto.RegisterHelloHandler(rpcServer, &Hello{})

	service := micro.NewService(
		micro.Server(rpcServer),
	)

	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}

上邊我們創(chuàng)建了一個 Hello 類型,然后給它綁定了一個名為Say的函數(shù)。這個是和proto協(xié)議對應(yīng)的,其實是實現(xiàn)了生成代碼 hello.pb.micro.go 中的HelloHandler接口:

type HelloHandler interface {
	Say(context.Context, *SayRequest, *SayResponse) error
}

然后main函數(shù)中是我們的重頭戲:先創(chuàng)建一個Server,默認(rèn)情況下就是rpc Server,設(shè)置它的名字、監(jiān)聽地址等參數(shù);然后創(chuàng)建一個Service,并綁定剛剛創(chuàng)建的Server;然后使用生成的服務(wù)端代理函數(shù)將我們編寫的Hello服務(wù)注冊到Server中;最后開啟運(yùn)行Service。

當(dāng)然只有一個服務(wù)端沒有什么意義,還得有客戶端來訪問它。這里也給一個例子:

package main

import (
	"bufio"
	"context"
	"fmt"
	"os"
	"rpchello/proto"

	"go-micro.dev/v4"
	"go-micro.dev/v4/client"
)

func main() {

	service := micro.NewService(
		micro.Client(client.NewClient()),
	)

	service.Init()
	client := proto.NewHelloService("rpchello.service", service.Client())

	rsp, err := client.Say(context.TODO(), &proto.SayRequest{Name: "BOSSMA"})
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(rsp)

	fmt.Println("Press Enter key to exit the program...")
	in := bufio.NewReader(os.Stdin)
	_, _, _ = in.ReadLine()
}

這里調(diào)用服務(wù)的時候沒有指定服務(wù)的地址和端口,因為內(nèi)部走了服務(wù)發(fā)現(xiàn),服務(wù)端會自動注冊服務(wù),客戶端會根據(jù)服務(wù)名稱查找到對應(yīng)的地址和端口。默認(rèn)的服務(wù)發(fā)現(xiàn)機(jī)制使用的是mdns。

RPC服務(wù)的運(yùn)行原理

這里從服務(wù)端的角度進(jìn)行介紹,先來看一張圖:

請大家參考代碼從上往下看。

NewServer 時創(chuàng)建一個rpcServer,這個rpcServer還會創(chuàng)建一個httpTransport用于程序間網(wǎng)絡(luò)通信,并綁定到當(dāng)前rpcServer。

RegisterXXXHandler 時使用我們編寫的Handler創(chuàng)建一個內(nèi)部的service實例,然后注冊這個service實例到rpcServer內(nèi)部的router中,客戶端請求時會用到它。這里其實可以注冊任意一個帶方法的類型,并不一定要定義proto協(xié)議,定義它只是為了協(xié)作更方便。

Service.Run 時會調(diào)用rpcServer的Start方法,這個方法內(nèi)部會調(diào)用其綁定的httpTransport的Listen方法,然后在其創(chuàng)建的Listener上接收客戶端連接,接收方法Accept傳入了當(dāng)前rpcServer的連接處理方法:rpcServer.ServeConn,有連接到來時會調(diào)用它。

當(dāng)客戶端請求來臨時,客戶端連接被交給rpcServer的ServeConn方法,然后又調(diào)用到HandleEvent方法。

然后進(jìn)入rpcServer內(nèi)部的router的函數(shù)ServeRequest中,通過分析請求消息,找到請求的服務(wù)名字和方法名字,在router中找到前面注冊過的service,通過servcie.call,再進(jìn)入function.call,最終通過反射調(diào)用到我們編寫的Handler的業(yè)務(wù)方法。

有的同學(xué)可能會想,反射不是性能很低嗎?!反射性能低主要是查找方法和字段的時候,調(diào)用方法的性能并不低,而查找方法和字段等的操作已經(jīng)在RegisterXXXHandler的步驟中做了,并且緩存到了router中,所以性能并不受影響。

到此這篇關(guān)于go-micro開發(fā)RPC服務(wù)的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • GoLang string與strings.Builder使用對比詳解

    GoLang string與strings.Builder使用對比詳解

    這篇文章主要介紹了GoLang string與strings.Builder使用對比,Builder 用于使用 Write 方法有效地構(gòu)建字符串。它最大限度地減少了內(nèi)存復(fù)制。零值可以使用了。不要復(fù)制非零生成器
    2023-03-03
  • GoLang 中的隨機(jī)數(shù)的示例代碼

    GoLang 中的隨機(jī)數(shù)的示例代碼

    本篇文章主要介紹了GoLang 中的隨機(jī)數(shù)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例

    Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例

    這篇文章主要介紹了Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例,Gocache是一個基于Go語言編寫的多存儲驅(qū)動的緩存擴(kuò)展組件,更多具體內(nèi)容感興趣的小伙伴可以參考一下
    2022-09-09
  • Go?語言開發(fā)環(huán)境搭建過程

    Go?語言開發(fā)環(huán)境搭建過程

    這篇文章主要介紹了Go?語言開發(fā)環(huán)境搭建過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-03-03
  • go實現(xiàn)冒泡排序算法

    go實現(xiàn)冒泡排序算法

    冒泡排序算法是數(shù)據(jù)結(jié)構(gòu)中常用的一種算法,本文就介紹了go實現(xiàn)冒泡排序算法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Go實現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法

    Go實現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法

    Go語言團(tuán)隊的一個核心目標(biāo)是保持語言的簡單性,他們認(rèn)為,如果一個功能可以用簡單的組合來實現(xiàn),那就沒有必要把它放進(jìn)標(biāo)準(zhǔn)庫里,本文給大家介紹Go實現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • IdeaGo啟動報錯Failed to create JVM的問題解析

    IdeaGo啟動報錯Failed to create JVM的問題解析

    這篇文章主要介紹了IdeaGo啟動報錯Failed to create JVM的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • GO語言實現(xiàn)簡單的目錄復(fù)制功能

    GO語言實現(xiàn)簡單的目錄復(fù)制功能

    這篇文章主要介紹了GO語言實現(xiàn)簡單的目錄復(fù)制功能,通過新建及復(fù)制內(nèi)容等操作最終實現(xiàn)復(fù)制目錄的功能效果,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • golang?select?機(jī)制和超時問題

    golang?select?機(jī)制和超時問題

    golang 中的協(xié)程使用非常方便,但是協(xié)程什么時候結(jié)束是一個控制問題,可以用 select 配合使用,這篇文章主要介紹了golang?select?機(jī)制和超時問題,需要的朋友可以參考下
    2022-06-06
  • Go數(shù)組與切片輕松掌握

    Go數(shù)組與切片輕松掌握

    在Java的核心庫中,集合框架可謂鼎鼎大名:Array、List、Set等等,隨便拎一個出來都值得開發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計源碼。雖然Go語言沒有如此豐富的容器類型,但也有一些基本的容器供開發(fā)者使用,接下來讓我們認(rèn)識一下這些容器類型吧
    2022-11-11

最新評論

石家庄市| 福安市| 兴海县| 洱源县| 芮城县| 靖西县| 房产| 长寿区| 桓台县| 甘谷县| 柯坪县| 安塞县| 白银市| 同心县| 改则县| 枣强县| 新竹县| 永年县| 久治县| 增城市| 富蕴县| 潼南县| 乐安县| 兴和县| 景东| 盐边县| 四川省| 五莲县| 信阳市| 黄梅县| 金山区| 东台市| 龙江县| 吴忠市| 石狮市| 呼图壁县| 商水县| 南投县| 乐平市| 临漳县| 梁山县|