微服务创建案例
创建新项目
项目名是test
gf init test -m
创建子项目
创建两个子项目,名为test1和test2
gf init app/test1 -a
gf init app/test2 -a
创建Protoc和使用gf gen pb
参考文章:这里
- test1项目是service,test2项目是client。 在test1的api文件夹当中创建v1, 路径为下
test/app/test/api/v1
- 在test1项目manifest当中创建user.proto文件
test/app/test/manifest/protobuf/v1/user.proto
├── manifest
│ ├── protobuf
│ │ ├── user
│ │ │ ├── v1
│ │ │ │ ├── user.proto
这个proto文件内容如下
syntax = "proto3";
package user; //协议包名
option go_package = "test1/api/v1"; //生成go代码文件包名
service User {
rpc SayHello (HelloRequest) returns (HelloReply) {} //rpc接口
}
// rpc请求体
message HelloRequest {
string name = 1;
}
message SingleUser {
string id = 1;
string display_name = 2;
}
message Data{
repeated SingleUser users = 1;
string batch = 2;
}
// rpc响应体
message HelloReply {
int64 code = 1;
string error = 2;
Data data = 3;
}
- 在test1目录底下执行gf gen pb命令行
gf gen pb
- 系统会根据proto文件定义好的接口,生成出以下2个golang文件
├── test1
│ ├── api
│ │ ├── v1
│ │ │ ├── user.pb.go
│ │ │ ├── user_grpc.pb.go
- 在test1子项目当中的internal/controller也会自动生成test1 controller
运行Service服务
- 执行以下命令
go mod tidy
- 拉取grpcx依赖
go get -u github.com/gogf/gf/contrib/rpc/grpcx/v2
- 在 test1 controller当中引入上个步骤生成的pb.go文件
api "test/app/test1/api/v1"
- 覆盖 test1 controller的 sayhello function
func (*Controller) SayHello(ctx context.Context, req *api.HelloRequest) (res *api.HelloReply, err error) {
res = &api.HelloReply{
Code: 200,
Error: "",
Data: &api.Data{
Batch: "batch_1",
Users: []*api.SingleUser{
{
Id: "1",
DisplayName: "test",
},
{
Id: "2",
DisplayName: req.Name,
},
},
},
}
return
}
- 把test1子项目cmd文件替换成以下的代码,服务端口为8001
var (
Main = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := grpcx.Server.New(&grpcx.GrpcServerConfig{Address: ":8001"})
test1.Register(s)
s.Run()
return nil
},
}
)
运行Client服务
- 去到test2的main文件导入以上生成的pb文件 (在test1子项目的)
v1 "test/app/test1/api/v1"
- 覆盖在test2的main function, 使用grpc访问test1的8001端口,提交name:john
func main() {
ctx := gctx.New()
conn, _ := grpcx.Client.NewGrpcClientConn("127.0.0.1:8001", grpc.WithTransportCredentials(insecure.NewCredentials()))
client := v1.NewUserClient(conn)
response, err := client.SayHello(ctx, &v1.HelloRequest{
Name: "john",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(response)
}
- 得到运行结果返回如下
code:200 data:{users:{id:"1" display_name:"test"} users:{id:"2" display_name:"john"} batch:"batch_1"}