Go语言实战 (14) Gin+gRPC 微服务实现备忘录 (上) | 用户模块
Posted 小生凡一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言实战 (14) Gin+gRPC 微服务实现备忘录 (上) | 用户模块相关的知识,希望对你有一定的参考价值。
写在前面
介于很多同学让我出一下关于gRPC的内容,我就用gRPC把备忘录重新做一遍。
源码地址:
https://github.com/CocaineCong/gRPC-todoList
1. 安装部分
1.1 安装gRPC
go get google.golang.org/grpc
go get google.golang.org/protobuf
1.2 安装protoc
可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
下载proto,我是下载这个的。
然后解压出来把bin目录放在直接放在系统变量当中
验证
2. 用户模块
2.1 总体项目架构
user/
├── cmd // 启动入口
├── config // 配置文件
├── discovery // etcd服务注册、keep-alive、获取服务信息等等
├── internal // 业务逻辑(不对外暴露)
│ ├── handler // 视图层
│ ├── cache // 缓存模块
│ ├── repository // 持久层
│ └── service // 服务层
│ └──pb // 放置生成的pb文件
├── logs // 放置打印日志模块
├── pkg // 各种包
│ ├── e // 统一错误状态码
│ ├── res // 统一response接口返回
│ └── util // 各种工具、JWT、Logger等等..
├── routes // http路由模块
└── wrappers // 各个服务之间的熔断降级
2.2 proto文件定义
- user/internal/service/pb
syntax="proto3";
package pb;
option go_package = "/internal/service;service";
message UserModel
// @inject_tag: json:"user_id"
uint32 UserID=1;
// @inject_tag: json:"user_name"
string UserName=2;
// @inject_tag: json:"nick_name"
string NickName=3;
执行
protoc -I internal/service/pb internal/service/pb/*.proto --go_out=plugins=grpc:.
生成 pb.go 文件
- user/service/pb
定义user模块的请求和返回的结构类型,已经rpc方法。
syntax="proto3";
package pb;
import "userModels.proto";
option go_package = "/internal/service;service";
message UserRequest
// @inject_tag: json:"nick_name" form:"nick_name" uri:"nick_name"
string NickName=1;
// @inject_tag: json:"user_name" form:"user_name" uri:"user_name"
string UserName=2;
// @inject_tag: json:"password" form:"password" uri:"password"
string Password=3;
// @inject_tag: json:"password_confirm" form:"password_confirm" uri:"password_confirm"
string PasswordConfirm=4;
message UserDetailResponse
UserModel UserDetail=1;
uint32 Code=2;
service UserService
rpc UserLogin(UserRequest) returns(UserDetailResponse);
rpc UserRegister(UserRequest) returns(UserDetailResponse);
rpc UserLogout(UserRequest) returns(UserDetailResponse);
2.3 repository
这一层主要是对持久化的操作,基础的业务操作。
type User struct
UserID uint `gorm:"primarykey"`
UserName string `gorm:"unique"`
NickName string
PasswordDigest string
- 视图返回
func BuildUser(item User) *service.UserModel
userModel := service.UserModel
UserID: uint32(item.UserID),
NickName: item.NickName,
UserName: item.UserName,
return &userModel
2.4 接入ETCD服务发现
- user/cmd/main.go
新建一个etcd节点
etcdAddress := []stringviper.GetString("etcd.address")
// 服务注册
etcdRegister := discovery.NewRegister(etcdAddress, logrus.New())
grpcAddress := viper.GetString("server.grpcAddress")
接入user节点
userNode := discovery.Server
Name: viper.GetString("server.domain"),
Addr: grpcAddress,
节点绑定服务
service.RegisterUserServiceServer(server, handler.NewUserService())
服务注册
if _, err := etcdRegister.Register(userNode, 10); err != nil
panic(fmt.Sprintf("start server failed, err: %v", err))
3. 接入网关
3.1 router
- api-gateway/routes/router.go
引入gin作为http网关
func NewRouter(service ...interface) *gin.Engine
ginRouter := gin.Default()
ginRouter.Use(middleware.Cors(), middleware.InitMiddleware(service), middleware.ErrorMiddleware())
store := cookie.NewStore([]byte("something-very-secret"))
ginRouter.Use(sessions.Sessions("mysession", store))
v1 := ginRouter.Group("/api/v1")
v1.GET("ping", func(context *gin.Context)
context.JSON(200, "success")
)
// 用户服务
v1.POST("/user/register", handler.UserRegister)
v1.POST("/user/login", handler.UserLogin)
return ginRouter
3.2 网关连接etcd
与user进行连接,获取user服务
userConn, _ := grpc.Dial("127.0.0.1:10001", opts...)
userService := service.NewUserServiceClient(userConn)
3.3 调用服务
- api-gateway/internal/handler/user.go
func UserRegister(ginCtx *gin.Context)
var userReq service.UserRequest
PanicIfUserError(ginCtx.Bind(&userReq))
// 从gin.Key中取出服务实例
userService := ginCtx.Keys["user"].(service.UserServiceClient)
userResp, err := userService.UserRegister(context.Background(), &userReq)
PanicIfUserError(err)
r := res.Response
Data: userResp,
Status: uint(userResp.Code),
Msg: e.GetMsg(uint(userResp.Code)),
ginCtx.JSON(http.StatusOK, r)
开发者涨薪指南
48位大咖的思考法则、工作方式、逻辑体系
以上是关于Go语言实战 (14) Gin+gRPC 微服务实现备忘录 (上) | 用户模块的主要内容,如果未能解决你的问题,请参考以下文章
3.13 Go微服务实战(微服务理论) --- 微服务中的进程间通信
13.Go语言高并发与微服务实战 --- 综合实战:秒杀系统的设计与实现
13.Go语言高并发与微服务实战 --- 综合实战:秒杀系统的设计与实现