go doudou开发gRPC服务快速上手实现详解

目录
  • 引言
  • 准备
    • 安装go
  • 安装gRPC编译器和插件
    • 安装编译器protoc
    • 安装插件
  • 安装go-doudou
  • 初始化项目
  • 定义服务
  • 生成代码
  • 实现接口
  • 测试服务
  • 总结

引言

go-doudou从v2版本开始已经支持开发gRPC服务。开发流程跟v1版本是一致的,都是先在svc.go文件里的interface里定义方法,然后执行go-doudou代码生成命令生成代码,最后你再写自定义业务逻辑实现接口。go-doudou的学习曲线非常平滑,对新手极其友好,特别是具有其他编程语言开发背景的开发者,比如从Java、Nodejs或是Python转过来的。go-doudou非常易学,但是却能带来极高的生产力。

本文中我将通过一个小demo来向各位同学展示开发流程是什么样的,同时也提供了一些最佳实践。我们将采用go-doudou开发一个通过最大余额法算法解决计算占比不等于100%的问题的gRPC服务,然后通过测试看一下效果。

完整代码托管在github:github.com/unionj-clou…

准备

安装go

go-doudou仅支持go 1.16及以上版本。

安装gRPC编译器和插件

安装编译器protoc

安装Protobuf编译器protoc,可参考官方文档,这里贴一下常见操作系统下的安装命令:

  • Ubuntu系统:
$ apt install -y protobuf-compiler
$ protoc --version  # 确保安装v3及以上版本

Mac系统,需要先安装Homebrew:

$ brew install protobuf
$ protoc --version  # 确保安装v3及以上版本

Windows系统,或者Mac系统安装Homebrew失败,需从github下载安装包,解压后,自行配置环境变量。

安装插件

  • 安装插件:
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
  • 配置环境变量:
$ export PATH="$PATH:$(go env GOPATH)/bin"

最新版本号请跳转 grpc.io/docs/langua… 查找。

安装go-doudou

  • 如果Go版本低于1.17
go get -v github.com/unionj-cloud/go-doudou/v2@v2.0.3
  • 如果Go版本 >= 1.17,推荐采用如下命令全局安装go-doudou命令行工具
go install -v github.com/unionj-cloud/go-doudou/v2@v2.0.3

推荐采用如下命令下载go-doudou作为项目的依赖

go get -v -d github.com/unionj-cloud/go-doudou/v2@v2.0.3

如果遇到410 Gone error报错,请先执行如下命令,再执行上述的安装命令

export GOSUMDB=off

安装完成后,如果遇到go-doudou: command not found报错,请将$HOME/go/bin配置到~/.bash_profile文件里,例如:

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:/usr/local/go/bin
PATH=$PATH:$HOME/go/bin
export PATH

我们可以执行以下命令确认一下安装是否成功:

➜  go-doudou -v
go-doudou version v2.0.3

初始化项目

做完准备工作我们就可以开始coding了。首先我们需要初始化项目。

go-doudou svc init go-stats -m go-doudou-tutorials/go-stats

go-stats是项目的根路径,go-doudou会逐层创建文件夹,底层类似执行unix命令mkdir -p-m 可以设置模块名,这里是go-doudou-tutorials/go-stats

go-doudou会生成以下的项目结构。

➜  go-stats git:(master) ✗ tree -L 2
.
├── Dockerfile
├── go.mod
├── svc.go
└── vo
    └── vo.go
1 directory, 4 files

svc.go文件里已经声明了一个接口,用于定义方法,go-doudou会通过这些方法提供的信息来生成proto文件里的rpc代码。vo包是用来定义go语言结构体的,go-doudou会扫描整个包里声明的所有结构体来生成proto文件里的message代码。

定义服务

下面我们来看一下svc.go文件。

