最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 2/3

来源:博客园

基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 1/3

基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 2/3


(资料图片)

基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 3/3

项目地址:https://github.com/janrs-io/Jgrpc

转载请注明来源:https://janrs.com/ugj7

在上一部分中,我们创建了微服务的目录结构并实现了微服务pongservice

这部分我们继续实现一个名为pingservice的微服务,访问上一节已经部署好的pongservice微服务。

创建一个新的微服务非常简单,只需复制之前创建的pongservice微服务,然后做一些小改动。

项目结构

这部分最终的目录结构如下:

pingservice├── buf.gen.yaml├── cmd│ ├── main.go│ └── server│     ├── grpc.go│     ├── http.go│     ├── run.go│     ├── wire.go│     └── wire_gen.go├── config│ ├── client.go│ ├── config.go│ └── config.yaml├── genproto│ └── v1│     ├── gw│     │ └── pingservice.pb.gw.go│     ├── pingservice.pb.go│     └── pingservice_grpc.pb.go├── go.mod├── go.sum├── proto│ ├── buf.lock│ ├── buf.yaml│ └── v1│     ├── pingservice.proto│     └── pingservice.yaml└── service    ├── client.go    └── server.go9 directories, 21 files

开始

复制

src目录下执行如下复制命令:

cp -R pongservice pingservice

删除 wire_gen.go

删除 pingservice/cmd/server目录中的 wire_gen.go文件。

修改 go.mod module

修改go.mod文件的模块,如下代码所示:

module github.com/janrs-io/Jgrpc/src/pingservice

生成 proto

删除pingservice/proto/v1目录下的pongservice.protopongservice.yaml文件以及整个genproto文件夹。

然后重新创建pingservice.protopingservice.yaml文件,代码如下:

pingservice.protocode:

syntax = "proto3";package proto.v1;option go_package = "github.com/janrs-io/Jgrpc/src/pingservice/genproto/v1";service PingService {  rpc Ping(PingRequest) returns(PingResponse){}}message PingRequest {  string msg = 1 ;}message PingResponse {  string msg = 1;}

pingservice.yamlcode:

type: google.api.Serviceconfig_version: 3http:  rules:    - selector: proto.v1.PingService.Ping      get: /ping.v1.ping

修改pingservice目录下的 buf.gen.yaml文件。 修改后的完整代码如下:

version: v1plugins:  - plugin: go    out: genproto/v1    opt:      - paths=source_relative  - plugin: go-grpc    out: genproto/v1    opt:      - paths=source_relative  - plugin: grpc-gateway    out: genproto/v1/gw    opt:      - paths=source_relative      - grpc_api_configuration=proto/v1/pingservice.yaml      - standalone=true

pingservice目录下执行以下命令生成 proto文件:

buf generate proto/v1

执行命令后,将重新生成genproto目录,并自动创建*pb.go文件。

修改 import 路径和所有代码

检查所有文件的导入,将导入路径的pongservice修改为pingservice

将所有代码的Pong/pong改为Ping/ping,直到没有错误为止。

修改 config.yaml

修改 config目录下的config.yaml文件。将 grpc的服务器端口更改为 50052,将 http的服务器端口更改为 9002。将 grpc的服务名改为ping-grpc,将 http的服务名改为ping-http

修改后的完整代码如下:

# grpc configgrpc:  host: ""  port: ":50052"  name: "ping-grpc"# http confighttp:  host: ""  port: ":9002"  name: "ping-http"

生成 generate inject

pingservice目录中执行以下 wire命令以重新生成依赖注入文件:

wire ./...

引入 pongservier 服务的 go.mod

我们要在 pingservice这个微服务中访问 pongservicegrpc服务,所以需要导入 pongservicego.mod

修改pingservice目录下的go.mod文件,添加导入pongservice的代码,如下:

module github.com/janrs-io/Jgrpc/src/pingservicego 1.19replace (pongservice => ../pongservice)require (pongservice v0.0.0github.com/google/wire v0.5.0github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2github.com/spf13/viper v1.15.0google.golang.org/grpc v1.54.0google.golang.org/protobuf v1.30.0)// the other required package...

修改 config.yaml

修改pingservice/config目录下的config.yaml文件,添加如下代码:

# service clientclient:  pong: ":50051"

修改后的完整代码如下:

# grpc configgrpc:  host: ""  port: ":50052"  name: "ping-grpc"# http confighttp:  host: ""  port: ":9002"  name: "ping-http"# service clientclient:  pong: ":50051"

生成 client.go

pingservice/config目录下生成client.go文件,添加如下代码:

package config// Client Client service configtype Client struct {Pong string `json:"pong" yaml:"pong"`}

修改 config.go

Config结构体中添加一个 Client字段,代码如下:

Client Client `json:"client" yaml:"client"`

修改后的完整代码如下:

