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

golang grpc配置使用實(shí)戰(zhàn)

 更新時(shí)間:2023年05月08日 09:04:36   作者:small_to_large  
本文主要介紹了golang grpc配置使用實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是PRC&GRPC

RPC是遠(yuǎn)程過程調(diào)用(Remote Procedure Call)的縮寫形式, RPC 的主要功能目標(biāo)是讓構(gòu)建分布式計(jì)算(應(yīng)用)更容易,在提供強(qiáng)大的遠(yuǎn)程調(diào)用能力時(shí)不損失本地調(diào)用的語義簡潔性。通俗地講,使用RPC進(jìn)行通信,調(diào)用遠(yuǎn)程函數(shù)就像調(diào)用本地函數(shù)一樣,RPC底層會做好數(shù)據(jù)的序列化與傳輸。 下圖是dubbo rpc實(shí)現(xiàn)的圖解,以便于大家理解RPC:

GRPC是rpc框架的實(shí)現(xiàn),是一個(gè)基于Protobuf序列化協(xié)議開發(fā)的高性能,開源和通用的RPC框架,且支持眾多開發(fā)語言。

從圖中還可以看出,proto文件的編譯支持多種語言(Go、Java、Python等),可以輕松實(shí)現(xiàn)跨語言調(diào)用。

RPC調(diào)用之前需要進(jìn)行IDL文件定義編寫和對應(yīng)語言調(diào)用模板方法生成(protoc自動生成)

RPC調(diào)用大致步驟:

  • 客戶端建立連接(gRPC Stub)并調(diào)用A方法,發(fā)起RPC調(diào)用
  • gRPC框架對請求信息使用Protobuf進(jìn)行對象序列化壓縮(IDL)
  • 服務(wù)端(gPRC Server)接收到請求后,解碼反序列化,進(jìn)行業(yè)務(wù)邏輯處理并返回。
  • 對響應(yīng)結(jié)果使用Protobuf進(jìn)行對象序列化壓縮(IDL)
  • 客戶端接受到服務(wù)端響應(yīng),解碼發(fā)序列化?;卣{(diào)被調(diào)用的A方法,喚醒正在等待響應(yīng)(阻塞)的客戶端調(diào)用并返回響應(yīng)結(jié)果。

Go gRPC 環(huán)境準(zhǔn)備

本人是在WSL環(huán)境(window linux 子系統(tǒng))進(jìn)行的,window 和 mac 可以自行嘗試,原理和步驟都一樣。

Go 語言環(huán)境安裝,下載對應(yīng)的安裝包,配置GOPATH、GOROOT、GOPROXY,以及GO111MODULE 設(shè)置為on,具體安裝和配置細(xì)節(jié)可參考官網(wǎng)和其他教程,這里列出自己的go env信息:

# GO111MODULE on模式
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/lizheng/.cache/go-build"
GOENV="/home/lizheng/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/lizheng/gopath/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
# GOPATH 配置
GOPATH="/home/lizheng/gopath"
GOPRIVATE=""
# GOPROXY 配置
GOPROXY="https://goproxy.cn"
# GOROOT 配置
GOROOT="/home/lizheng/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/lizheng/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.7"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1495300227=/tmp/go-build -gno-record-gcc-switches"

Protocol buffer 編譯器配置這里的Protocol buffer編譯器用來編譯 .proto RPC協(xié)議定義文件,自動生成對應(yīng)語言的目標(biāo)代碼,減少開發(fā)量。安裝步驟參考:protoc 安裝文檔

lizheng@lz-x:~$  apt install -y protobuf-compiler
lizheng@lz-x:~$ protoc --version
libprotoc 3.6.1

Protocol buffer Go語言編譯插件配置安裝因?yàn)槲覀兪褂玫氖莋o語言實(shí)現(xiàn)grpc,所以 protoc 命令在執(zhí)行編譯的時(shí)候,會調(diào)用go語言插件,來生成golang代碼。

lizheng@lz-x:~$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
lizheng@lz-x:~$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

注意:這里安裝完成之后,會將對應(yīng)命令安裝到gopath配置目錄下的bin文件夾下如下圖

我們需要確保bin下文件命令可以被全局訪問到,配置到PATH中即可,如果是window需要配置到環(huán)境變量path中

實(shí)戰(zhàn)編寫和調(diào)用

