Triple 協(xié)議快速開始

2022-04-14 11:03 更新

1. 環(huán)境安裝

1.1 安裝Go語言環(huán)境

建議使用最新版 go 1.17

go version >= go 1.15

【Go 語言官網(wǎng)下載地址】

將 $GOPATH/bin 加入環(huán)境變量

1.2 安裝序列化工具protoc

【protoc 下載地址】

1.3 安裝 protoc-gen-go, proto-gen-go-triple 編譯插件

本章 quick start 按照最新版示例和組件進行介紹。

依賴Dubbo-goTripleprotoc-gen-go-triple
適配版本號v3.0.0-rc4-1v1.1.3v1.0.2
適配版本號v3.0.0-rc3v1.0.9v1.0.0
export GO111MODULE="on"
export GOPROXY="https://goproxy.cn"
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26.0
go install github.com/dubbogo/tools/cmd/protoc-gen-go-triple@v1.0.2

確保上述protoc 和安裝的 protoc-gen-go-triple 位于$(GOPATH)/bin, 在系統(tǒng)環(huán)境變量內(nèi)

$ protoc --version
libprotoc 3.14.0
$ protoc-gen-go --version
protoc-gen-go v1.26.0
$ protoc-gen-go-triple --version
protoc-gen-go-triple 1.0.2

1.4 啟動zookeeper

選擇您喜歡的方式啟動zk,如您安裝docker-compose可直接從文件啟動:

zookeeper.yml:

version: '3'
services:
  zookeeper:
    image: zookeeper
    ports:
      - 2181:2181
    restart: on-failure
docker-compose -f ./zookeeper.yml up -d

2. 編譯接口

2.1 編寫接口描述文件 helloworld.proto

syntax = "proto3";

option go_package="./;api"; // 必須填寫,這里的意義為:生成代碼在./(當前目錄) 使用'api'作為package名

// The greeting service definition.
service Greeter {
  rpc SayHello (HelloRequest) returns (User) {}
  rpc SayHelloStream (stream HelloRequest) returns (stream User) {}
}

// The request message
message HelloRequest {
  string name = 1;
}

// The response message
message User {
  string name = 1;
  string id = 2;
  int32 age = 3;
}

2.2 使用安裝好的編譯工具編譯接

參數(shù)意義:--go_out=. 使用上述安裝的 protoc-gen-go 插件,生成文件到當前目錄,--go-triple_out=.使用上述安裝的 protoc-gen-go-triple 插件,生成文件到當前目錄。

protoc --go_out=. --go-triple_out=. ./helloworld.proto

執(zhí)行該指令后,會生成兩個文件,分別是helloworld.pb (包含 proto 結(jié)構) 和 helloworld_triple.pb.go (包含 triple 協(xié)議接口)。

代碼生成和使用方式與 grpc 類似。

3. 開啟一次RPC調(diào)用

建立如下文件目錄:

quickstart
├── api
│   ├── helloworld.pb.go
│   ├── helloworld.proto
│   └── helloworld_triple.pb.go
├── client
│   └── client.go
└── server
    └── server.go

client.go文件:

package main

import (
	"context"
)

import (
	"dubbo.apache.org/dubbo-go/v3/common/logger"
	"dubbo.apache.org/dubbo-go/v3/config"
	_ "dubbo.apache.org/dubbo-go/v3/imports"
)

import (
	"dubbo3-demo/api"
)

var greeterProvider = &api.GreeterClientImpl{}


func init() {
	// validate consumer greeterProvider ptr
	config.SetConsumerService(greeterProvider)
}

