内容简介:微服务想必大家都不陌生了。刚接触到示例代码通过目录可以看到这里使用了
微服务想必大家都不陌生了。刚接触到 golang ,那么在 golang 中怎么使用微服务呢。这里使用 gRRC 框架写了一个简单的例子。
环境要求
- go>=1.13; set GO111MODULE=on
- 安装 protoc
- 安装 Protoc plugin-go
示例代码 iris-grpc-example
项目结构
iris-grpc-example
│ .gitignore
│ go.mod
│ go.sum
│ README.md
│
├─proto
│ README.md
│ servers.pb.go
│ servers.proto
│
└─servers
main.go
services.go
通过目录可以看到这里使用了 go mod ,当前 golang 版本 1.13 。
proto
使用 Protobuf 定义了通信的IDL,可以理解为 rpc 中接口定义。
-
protocol buf
可扩展的序列化数据结构,在通信协议中使用的比较广泛。比 json 更快,更小。比 xml 更简洁。
servers.proto
syntax = "proto3";
package proto;
message Id {
int32 id=1;
}
message Name {
string name=1;
}
message Age {
int32 age=1;
}
// 用户变量
message User {
int32 id=1;
string name=2;
int32 age=3;
}
// 用户参数
message UserParams{
Name name=1;
Age age=2;
}
// 声明那些方法可以使用rpc
service ServiceSearch{
rpc SaveUser(UserParams) returns (Id){}
rpc UserInfo(Id) returns (User){}
}
简单说明
syntax = "proto3"; 声明了 proto 语法版本。
package 声明包名
message Id {
int32 id=1;
}
接口中使用的变量声明 变量名称: Id ,类型: int32 ,等号后面表示字段编号为 1
service ServiceSearch{
rpc SaveUser(UserParams) returns (Id){}
rpc UserInfo(Id) returns (User){}
}
声明了两个函数 SaveUser(),UserInfo() 是使用 RPC 协议,接收的参数与返回参数分别为什么。
servers.go
该文件是使用 servers.proto 编译生成的
。在完成 servers.proto 之后 在 proto 目录下执行
protoc --go_out=plugins=grpc:. *.proto
Protoc plugin-go grpc
编译命令执行完之后,就会生成 servers.go 。而我们在 go 的模块中实际使用的代码也就是这个文件。
如果有兴趣的同学可以看看里面的代码,主要就是一些参数定义【 我们在proto中所定义的 】,还有一个接口的声明。
......
// ServiceSearchServer is the server API for ServiceSearch service.
type ServiceSearchServer interface {
SaveUser(context.Context, *UserParams) (*Id, error)
UserInfo(context.Context, *Id) (*User, error)
}
// UnimplementedServiceSearchServer can be embedded to have forward compatible implementations.
type UnimplementedServiceSearchServer struct {
}
func (*UnimplementedServiceSearchServer) SaveUser(ctx context.Context, req *UserParams) (*Id, error) {
return nil, status.Errorf(codes.Unimplemented, "method SaveUser not implemented")
}
func (*UnimplementedServiceSearchServer) UserInfo(ctx context.Context, req *Id) (*User, error) {
return nil, status.Errorf(codes.Unimplemented, "method UserInfo not implemented")
}
func RegisterServiceSearchServer(s *grpc.Server, srv ServiceSearchServer) {
s.RegisterService(&_ServiceSearch_serviceDesc, srv)
}
......
可以看到最后有一个 RegisterServiceSearchServer 注册服务的方法,接受一个 grpc.Server 与一个 ServiceSearchServer 的接口。而我们在 servers/services.go 中,主要就是实现 ServiceSearchServer 这个接口,并通过 RegisterServiceSearchServer 将接口实现的函数注册 rpc 服务中。
servers
rpc 接口的实现与调用
services.go 接口的实现
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"iris-grpc-example/proto"
"log"
"math/rand"
"net"
)
type ServiceSearch struct{}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:9527")
if err != nil {
log.Fatalf("tcp listen failed:%v", err)
}
server := grpc.NewServer()
fmt.Println("services start success")
proto.RegisterServiceSearchServer(server, &ServiceSearch{})
server.Serve(listen)
}
//保存用户
func (Service *ServiceSearch) SaveUser(ctx context.Context, params *proto.UserParams) (*proto.Id, error) {
id := rand.Int31n(10) //随机生成id 模式保存成功
res := &proto.Id{Id: id}
fmt.Printf("username:%s,age:%d\r\n", params.Name, params.Age)
return res, nil
}
func (Service *ServiceSearch) UserInfo(ctx context.Context, id *proto.Id) (*proto.User, error) {
res := &proto.User{Id:id.GetId(),Name:"test",Age:31}
return res, nil
}
- 实现
ServiceSearchServer接口,在代码中声明了一个ServiceSearch来实现了ServiceSearchServer接口。 -
SaveUser,实现了proto中定义的SaveUser方法,需要注意的是这里需要返回两个参,数第一个是我们预先定好的参数,第二个为定义的错误信息。 -
main函数声明当前服务的ip以及端口,并创建了一个grpc server然后通过proto.RegisterServiceSearchServer(server, &ServiceSearch{})将ServiceSearch注册到grpc中
main.go 接口的调用
package main
import (
"context"
"github.com/kataras/iris/v12"
"google.golang.org/grpc"
"iris-grpc-example/proto"
"log"
)
var client proto.ServiceSearchClient
func main() {
app := iris.New()
app.Logger().SetLevel("debug") //debug
app.Handle("GET", "/testSaveUser", saveUser)
app.Handle("GET", "/testUserInfo", userInfo)
app.Run(iris.Addr("127.0.0.1:8080"))
}
func saveUser(ctx iris.Context) {
params := proto.UserParams{}
params.Age = &proto.Age{Age: 31}
params.Name = &proto.Name{Name: "test"}
res, err := client.SaveUser(context.Background(), ¶ms)
if err != nil {
log.Fatalf("client.SaveUser err: %v", err)
}
ctx.JSON(res)
}
func userInfo(ctx iris.Context) {
res, err := client.UserInfo(context.Background(), &proto.Id{Id: 1})
if err != nil {
log.Fatalf("client.userInfo err: %v", err)
}
ctx.JSON(res)
}
func init() {
connect, err := grpc.Dial("127.0.0.1:9527", grpc.WithInsecure())
if err != nil {
log.Fatalln(err)
}
client = proto.NewServiceSearchClient(connect)
}
这里使用了 iris 作为了一个 client 。与传统 http 的区别主要是在
func init() {
connect, err := grpc.Dial("127.0.0.1:9527", grpc.WithInsecure())
if err != nil {
log.Fatalln(err)
}
client = proto.NewServiceSearchClient(connect)
}
这里创建了一个 rpc 的 client 。在使用的时候我们只需要调用 services 里面已经写好的函数即可。
测试
\iris-grpc-example>cd servers
开启服务: go run services.go
开启Client: go run main.go
浏览器访问
http://127.0.0.1:8080/testSaveUser
{
"id": 1
}
http://127.0.0.1:8080/testUserInfo
{
"id": 1,
"name": "test",
"age": 31
}
期待一起交流
以上所述就是小编给大家介绍的《go-gRPC 初体验》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 降低云游戏延迟优化云游戏体验:贝塞斯达推出Orion技术,还公布了免费体验计划
- PyTorch 初体验
- indexedDB 初体验
- golang爬虫初体验
- Netty 入门初体验
- Ansible初体验
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
热搜:搜索排名营销大揭秘
【美】肖恩·布拉德利 / 中国人民大学出版社有限公司 / 2018-7-30 / CNY 55.00
首部大数据在我国政府管理场景中的应用实践案例读本,全面展示我国电子政务与数字化建设的成果,深度理解实施国家大数据战略的重要意义。 本书作者作为国内最早从事大数据应用研究的实践者之一,亲历了中国大数据的发展历程、主要事件、应用案例以及行业变化。 在本书中,作者将其所亲历的大数据发展历程进行了阐述,从大数据的基本概念、特点到实践解读,通俗易懂,给我们的实际工作提供了重要参考。作者将帮助读者......一起来看看 《热搜:搜索排名营销大揭秘》 这本书的介绍吧!
在线进制转换器
各进制数互转换器
RGB CMYK 转换工具
RGB CMYK 互转工具