經(jīng)過上述步驟環(huán)境已經(jīng)完成配置,我們開始一個(gè)helloword的程序開發(fā),包括服務(wù)端和客戶端兩部分。

  • 新建一個(gè)文件夾 my-grpc,使用 go mod init example.com/ggrpc初始化項(xiàng)目
  • 建立子文件夾:client、server、proto,分別存儲客戶端、服務(wù)端、grpc存根文件。
  • 進(jìn)入proto,新建一個(gè) helloworld.proto 文件,編寫一下內(nèi)容:
// 使用的語法協(xié)議版本 proto3
syntax = "proto3";
package proto;
// 定義生成go文件的package位置和名稱
option go_package = "./;proto";
// 定義Greeter服務(wù)
service Greeter {
    // 定義SayHello方法,接受HelloRequest消息, 并返回HelloReply消息
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 定義請求對象
message HelloRequest {
    string name = 1;
}
// 定義返回對象
message HelloReply {
    string message = 1;
}

上面只是一個(gè)簡單的定義,細(xì)節(jié)proto語法可自行官網(wǎng)學(xué)習(xí)

執(zhí)行protoc命令,生成目標(biāo)語言文件

# \ 為命令換行但不執(zhí)行,可以寫一行那就不需要 \ 了
protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    helloworld.proto

執(zhí)行成功會生成:helloworld.pb.go 和 helloworld_grpc.pb.go 兩個(gè)文件

5. 執(zhí)行 go mod tidy 下載依賴包,主要是grpc相關(guān)的包6. 編寫服務(wù)端和客戶端代碼

服務(wù)端

package main
import (
	"context"
	"flag"
	"fmt"
	"log"
	"net"
	"time"
	h "example.com/ggrpc/handler"
	pb "example.com/ggrpc/proto"
	"google.golang.org/grpc"
)
var (
	port = flag.Int("port", 8000, "The server port")
)
// 定義一個(gè)server實(shí)現(xiàn)UnimplementedGreeterServer
// UnimplementedGreeterServer 是第四步自動生成的,可以打開對應(yīng)文件查看
type server struct {
	pb.UnimplementedGreeterServer
}
// server 重寫SayHello方法,做業(yè)務(wù)處理
func (s *server) SayHello(c context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
	log.Printf("接收到客戶端的消息: %v", req.GetName())
	time.Sleep(time.Second)
	ms := fmt.Sprintf("好的收到,%s %s", req.GetName(), time.Now())
	log.Printf("回復(fù)客戶端的消息: %s", ms)
	return &pb.HelloReply{Message: ms}, nil
}
func main() {
	// 解析命令行參數(shù)
	flag.Parse()
	// 監(jiān)聽本地tcp端口
	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	// 創(chuàng)建一個(gè)grpc Server服務(wù)對象,Handler非必傳
	// s := grpc.NewServer() // 可以直接創(chuàng)建對象
	s := grpc.NewServer(grpc.StatsHandler(&h.MyHandler{}))
	// 注冊服務(wù)
	pb.RegisterGreeterServer(s, &server{})
	// 啟動RPC并監(jiān)聽
	log.Printf("server listening at %v", lis.Addr())
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

客戶端

package main
import (
	"context"
	"flag"
	"log"
	"time"
	pb "example.com/ggrpc/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)
var serAddr = flag.String("addr", "localhost:8000", "the address to connect to")
func main() {
	// 解析命令行參數(shù)
	flag.Parse()
	// 連接服務(wù)端
	conn, err := grpc.Dial(*serAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("連接服務(wù)器失敗: %v", err)
	}
	log.Printf("建立連接成功: %s", *serAddr)
	// 執(zhí)行完方法自動關(guān)閉資源
	defer conn.Close()
	// 創(chuàng)建客戶端
	c := pb.NewGreeterClient(conn)
	log.Println("5秒中之后調(diào)用SayHello方法")
	time.Sleep(time.Second * 5)
	// 創(chuàng)建2秒超時(shí)ctx
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
	defer cancel()
	// 發(fā)起RPC請求
	log.Println("開始調(diào)用SayHello方法")
	res, err := c.SayHello(ctx, &pb.HelloRequest{Name: "一號"})
	if err != nil {
		log.Fatalf("請求失敗: %v", err)
	}
	log.Printf("請求結(jié)果: %s", res.GetMessage())
	// 睡眠一會再結(jié)束
	log.Println("3秒后結(jié)束,客戶端自動斷開連接")
	time.Sleep(time.Second * 3)
}

因?yàn)楸救藴y試加了一個(gè)server端的handler,給出handle的代碼,可以忽略

package handler
import (
	"context"
	"log"
	"google.golang.org/grpc/stats"
)
// 自定義handler實(shí)現(xiàn)stats.Handler打印一些信息
type MyHandler struct {
}
func (h *MyHandler) TagRPC(c context.Context, tag *stats.RPCTagInfo) context.Context {
	log.Printf("TagRPC: %v", tag)
	return c
}
func (h *MyHandler) HandleRPC(c context.Context, s stats.RPCStats) {
	log.Printf("HandleRPC: %v", s)
}
func (h *MyHandler) TagConn(c context.Context, tag *stats.ConnTagInfo) context.Context {
	log.Printf("TagConn: %v", tag)
	return c
}
func (h *MyHandler) HandleConn(c context.Context, s stats.ConnStats) {
	log.Printf("HandleConn: %v", s)
}

到此這篇關(guān)于golang grpc配置使用實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)golang grpc配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解GO語言中[]byte與string的兩種轉(zhuǎn)換方式和底層實(shí)現(xiàn)

    詳解GO語言中[]byte與string的兩種轉(zhuǎn)換方式和底層實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了GO語言中[]byte與string的兩種轉(zhuǎn)換方式和底層實(shí)現(xiàn)的相關(guān)知識,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下
    2024-03-03
  • 詳解Golang net/http包中的RoundTripper接口

    詳解Golang net/http包中的RoundTripper接口

    RoundTripper 是 net/http 包中的一個(gè)接口,定義了處理 HTTP 請求返回和響應(yīng)的方法,是 http.Client 結(jié)構(gòu)體中執(zhí)行 http 請求的核心部分,本文將詳細(xì)的給大家介紹Golang RoundTripper接口,需要的朋友可以參考下
    2023-09-09
  • golang連接redis庫及基本操作示例過程

    golang連接redis庫及基本操作示例過程

    這篇文章主要介紹了golang連接redis庫及基本操作示例過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • golang 如何獲取pem格式RSA公私鑰長度

    golang 如何獲取pem格式RSA公私鑰長度

    這篇文章主要介紹了golang 如何獲取pem格式RSA公私鑰長度操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • GoFrame框架gcache的緩存控制淘汰策略實(shí)踐示例

    GoFrame框架gcache的緩存控制淘汰策略實(shí)踐示例

    這篇文章主要為大家介紹了GoFrame框架gcache的緩存控制淘汰策略的實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go高級特性探究之recover捕獲panic詳解

    Go高級特性探究之recover捕獲panic詳解

    在Go語言中,當(dāng)程序出現(xiàn)panic(即運(yùn)行時(shí)錯(cuò)誤)時(shí),程序會立即停止當(dāng)前的執(zhí)行流程,而recover函數(shù)的作用就是捕獲這個(gè)panic,下面就來看看具體是怎么操作的吧
    2023-06-06
  • GoLang sync.Pool簡介與用法

    GoLang sync.Pool簡介與用法

    這篇文章主要介紹了GoLang sync.Pool簡介與用法,Pool是可伸縮、并發(fā)安全的臨時(shí)對象池,用來存放已經(jīng)分配但暫時(shí)不用的臨時(shí)對象,通過對象重用機(jī)制,緩解GC壓力,提高程序性能
    2023-01-01
  • golang字符串切片去重的幾種算法

    golang字符串切片去重的幾種算法

    這篇文章主要介紹了golang字符串切片去重的幾種算法的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • Go并發(fā)之RWMutex的源碼解析詳解

    Go并發(fā)之RWMutex的源碼解析詳解

    RWMutex是一個(gè)支持并行讀串行寫的讀寫鎖。RWMutex具有寫操作優(yōu)先的特點(diǎn),寫操作發(fā)生時(shí),僅允許正在執(zhí)行的讀操作執(zhí)行,后續(xù)的讀操作都會被阻塞。本文就來從源碼解析一下RWMutex的使用
    2023-03-03
  • VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程

    VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程

    這篇文章主要介紹了VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程,本文通過實(shí)例代碼圖文相結(jié)合的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評論

盐津县| 桂东县| 丹巴县| 马公市| 友谊县| 区。| 武安市| 东台市| 兰州市| 慈利县| 吴忠市| 班玛县| 齐齐哈尔市| 青河县| 贵德县| 平利县| 辽中县| 苏尼特右旗| 平舆县| 丹阳市| 广平县| 息烽县| 临潭县| 乌恰县| 广水市| 璧山县| 沁源县| 辰溪县| 河南省| 怀远县| 静宁县| 大方县| 大连市| 庆元县| 丹江口市| 西贡区| 上高县| 荆州市| 阿瓦提县| 涡阳县| 会同县|