package configimport ("net/http""github.com/spf13/viper""google.golang.org/grpc")// Config Service configtype Config struct {Grpc   Grpc   `json:"grpc" yaml:"grpc"`Http   Http   `json:"http" yaml:"http"`Client Client `json:"client" yaml:"client"`}// NewConfig Initial service"s configfunc NewConfig(cfg string) *Config {if cfg == "" {panic("load config file failed.config file can not be empty.")}viper.SetConfigFile(cfg)// Read config fileif err := viper.ReadInConfig(); err != nil {panic("read config failed.[ERROR]=>" + err.Error())}conf := &Config{}// Assign the overloaded configuration to the globalif err := viper.Unmarshal(conf); err != nil {panic("assign config failed.[ERROR]=>" + err.Error())}return conf}// Grpc Grpc server configtype Grpc struct {Host   string `json:"host" yaml:"host"`Port   string `json:"port" yaml:"port"`Name   string `json:"name" yaml:"name"`Server *grpc.Server}// Http Http server configtype Http struct {Host   string `json:"host" yaml:"host"`Port   string `json:"port" yaml:"port"`Name   string `json:"name" yaml:"name"`Server *http.Server}

修改 client.go

修改pingservice/service目录下的client.go文件,添加如下代码:

// NewPongClient New pong service clientfunc NewPongClient(conf *config.Config) (pongclientv1.PongServiceClient, error) {ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()conn, err := grpc.DialContext(ctx, conf.Client.Pong, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {fmt.Println("dial auth server failed.[ERROR]=>" + err.Error())return nil, err}client := pongclientv1.NewPongServiceClient(conn)return client, nil}

修改后的完整代码如下:

package serviceimport ("context""fmt""time""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""github.com/janrs-io/Jgrpc/src/pingservice/config"v1 "github.com/janrs-io/Jgrpc/src/pingservice/genproto/v1"pongclientv1 "github.com/janrs-io/Jgrpc/src/pongservice/genproto/v1")// NewClient New service"s clientfunc NewClient(conf *config.Config) (v1.PingServiceClient, error) {serverAddress := conf.Grpc.Host + conf.Grpc.Portctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()conn, err := grpc.DialContext(ctx, serverAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {return nil, err}client := v1.NewPingServiceClient(conn)return client, nil}// NewPongClient New pong service clientfunc NewPongClient(conf *config.Config) (pongclientv1.PongServiceClient, error) {ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()conn, err := grpc.DialContext(ctx, conf.Client.Pong, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {fmt.Println("dial auth server failed.[ERROR]=>" + err.Error())return nil, err}client := pongclientv1.NewPongServiceClient(conn)return client, nil}

修改 server.go

修改pingservice/service目录下的server.go文件,修改后的完整代码如下:

package serviceimport ("context""google.golang.org/grpc/grpclog""github.com/janrs-io/Jgrpc/src/pingservice/config"v1 "github.com/janrs-io/Jgrpc/src/pingservice/genproto/v1"pongclientv1 "github.com/janrs-io/Jgrpc/src/pongservice/genproto/v1")// Server Server structtype Server struct {v1.UnimplementedPingServiceServerpingClient v1.PingServiceClientpongClient pongclientv1.PongServiceClientconf       *config.Config}// NewServer New service grpc serverfunc NewServer(conf *config.Config,pingClient v1.PingServiceClient,pongClient pongclientv1.PongServiceClient,) v1.PingServiceServer {return &Server{pingClient: pingClient,pongClient: pongClient,conf:       conf,}}func (s *Server) Ping(ctx context.Context, req *v1.PingRequest) (*v1.PingResponse, error) {pongReq := &pongclientv1.PongRequest{Msg: "request from ping service"}pongResp, err := s.pongClient.Pong(ctx, pongReq)if err != nil {grpclog.Error("connect pong failed.[ERROR]=>" + err.Error())return nil, err}return &v1.PingResponse{Msg: "response ping msg:" + req.Msg + " and msg from pong service is: " + pongResp.Msg,}, nil}

修改 wire.go

修改pingservice/cmd/serverwire.go文件,添加service.NewPongClient依赖注入。 代码如下:

service.NewPongClient

修改后的完整代码如下:

//go:build wireinject// +build wireinjectpackage serverimport ("github.com/google/wire""github.com/janrs-io/Jgrpc/src/pingservice/config"v1 "github.com/janrs-io/Jgrpc/src/pingservice/genproto/v1""github.com/janrs-io/Jgrpc/src/pingservice/service")// InitServer Inject service"s componentfunc InitServer(conf *config.Config) (v1.PingServiceServer, error) {wire.Build(service.NewPongClient,service.NewClient,service.NewServer,)return &service.Server{}, nil}

pingservice目录下执行以下 wire命令重新生成依赖注入文件:

如果出现 go.mod引入错误,只需在 pingservice目录中再次运行 go mod tidy

wire ./...

启动 service

分别在pongservice目录和pingservice目录下执行go run命令。

go run cmd/main.go

在浏览器中输入以下请求地址:

127.0.01:9002/ping.v1.ping?msg=best practice

一切正确的情况下返回以下 json 数据:

{    "msg": "response ping msg:best practice and msg from pong service is: response pong msg:request from ping service"}

总结

这部分我们新建一个 pingservice微服务,实现访问 pongservicegrpc服务。

相信通过这两次创建微服务的简单尝试,你一定觉得基于GoGrpc开发微服务并不难。

在下一部分中,我们将利用 Jenkins/Gitlab/HarborKubernets/Istio进行 devopsCICD部署。

转载请注明来源:https://janrs.com/ugj7

关键词: