这是我参与「 第五届青训营 」伴学笔记创作活动的第 14 天 go-micro 是一个RPC分布式系统开发的框架。文章介绍了使用 go-micro 实现用户注册登陆功能。
基础
1 为单独模块创建模块文件夹并创建单独的gomod文件
2 service文件夹下编写proto并生成pb文件
syntax = "proto3";
package service;
option go_package = "./;proto";
message UserModel {
int64 ID = 1;
string Username = 2;
string Password = 3;
int64 CreatedAt = 4;
int64 UpdatedAt = 5;
int64 DeletedAt = 6;
}
syntax = "proto3";
package service;
import "userModel.proto";
option go_package = "./;proto";
message UserRequest {
string Username = 1;
string Password = 2;
string PasswordConfirm = 3;
}
message UserDetailResponse {
uint32 Code = 1;
UserModel UserDetail = 2;
}
service UserService {
rpc UserLogin(UserRequest) returns(UserDetailResponse);
rpc UserRegister(UserRequest) returns(UserDetailResponse);
}
protoc --proto_path=. --micro_out=. --go_out=. FILENAME.proto
3 实现pb.micro文件中的Server API接口
// Server API for UserService service
type UserServiceHandler interface {
UserLogin(context.Context, *UserRequest, *UserDetailResponse) error
UserRegister(context.Context, *UserRequest, *UserDetailResponse) error
}
type UserService struct {
}
func (*UserService) UserLogin(ctx context.Context, req *service.UserRequest, resp *service.UserDetailResponse) error {
return nil
}
func (*UserService) UserRegister(ctx context.Context, req *service.UserRequest, resp *service.UserDetailResponse) error {
return nil
}
服务端
1 得到etcd注册件 设置etcd端口 启动etcd
etcdRegistry := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
使用etcpkeeper::etcdkeeper -h 127.0.0.1 -p 3000
2 得到micro微服务实例 设置微服务名称 端口 ectd注册件
userService := micro.NewService(
micro.Name("userService"),
micro.Address("127.0.0.1:8081"),
micro.Registry(etcdRegistry),
)
3 微服务实例初始化
userService.Init()
4 使用go micro service注册微服务及其对应的实现方法
_ = service.RegisterUserServiceHandler(userService.Server(), new(core.UserService))
5 运行微服务
_ = userService.Run()
6 设置启动参数
--registry=etcd --registry_address=127.0.0.1:2379
编写网关路由
1 新建service文件夹 复制proto文件 重新生成pb文件
2 新建web文件夹 创建gin路由
func NewRouter(service ...interface{}) *gin.Engine {
engine := gin.Default()
return engine
}
注册网关
1 创建wrapper文件夹 配置服务熔断
import (
"context"
"github.com/afex/hystrix-go/hystrix"
"github.com/micro/go-micro/v2/client"
)
type userWrapper struct {
client.Client
}
func (wrapper *userWrapper) Call(ctx context.Context,req client.Request,resp interface{},opts ...client.CallOption)error {
cmdName := req.Service() + "." + req.Endpoint()
config := hystrix.CommandConfig{
Timeout: 30000,
RequestVolumeThreshold: 20, //熔断器请求阈值,默认20,意思是有20个请求才能进行错误百分比计算
ErrorPercentThreshold: 50, //错误百分比,当错误超过百分比时,直接进行降级处理,直至熔断器再次 开启,默认50%
SleepWindow: 5000, //过多长时间,熔断器再次检测是否开启,单位毫秒ms(默认5秒)
}
hystrix.ConfigureCommand(cmdName, config)
return hystrix.Do(cmdName, func() error {
return wrapper.Client.Call(ctx, req, resp)
}, func(err error) error {
return err
})
}
//NewUserWrapper 初始化Wrapper
func NewUserWrapper(c client.Client) client.Client {
return &userWrapper{c}
}
2 创建main函数
2 得到etcd注册件 设置etcd端口
etcdRegistry := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
3 创建微服务实例客户端
userMicroServiceClient := micro.NewService(
micro.Name("userService.client"),
micro.WrapClient(wrappers.NewUserWrapper),
)
4 获取用户服务调用实例
userService := service.NewUserService(
"userService",
userMicroServiceClient.Client(),
)
5 创建微服务实例 使用gin暴露http接口
server := web.NewService(
web.Name("httpService"),
web.Address("127.0.0.1:4000"),
//将服务调用实例使用gin处理
web.Handler(weblib.NewRouter(userService)),
web.Registry(etcdRegistry),
web.RegisterTTL(time.Second*30),
web.RegisterInterval(time.Second*15),
web.Metadata(map[string]string{"protocol": "http"}),
)
6 服务初始化
_ = server.Init()
7 启动服务
_ = server.Run()