/**
* Generated by go-doudou v2.0.3.
* You can edit it as your need.
*/
package service
import (
	"context"
	"go-doudou-tutorials/go-stats/vo"
)
//go:generate go-doudou svc http -c
//go:generate go-doudou svc grpc
type GoStats interface {
	// You can define your service methods as your need. Below is an example.
	// You can also add annotations here like @role(admin) to add meta data to routes for
	// implementing your own middlewares
	PageUsers(ctx context.Context, query vo.PageQuery) (data vo.PageRet, err error)
}

有两个//go:generate 指令,12行和13行分别是用来生成RESTful和gRPC服务代码的,主要是为了方便执行代码生成命令。如果你用goland的话,你可以像下面的截图所示那样操作界面执行命令。

PageUsers是一个示例,我们删掉它写上我们的方法。

/**
* Generated by go-doudou v2.0.3.
* You can edit it as your need.
 */
package service
import (
	"context"
	"go-doudou-tutorials/go-stats/vo"
)
//go:generate go-doudou svc http -c
//go:generate go-doudou svc grpc
// GoStats is a demo gRPC service developed by go-doudou
type GoStats interface {
	// LargestRemainder implements Largest Remainder Method https://en.wikipedia.org/wiki/Largest_remainder_method
	LargestRemainder(ctx context.Context, payload vo.PercentageReqVo) (data []vo.PercentageRespVo, err error)
}

我们还需要在vo包里声明PercentageReqVo和PercentageRespVo这两个vo结构体。需要注意的是,GoStats接口的方法里出现的结构体类型参数必须声明在vo包里,否则go-doudou获取不到字段信息,就无法在proto文件里生成对应的message。

/**
* Generated by go-doudou v2.0.3.
* You can edit it as your need.
 */
package vo
//go:generate go-doudou name --file $GOFILE
// request vo
type PercentageReqVo struct {
	// key value pairs
	Data []PercentageVo `json:"data"`
	// digit number after dot
	Places int `json:"places"`
}
// key value pair
type PercentageVo struct {
	// number for something
	Value int `json:"value"`
	// unique key for distinguishing something
	Key string `json:"key"`
}
// result vo
type PercentageRespVo struct {
	Value   int     `json:"value"`
	Key     string  `json:"key"`
	Percent float64 `json:"percent"`
	// formatted percentage
	PercentFormatted string `json:"percentFormatted"`
}

第7行的go-doudou name 命令是go-doudou内置的一个小工具,可以一把生成或更新结构体字段后面的json标签,默认是首字母小写的驼峰命名格式。

生成代码

现在我们可以执行go-doudou svc grpc 命令生成proto文件和gRPC相关的服务端、客户端代码了。执行命令后的项目结构如下所示:

➜  go-stats git:(master) ✗ tree -L 3 -a
.
├── .dockerignore
├── .env
├── .gitignore
├── Dockerfile
├── cmd
│   └── main.go
├── config
│   └── config.go
├── db
│   └── db.go
├── go.mod
├── svc.go
├── svcimpl.go
├── transport
│   └── grpc
│       ├── annotation.go
│       ├── gostats.pb.go
│       ├── gostats.proto
│       └── gostats_grpc.pb.go
└── vo
    └── vo.go
13 directories, 16 files

go-doudou为我们生成了一些新的文件夹和文件。