func main() {
	// init rootConfig with config api
	rc := config.NewRootConfigBuilder().
		SetConsumer(config.NewConsumerConfigBuilder().
			AddReference("GreeterClientImpl", config.NewReferenceConfigBuilder().
				SetInterface("org.apache.dubbo.UserProvider").
				SetProtocol("tri").
				Build()).
			Build()).
		AddRegistry("zookeeper", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
		Build()

	// start dubbo-go framework with configuration
	if err := config.Load(config.WithRootConfig(rc)); err != nil{
		panic(err)
	}

	// run rpc invocation
	testSayHello()
}

func testSayHello() {
	ctx := context.Background()

	req := api.HelloRequest{
		Name: "laurence",
	}
	user, err := greeterProvider.SayHello(ctx, &req)
	if err != nil {
		panic(err)
	}

	logger.Infof("Receive user = %+v\n", user)
}

server.go文件:

package main

import (
	"context"
)

import (
	"dubbo.apache.org/dubbo-go/v3/common/logger"
	"dubbo.apache.org/dubbo-go/v3/config"
	_ "dubbo.apache.org/dubbo-go/v3/imports"
)

import (
	"dubbo3-demo/api"
)

func main() {
	config.SetProviderService(&GreeterProvider{})

	rc := config.NewRootConfigBuilder().
		SetProvider(config.NewProviderConfigBuilder().
			AddService("GreeterProvider", config.NewServiceConfigBuilder().
				SetInterface("org.apache.dubbo.UserProvider").
				Build()).
			Build()).
		AddProtocol("tripleProtocolKey", config.NewProtocolConfigBuilder().
			SetName("tri").
			Build()).
		AddRegistry("registryKey", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
		Build()

	// start dubbo-go framework with configuration
	if err := config.Load(config.WithRootConfig(rc)); err != nil{
		panic(err)
	}

	select {}
}

type GreeterProvider struct {
	api.UnimplementedGreeterServer
}

func (s *GreeterProvider) SayHelloStream(svr api.Greeter_SayHelloStreamServer) error {
	c, err := svr.Recv()
	if err != nil {
		return err
	}
	logger.Infof("Dubbo-go GreeterProvider recv 1 user, name = %s\n", c.Name)
	c2, err := svr.Recv()
	if err != nil {
		return err
	}
	logger.Infof("Dubbo-go GreeterProvider recv 2 user, name = %s\n", c2.Name)
	c3, err := svr.Recv()
	if err != nil {
		return err
	}
	logger.Infof("Dubbo-go GreeterProvider recv 3 user, name = %s\n", c3.Name)

	if err:= svr.Send(&api.User{
		Name: "hello " + c.Name,
		Age:  18,
		Id:   "123456789",
	}); err != nil{
		return err
	}
	if err := svr.Send(&api.User{
		Name: "hello " + c2.Name,
		Age:  19,
		Id:   "123456789",
	}); err != nil{
		return err
	}
	return nil
}

func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
	logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
	return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
}

quickstart 目錄下,執(zhí)行 go mod init dubbo3-demo

如果彈出 go mod detected 彈窗,需要勾選 Enable Go modules integration ,設置GOPROXY,保證 Goland 可以正確拉取到依賴,方便開發(fā)?;蛘咴谠O置中按照如下位置設置。

命令行執(zhí)行 export GOPROXY="https://goproxy.cn" 設置PROXY

執(zhí)行go mod tidy

您可以看到最新的框架依賴

module dubbo3-demo

go 1.17

require (
	dubbo.apache.org/dubbo-go/v3 v3.0.0-rc4-1
	github.com/dubbogo/grpc-go v1.42.5-triple
	github.com/dubbogo/triple v1.1.3
	github.com/golang/protobuf v1.5.2
	google.golang.org/protobuf v1.27.1
)

require (
...
)

最終文件目錄:

quickstart
├── api
│   ├── helloworld.pb.go
│   ├── helloworld.proto
│   └── helloworld_triple.pb.go
├── client
│   └── client.go
├── go.mod
├── go.sum
└── server
    └── server.go

先后啟動服務端和客戶端(在 server 和 client 文件夾下分別執(zhí)行 go run .) , 可在客戶端看到輸出:

 Receive user = {Name:Hello laurence Id:12345 Age:21 ...}

獲得調(diào)用結(jié)果成功

4. 更多

細心的讀者可以發(fā)現(xiàn),以上例子編寫的的服務端可以接受來自客戶端的普通RPC、流式RPC調(diào)用請求。目前只編寫了普通調(diào)用的Client,讀者可以根據(jù)samples庫中的例子來嘗試編寫流式客戶端發(fā)起調(diào)用。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號