.dockerignore : 用于打包docker镜像的时候忽略**/*.local文件

.env : 配置文件

cmd : 里面有main.go文件

config : 用于将环境变量映射到config结构体

db : 用于建立数据库连接实例,我们这个demo用不到

svcimpl.go : 用于编写自定义的业务逻辑,实现GoStats接口

transport : proto文件和gRPC相关的服务端、客户端代码在这里

在我们实现接口之前,需要执行 go mod tidy 命令来下载依赖。然后我们启动程序,先看一下是否一切正常。

➜  go-stats git:(master) ✗ go run cmd/main.go
2022/11/23 11:07:45 maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined
                           _                    _
                          | |                  | |
  __ _   ___   ______   __| |  ___   _   _   __| |  ___   _   _
 / _` | / _ \ |______| / _` | / _ \ | | | | / _` | / _ \ | | | |
| (_| || (_) |        | (_| || (_) || |_| || (_| || (_) || |_| |
 __, | ___/          __,_| ___/  __,_| __,_| ___/  __,_|
  __/ |
 |___/
2022-11-23 11:07:45 INF ================ Registered Services ================
2022-11-23 11:07:45 INF +------------------------------------------+----------------------+
2022-11-23 11:07:45 INF |                 SERVICE                  |         RPC          |
2022-11-23 11:07:45 INF +------------------------------------------+----------------------+
2022-11-23 11:07:45 INF | grpc.reflection.v1alpha.ServerReflection | ServerReflectionInfo |
2022-11-23 11:07:45 INF | go_stats.GoStatsService                  | LargestRemainderRpc  |
2022-11-23 11:07:45 INF +------------------------------------------+----------------------+
2022-11-23 11:07:45 INF ===================================================
2022-11-23 11:07:45 INF Grpc server is listening at [::]:50051
2022-11-23 11:07:45 INF Grpc server started in 1.110168ms

go-doudou依赖了 go.uber.org/automaxprocs 这个包来根据我们给容器做的资源限制来设置处理器P的数量,所以会有第2行的日志输出。

我们再看一下transport/grpc/gostats.proto文件。

/**
* Generated by go-doudou v2.0.3.
* Don't edit!
*
* Version No.: v20221123
*/
syntax = "proto3";
package go_stats;
option go_package = "go-doudou-tutorials/go-stats/transport/grpc";
message LargestRemainderRpcResponse {
  repeated PercentageRespVo data = 1 [json_name="data"];
}
// request vo
message PercentageReqVo {
  // key value pairs
  repeated PercentageVo data = 1 [json_name="data"];
  // digit number after dot
  int32 places = 2 [json_name="places"];
}
// result vo
message PercentageRespVo {
  int32 value = 1 [json_name="value"];
  string key = 2 [json_name="key"];
  double percent = 3 [json_name="percent"];
  // formatted percentage
  string percentFormatted = 4 [json_name="percentFormatted"];
}
// key value pair
message PercentageVo {
  // number for something
  int32 value = 1 [json_name="value"];
  // unique key for distinguishing something
  string key = 2 [json_name="key"];
}
service GoStatsService {
  // LargestRemainder implements Largest Remainder Method https://en.wikipedia.org/wiki/Largest_remainder_method
  rpc LargestRemainderRpc(PercentageReqVo) returns (LargestRemainderRpcResponse);
}

如代码所示,所有message里的字段名称都是首字母小写的驼峰命名。其实Protobuf官方给出的规范是下划线分隔单词的蛇形命名。因为我们vo包里的结构体的字段的json标签是首字母小写的驼峰命名,所以我们这里为了保持一致,就没有遵循规范。保持一致的作用是我们后面如果需要将protoc生成的结构体转成vo包里的结构体的时候,可以直接用json序列化反序列化的方式做深拷贝,而无需手工一个个字段去赋值。如果你担心这个办法的性能开销而选择其他办法的话,就无所谓了。

go-doudou在生成proto文件的时候会将方法出参中的除error类型之外的其他类型参数都封装到一个单独的message中,如这里的LargestRemainderRpcResponse。

go-doudou只支持Protobuf v3。

实现接口

下面我们在svcimpl.go文件中编写我们的业务代码。先看一下现在的代码。

/**
* Generated by go-doudou v2.0.3.
* You can edit it as your need.
 */
package service
import (
	"context"
	"go-doudou-tutorials/go-stats/config"
	pb "go-doudou-tutorials/go-stats/transport/grpc"
)
var _ pb.GoStatsServiceServer = (*GoStatsImpl)(nil)
type GoStatsImpl struct {
	pb.UnimplementedGoStatsServiceServer
	conf *config.Config
}
func (receiver *GoStatsImpl) LargestRemainderRpc(ctx context.Context, request *pb.PercentageReqVo) (*pb.LargestRemainderRpcResponse, error) {
	//TODO implement me
	panic("implement me")
}
func NewGoStats(conf *config.Config) *GoStatsImpl {
	return &GoStatsImpl{
		conf: conf,
	}
}

第13行将*GoStatsImpl类型的nil赋值给pb.GoStatsServiceServer接口类型的_的作用是确保指针类型的GoStatsImpl结构体实例始终都实现pb.GoStatsServiceServer接口。相当于一种约束。

我们可以根据实际需求往GoStatsImpl结构体里声明任何字段来存放各种资源,比如外部服务的客户端,数据库连接,任意的队列或者池等等。这里有一个包级别的工厂方法NewGoStats用来注入各种依赖,创建一个指针类型的GoStatsImpl结构体实例。

接下来我们实现LargestRemainderRpc方法。因为go-doudou不支持grpc-gateway和grpc-web等RESTful转gRPC的转发器,如果需要在一套程序同时支持RESTful服务和gRPC服务,go-doudou提供的解决方案是分别绑定两个端口,启动http服务器和gRPC服务器,复用一套业务逻辑代码,所以如果考虑后期可能需要加上RESTful支持的话,推荐不要直接实现pb.GoStatsServiceServer接口,而是先实现GoStats接口,然后再调用GoStats接口的实现方法去实现pb.GoStatsServiceServer接口。这样就实现了业务逻辑代码的复用。

我个人倾向于不管现在和以后是否需要支持RESTful,都先执行 go-doudou svc http -c 命令生成RESTful相关代码。

现在的项目结构是这样的:

➜  go-stats git:(master) ✗ tree -L 3
.
├── Dockerfile
├── client
│   ├── client.go
│   ├── clientproxy.go
│   └── iclient.go
├── cmd
│   └── main.go
├── config
│   └── config.go
├── db
│   └── db.go
├── go.mod
├── go.sum
├── gostats_openapi3.go
├── gostats_openapi3.json
├── svc.go
├── svcimpl.go
├── transport
│   ├── grpc
│   │   ├── annotation.go
│   │   ├── gostats.pb.go
│   │   ├── gostats.proto
│   │   └── gostats_grpc.pb.go
│   └── httpsrv
│       ├── handler.go
│       ├── handlerimpl.go
│       └── middleware.go
└── vo
    └── vo.go
8 directories, 21 files

httpsrv包里是http路由以及http请求解析和返回数据序列化相关的代码。我们可以删掉也可以先留着。我们看一下svcimpl.go文件有什么变化。

/**
* Generated by go-doudou v2.0.3.
* You can edit it as your need.
*/
package service
import (
    "context"
    "go-doudou-tutorials/go-stats/config"
    pb "go-doudou-tutorials/go-stats/transport/grpc"
    "go-doudou-tutorials/go-stats/vo"
    "github.com/brianvoe/gofakeit/v6"
)
var _ GoStats = (*GoStatsImpl)(nil)
var _ pb.GoStatsServiceServer = (*GoStatsImpl)(nil)
type GoStatsImpl struct {
    pb.UnimplementedGoStatsServiceServer
    conf *config.Config
}
func (receiver *GoStatsImpl) LargestRemainderRpc(ctx context.Context, request *pb.PercentageReqVo) (*pb.LargestRemainderRpcResponse, error) {
    //TODO implement me
    panic("implement me")
}
func NewGoStats(conf *config.Config) *GoStatsImpl {
    return &GoStatsImpl{
        conf: conf,
    }
}
func (receiver *GoStatsImpl) LargestRemainder(ctx context.Context, payload vo.PercentageReqVo) (data []vo.PercentageRespVo, err error) {
    var _result struct {
        Data []vo.PercentageRespVo
    }
    _ = gofakeit.Struct(&_result)
    return _result.Data, nil
}

第17行和第3642行是新生成的代码。第17行的作用是确保指针类型的GoStatsImpl始终实现GoStats接口。第3642行是需要我们实现的打桩代码。

下面我们编写业务逻辑代码:

func (receiver *GoStatsImpl) LargestRemainder(ctx context.Context, payload vo.PercentageReqVo) (data []vo.PercentageRespVo, err error) {
    if len(payload.Data) == 0 {
        return
    }
    input := make([]numberutils.Percentage, 0)
    for _, item := range payload.Data {
        input = append(input, numberutils.Percentage{
            Value: item.Value,
            Data:  item.Key,
        })
    }
    numberutils.LargestRemainder(input, int32(payload.Places))
    for _, item := range input {
        data = append(data, vo.PercentageRespVo{
            Value:            item.Value,
            Key:              item.Data.(string),
            Percent:          item.Percent,
            PercentFormatted: item.PercentFormatted,
        })
    }
    return
}

go-doudou在 github.com/unionj-cloud/go-doudou/v2/toolkit/numberutils 包里提供了一个工具函数LargestRemainder。此处略过具体的算法实现。

现在我们可以通过复用LargestRemainder方法里的代码实现LargestRemainderRpc方法。

func (receiver *GoStatsImpl) LargestRemainderRpc(ctx context.Context, request *pb.PercentageReqVo) (*pb.LargestRemainderRpcResponse, error) {
	var payload vo.PercentageReqVo
	copier.DeepCopy(request, &payload)
	data, err := receiver.LargestRemainder(ctx, payload)
	if err != nil {
		return nil, err
	}
	var ret pb.LargestRemainderRpcResponse
	err = copier.DeepCopy(data, &ret.Data)
	if err != nil {
		return nil, err
	}
	return &ret, nil
}

我们无需手工编写pb.PercentageReqVo转vo.PercentageReqVo和[]vo.PercentageRespVo转[]*pb.PercentageRespVo的代码,直接用 github.com/unionj-cloud/go-doudou/v2/toolkit/copier 包里的DeepCopy函数做深拷贝即可。

测试服务

因为我们生成了新的代码,导入了新的依赖,所以我们需要再执行一下 go mod tidy 。然后我们启动服务,测试一下效果。

➜  go-stats git:(master) ✗ go mod tidy && go run cmd/main.go
2022/11/23 13:18:13 maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined
                           _                    _
                          | |                  | |
  __ _   ___   ______   __| |  ___   _   _   __| |  ___   _   _
 / _` | / _ \ |______| / _` | / _ \ | | | | / _` | / _ \ | | | |
| (_| || (_) |        | (_| || (_) || |_| || (_| || (_) || |_| |
 __, | ___/          __,_| ___/  __,_| __,_| ___/  __,_|
  __/ |
 |___/
2022-11-23 13:18:13 INF ================ Registered Services ================
2022-11-23 13:18:13 INF +------------------------------------------+----------------------+
2022-11-23 13:18:13 INF |                 SERVICE                  |         RPC          |
2022-11-23 13:18:13 INF +------------------------------------------+----------------------+
2022-11-23 13:18:13 INF | go_stats.GoStatsService                  | LargestRemainderRpc  |
2022-11-23 13:18:13 INF | grpc.reflection.v1alpha.ServerReflection | ServerReflectionInfo |
2022-11-23 13:18:13 INF +------------------------------------------+----------------------+
2022-11-23 13:18:13 INF ===================================================
2022-11-23 13:18:13 INF Grpc server is listening at [::]:50051
2022-11-23 13:18:13 INF Grpc server started in 1.001238ms

我个人倾向于采用 evans 去帮助测试和调试gRPC服务。

➜  go-stats git:(master) ✗ evans -r repl -p 50051
  ______
 |  ____|
 | |__    __   __   __ _   _ __    ___
 |  __|   \ \ / /  / _. | | '_ \  / __|
 | |____   \ V /  | (_| | | | | | __ \
 |______|   _/    __,_| |_| |_| |___/
 more expressive universal gRPC client
go_stats.GoStatsService@127.0.0.1:50051> show service
+----------------+---------------------+-----------------+-----------------------------+
|    SERVICE     |         RPC         |  REQUEST TYPE   |        RESPONSE TYPE        |
+----------------+---------------------+-----------------+-----------------------------+
| GoStatsService | LargestRemainderRpc | PercentageReqVo | LargestRemainderRpcResponse |
+----------------+---------------------+-----------------+-----------------------------+
go_stats.GoStatsService@127.0.0.1:50051> service GoStatsService
go_stats.GoStatsService@127.0.0.1:50051> call LargestRemainderRpc
<repeated> data::value (TYPE_INT32) => 20
<repeated> data::key (TYPE_STRING) => apple
<repeated> data::value (TYPE_INT32) => 30
<repeated> data::key (TYPE_STRING) => banana
<repeated> data::value (TYPE_INT32) => 40
<repeated> data::key (TYPE_STRING) => pear
<repeated> data::value (TYPE_INT32) =>
places (TYPE_INT32) => 2
{
  "data": [    {      "key": "apple",      "percent": 22.22,      "percentFormatted": "22.22%",      "value": 20    },    {      "key": "banana",      "percent": 33.33,      "percentFormatted": "33.33%",      "value": 30    },    {      "key": "pear",      "percent": 44.45,      "percentFormatted": "44.45%",      "value": 40    }  ]
}

我们输入apple 20kg,banana 30kg,pear 40kg和保留2位小数,然后得到了我们期望的结果:22.22 + 33.33 + 44.45 = 100。

总结

本文我们学到了采用go-doudou微服务框架开发gRPC服务的基本技能,同时我们需要知道go-doudou不仅可以帮助开发者轻松地开发gRPC服务,它还包含了一套完善的服务治理方案帮助开发者打造完整的微服务系统。go-doudou虽然开源时间不长,但是非常有发展潜力,希望越来越多的开发者可以加入进来,更多关于go doudou开发gRPC服务的资料请关注我们其它相关文章!

(0)

相关推荐

  • Go gRPC服务进阶middleware使用教程

    目录 前言 go-grpc-middleware简介 grpc_zap日志记录 grpc_auth认证 grpc_recovery恢复 总结 前言 之前介绍了gRPC中TLS认证和自定义方法认证,最后还简单介绍了gRPC拦截器的使用.gRPC自身只能设置一个拦截器,所有逻辑都写一起会比较乱.本篇简单介绍go-grpc-middleware的使用,包括grpc_zap.grpc_auth和grpc_recovery. go-grpc-middleware简介 go-grpc-middleware封

  • Go gRPC进阶教程gRPC转换HTTP

    目录 前言 gRPC转成HTTP 编写和编译proto 服务端代码修改 使用postman测试 生成swagger文档 把swagger-ui转成Go代码,备用 对外提供swagger-ui 在swagger中配置bearer token 验证测试 总结 前言 我们通常把RPC用作内部通信,而使用Restful Api进行外部通信.为了避免写两套应用,我们使用grpc-gateway把gRPC转成HTTP.服务接收到HTTP请求后,grpc-gateway把它转成gRPC进行处理,然后以JSON

  • Go Grpc Gateway兼容HTTP协议文档自动生成网关

    目录 前言 一,grpc-gateway介绍 二,grpc-gateway环境准备 二,编写grpc-gateway服务 四,使用gateway生成swagger文档 五,性能对比 http -> go -> grpc -> go http -> go -> http -> grpc_gateway -> grpc -> go 六,总结 前言 调用,让客户端可以更具自身情况自由选择,服务端工作只需要做一份呢?还别说真还有一个准备好的轮子那就是今天的主角<

  • go doudou开发单体RESTful服务快速上手教程

    目录 引言 需求清单 学习目标 开发环境准备 安装go-doudou 初始化工程 定义接口 生成代码 启动服务 数据库和表结构准备 生成domain和dao层代码 用户注册接口 修改domain PublicSignUp方法实现 Postman测试 用户登录接口 PublicLogIn方法实现 Postman测试 上传头像接口 修改domain 修改.env配置 JWT校验中间件 UploadAvatar方法实现 下载头像接口 GetPublicDownloadAvatar方法实现 用户详情接口

  • go doudou应用中使用枚举类型教程示例

    目录 go语言支持语法自己实现枚举类型 结构体类型示例 接口请求参数示例 go语言支持语法自己实现枚举类型 我们都知道go语言没有原生的枚举类型,但是做业务开发有些时候没有枚举类型确实不方便前后端联调.我们可以通过go语言支持的语法自己实现枚举类型.请看以下示例代码和注释说明: // 首先定义一个int类型别名,新类型名称就是枚举类型名称 type KeyboardLayout int // 然后定义若干常量,作为枚举值 // 第一个常量是默认值 const ( UNKNOWN Keyboard

  • go doudou应用中使用注解示例详解

    目录 快速上手 准备 初始化工程 设计业务接口 生成代码 下载依赖 Auth中间件 修改main函数 启动服务 测试效果 注解实现原理 总结 快速上手 我们都知道go语言没有原生的注解,但是做业务开发有些时候没有注解确实不方便.go-doudou通过go语言标准库ast/parser实现了对注解的支持.b站配套视频教程地址:[golang] go-doudou微服务框架入门03-如何使用注解,如果喜欢看视频,可直接跟视频上手实践. 我们通过一个简单的基于go-doudou开发的服务来演示用法和效

  • Golang gRPC HTTP协议转换示例

    gRPC HTTP协议转换 正当有这个需求的时候,就看到了这个实现姿势.源自coreos的一篇博客,转载到了grpc官方博客gRPC with REST and Open APIs. etcd3改用grpc后为了兼容原来的api,同时要提供http/json方式的API,为了满足这个需求,要么开发两套API,要么实现一种转换机制,他们选择了后者,而我们选择跟随他们的脚步. 他们实现了一个协议转换的网关,对应github上的项目grpc-gateway,这个网关负责接收客户端请求,然后决定直接转发

  • Go gRPC服务proto数据验证进阶教程

    前言 上篇介绍了go-grpc-middleware的grpc_zap.grpc_auth和grpc_recovery使用,本篇将介绍grpc_validator,它可以对gRPC数据的输入和输出进行验证. 创建proto文件,添加验证规则 这里使用第三方插件go-proto-validators自动生成验证规则. go get github.com/mwitkow/go-proto-validators 1.新建simple.proto文件 syntax = "proto3"; pa

  • go doudou开发gRPC服务快速上手实现详解

    目录 引言 准备 安装go 安装gRPC编译器和插件 安装编译器protoc 安装插件 安装go-doudou 初始化项目 定义服务 生成代码 实现接口 测试服务 总结 引言 go-doudou从v2版本开始已经支持开发gRPC服务.开发流程跟v1版本是一致的,都是先在svc.go文件里的interface里定义方法,然后执行go-doudou代码生成命令生成代码,最后你再写自定义业务逻辑实现接口.go-doudou的学习曲线非常平滑,对新手极其友好,特别是具有其他编程语言开发背景的开发者,比如

  • C语言编程题杨氏矩阵算法快速上手示例详解

    目录 题目概要 一.解题思路 二.具体代码 题目概要 有一个数字矩阵,矩阵的每行从左到右都是递增的,矩阵从上到下都是递增的,请编写程序在这样的矩阵中查找某个数字是否存在? 一.解题思路 对于查找一个数组中元素是否存在,很多同学第一想法就是从头到尾遍历一遍.这样的想法优点是代码简单且无脑容易上手,但是这样的缺点也很明显,比如是m *n的数组,你从头到尾遍历,最坏情况要找m *n次.题目给的相关条件比如从左向右递增,从上向下递增你也完全没有使用,这样的暴力求解显然不是我们想看到的 我们来介绍一种方法

  • Golang开发gRPC服务入门介绍

    目录 1.安装protoc 2.安装protoc的Golang gRPC插件 3.编写proto文件 4.生成gRPC代理代码 5.编写gRPC服务端程序 6.编写gRPC客户端程序 7.运行程序 gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. Golang开发gRPC应用程序的套路也已经很清晰,这篇文章就来做一个简单的介绍,算是入门. 1.安

  • Go语言程序开发gRPC服务

    目录 前言 介绍 入门 proto server client 流方式 proto server client 验证器 proto Token 认证 认证函数: 拦截器: 初始化: 实现接口: 连接: 单向证书认证 生成证书 gRPC 代码 双向证书认证 生成带 SAN 的证书 gRPC 代码 Python 客户端 总结 前言 gRPC 这项技术真是太棒了,接口约束严格,性能还高,在 k8s 和很多微服务框架中都有应用. 作为一名程序员,学就对了. 之前用 Python 写过一些 gRPC 服务

  • Java微服务开发之Swagger详解

    目录 一.Swagger的作用和概念 1.Swagger 的优势 2.SwaggerUI 特点 2.SpringBoot集成Swagger 3.配置Swagger 4.实体配置 5.其他皮肤 一.Swagger的作用和概念 ​ 官方地址:https://swagger.io/ ​ Swagger 是一个规范且完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务以及 集成Swagger自动生成API文档. ​ Swagger 的目标是对 REST API 定义一个标准且和

  • 微服务架构拆分策略详解

    目录 1 微服务迁移准备 2 微服务颗粒的拆分策略 2.1 基于业务逻辑拆分 2.1.1 领域模型拆分 2.1.2 用户群体拆分 2.2 基于可扩展拆分 2.3 基于可靠性拆分 2.3.1 核心模块拆分 2.3.2 主次链路拆分 2.4 基于性能需求拆分 3 总结拆分原则 微服务架构及其演进史 微服务全景架构全面瓦解 前面我们学习了微服务的全景架构,了解到相对于传统单体架构,微服务的优势,以及系统服务化的发展趋势. 对于新启动的项目,我们在权衡之后可以大方的使用微服务架构.但其实大部分情况下,我

  • hibernate4快速入门实例详解

    Hibernate是什么 Hibernate是一个轻量级的ORMapping框架 ORMapping原理(Object RelationalMapping) ORMapping基本对应规则: 1:类跟表相对应 2:类的属性跟表的字段相对应 3:类的实例与表中具体的一条记录相对应 4:一个类可以对应多个表,一个表也可以对应对个类 5:DB中的表可以没有主键,但是Object中必须设置主键字段 6:DB中表与表之间的关系(如:外键)映射成为Object之间的关系 7:Object中属性的个数和名称可

  • JSP开发之生成图片验证码技术的详解

    JSP开发之生成图片验证码技术的详解 我们在网页注册用户时,常常会需要格根据图片给的图片验证码把验证码输进去.那么我们今天就来学习这个. 简单来说分为三步骤: 1.底层用Java实现生成验证码图片 2.通过配置文件调用实现Java生成片 3.通过HTML技术把图片显示到网页 首先是最底层Java生成图片代码 package cn.hncu.servlets; import java.awt.Color; import java.awt.Font; import java.awt.Graphics

  • 使用Vue开发动态刷新Echarts组件的教程详解

    需求背景:dashboard作为目前企业中后台产品的"门面",如何更加实时.高效.炫酷的对统计数据进行展示,是值得前端开发工程师和UI设计师共同思考的一个问题.今天就从0开始,封装一个动态渲染数据的Echarts折线图组件,抛砖引玉,一起来思考更多有意思的组件. 准备工作 项目结构搭建 因为生产需要(其实是懒),所以本教程使用了 ==vue-cli==进行了项目的基础结构搭建. npm install -g vue-cli vue init webpack vue-charts cd

  • spring boot微服务自定义starter原理详解

    这篇文章主要介绍了spring boot微服务自定义starter原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用spring boot开发微服务后,工程的数量大大增加(一定要按照领域来切,不要一个中间件客户端包一个),让各个jar从开发和运行时自包含成了一个重要的内容之一.spring boot starter就可以用来解决该问题(没事启动时别依赖于applicationContext.getBean获取bean进行处理,依赖关系

随机推荐