写点什么

go-zero docker-compose 搭建课件服务(五):完善 user 服务

作者:六月的
  • 2022-10-19
    上海
  • 本文字数:6468 字

    阅读完需:约 1 分钟

0、转载

go-zero docker-compose 搭建课件服务(五):完善user服务

0.1 源码地址

https://github.com/liuyuede123/go-zero-courseware

1、生成 model

到项目根目录下创建 model 目录,并新建 user.sql


mkdir user/rpc/modeltouch user/rpc/model/user.sql
复制代码


CREATE TABLE `user`(    `id`          bigint unsigned NOT NULL AUTO_INCREMENT,    `login_name`  varchar(255) NOT NULL DEFAULT '' COMMENT '登录名',    `username`        varchar(255) NOT NULL DEFAULT '' COMMENT '用户姓名',    `sex`      tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '用户性别',    `password`    varchar(255) NOT NULL DEFAULT '' COMMENT '用户密码',    `is_delete`   tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0-未删除 1-已删除',    `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,    `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,    PRIMARY KEY (`id`),    UNIQUE KEY `udx_login_name` (`login_name`)) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;
复制代码


到 model 目录下生成 model


cd user/rpc/modelgoctl model mysql ddl -src="./*.sql" -dir="./" -c
复制代码

2、生成 rpc 文件

到 user/rpc 目录下生成 rpc 文件


goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.
复制代码

3、增加 mysql 配置

user 目录下初始化 module


go mod initgo mod tidy
复制代码


user/rpc/etc/user.yaml 中增加数据源和缓存配置


Name: user.rpcListenOn: 127.0.0.1:8300Etcd:  Hosts:  - etcd:2379  Key: user.rpc
# mysql数据源Mysql: DataSource: root:liufutian@tcp(192.168.0.110:3306)/go_zero_courseware?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
# redis缓存CacheRedis: - Host: 192.168.0.110:6379 Pass:
复制代码


修改 user/rpc/internal/config/config.go 中配置


package config
import ( "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/zrpc")
type Config struct { zrpc.RpcServerConf
Mysql struct { DataSource string }
CacheRedis cache.CacheConf}
复制代码


修改 courseware/rpc/internal/svc/servicecontext.go 相关配置


package svc
import ( "github.com/zeromicro/go-zero/core/stores/sqlx" "go-zero-courseware/user/rpc/internal/config" "go-zero-courseware/user/rpc/model")
type ServiceContext struct { Config config.Config
UserModel model.UserModel}
func NewServiceContext(c config.Config) *ServiceContext { conn := sqlx.NewMysql(c.Mysql.DataSource) return &ServiceContext{ Config: c, UserModel: model.NewUserModel(conn, c.CacheRedis), }}
复制代码

4、添加用户逻辑

先走通,后续会优化用户逻辑


user/rpc/internal/logic/registerlogic.go 增加注册逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/internal/svc" "go-zero-courseware/user/rpc/model" "go-zero-courseware/user/rpc/user" "google.golang.org/grpc/status"
"github.com/zeromicro/go-zero/core/logx")
type RegisterLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger}
func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic { return &RegisterLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), }}
func (l *RegisterLogic) Register(in *user.RegisterRequest) (*user.RegisterResponse, error) { _, err := l.svcCtx.UserModel.FindOneByLoginName(l.ctx, in.LoginName) if err == nil { return nil, status.Error(5000, "登录名已存在") }
if err != model.ErrNotFound { return nil, status.Error(500, err.Error()) } newUser := model.User{ LoginName: in.LoginName, Username: in.Username, Sex: in.Sex, Password: in.Password, } _, err = l.svcCtx.UserModel.Insert(l.ctx, &newUser) if err != nil { return nil, status.Error(500, err.Error()) }
return &user.RegisterResponse{}, nil}
复制代码


user/rpc/internal/logic/loginlogic.go 增加登录逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/model" "google.golang.org/grpc/status"
"go-zero-courseware/user/rpc/internal/svc" "go-zero-courseware/user/rpc/user"
"github.com/zeromicro/go-zero/core/logx")
type LoginLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger}
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { return &LoginLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), }}
func (l *LoginLogic) Login(in *user.LoginRequest) (*user.LoginResponse, error) { userInfo, err := l.svcCtx.UserModel.FindOneByLoginName(l.ctx, in.LoginName) if err == model.ErrNotFound { return nil, status.Error(5000, "用户不存在") } if err != nil { return nil, status.Error(500, err.Error()) }
if in.Password != userInfo.Password { return nil, status.Error(5000, "密码错误") }
return &user.LoginResponse{ Id: userInfo.Id, Token: "a.b.c", }, nil}
复制代码


增加用户信息逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/model" "google.golang.org/grpc/status"
"go-zero-courseware/user/rpc/internal/svc" "go-zero-courseware/user/rpc/user"
"github.com/zeromicro/go-zero/core/logx")
type UserInfoLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger}
func NewUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserInfoLogic { return &UserInfoLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), }}
func (l *UserInfoLogic) UserInfo(in *user.UserInfoRequest) (*user.UserInfoResponse, error) { userInfo, err := l.svcCtx.UserModel.FindOne(l.ctx, in.Id) if err == model.ErrNotFound { return nil, status.Error(5000, "用户不存在") } if err != nil { return nil, status.Error(500, err.Error()) }
return &user.UserInfoResponse{ Id: userInfo.Id, Username: userInfo.Username, LoginName: userInfo.LoginName, Sex: userInfo.Sex, }, nil}
复制代码

5、完善 api 代码

到 user/api 目录下,生成 api 端代码


goctl api go -api user.api -dir . -style gozero
复制代码


user/api/etc/user.yaml 配置


Name: userHost: 0.0.0.0Port: 8300
UserRpc: Etcd: Hosts: - etcd:2379 Key: user.rpc
复制代码


user/api/internal/config/config.go 配置


package config
import ( "github.com/zeromicro/go-zero/rest" "github.com/zeromicro/go-zero/zrpc")
type Config struct { rest.RestConf
UserRpc zrpc.RpcClientConf}
复制代码


user/api/internal/svc/servicecontext.go 配置


package svc
import ( "github.com/zeromicro/go-zero/zrpc" "go-zero-courseware/user/api/internal/config" "go-zero-courseware/user/rpc/userclient")
type ServiceContext struct { Config config.Config
UserRpc userclient.User}
func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ Config: c, UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)), }}
复制代码


user/api/internal/logic/userregisterlogic.go 增加注册逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/userclient" "google.golang.org/grpc/status"
"go-zero-courseware/user/api/internal/svc" "go-zero-courseware/user/api/internal/types"
"github.com/zeromicro/go-zero/core/logx")
type UserRegisterLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext}
func NewUserRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserRegisterLogic { return &UserRegisterLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, }}
func (l *UserRegisterLogic) UserRegister(req *types.RegisterRequest) (resp *types.RegisterResponse, err error) { _, err = l.svcCtx.UserRpc.Register(l.ctx, &userclient.RegisterRequest{ LoginName: req.LoginName, Username: req.Username, Password: req.Password, Sex: req.Sex, }) if err != nil { return nil, status.Error(500, err.Error()) }
return &types.RegisterResponse{}, nil}
复制代码


user/api/internal/logic/userloginlogic.go 增加登录逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/userclient"
"go-zero-courseware/user/api/internal/svc" "go-zero-courseware/user/api/internal/types"
"github.com/zeromicro/go-zero/core/logx")
type UserLoginLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext}
func NewUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLoginLogic { return &UserLoginLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, }}
func (l *UserLoginLogic) UserLogin(req *types.LoginRequest) (resp *types.LoginResponse, err error) { login, err := l.svcCtx.UserRpc.Login(l.ctx, &userclient.LoginRequest{ LoginName: req.LoginName, Password: req.Password, }) if err != nil { return nil, err }
return &types.LoginResponse{ Id: login.Id, Token: login.Token, }, nil}
复制代码


user/api/internal/logic/userinfologic.go 增加用户信息逻辑


package logic
import ( "context" "go-zero-courseware/user/rpc/userclient" "google.golang.org/grpc/status"
"go-zero-courseware/user/api/internal/svc" "go-zero-courseware/user/api/internal/types"
"github.com/zeromicro/go-zero/core/logx")
type UserInfoLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext}
func NewUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserInfoLogic { return &UserInfoLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, }}
func (l *UserInfoLogic) UserInfo(req *types.UserInfoRequest) (resp *types.UserInfoResponse, err error) { info, err := l.svcCtx.UserRpc.UserInfo(l.ctx, &userclient.UserInfoRequest{ Id: req.Id, }) if err != nil { return nil, status.Error(500, err.Error()) }
return &types.UserInfoResponse{ Id: info.Id, Username: info.Username, LoginName: info.LoginName, Sex: info.Sex, }, nil}
复制代码

6、docker-compose 增加配置

user/rpc 目录下生成 rpc 的 Dockerfile


goctl docker -go user.go
复制代码


user/api 目录下生成 api 的 Dockerfile


goctl docker -go user.go
复制代码


根目录下 docker-compose.yml 增加用户服务 api 和 rpc 配置


version: '3.5'# 网络配置networks:  backend:    driver: bridge
# 服务容器配置services: etcd: # 自定义容器名称 build: context: etcd # 指定构建使用的 Dockerfile 文件 environment: - TZ=Asia/Shanghai - ALLOW_NONE_AUTHENTICATION=yes - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 ports: # 设置端口映射 - "2379:2379" networks: - backend restart: always
etcd-manage: build: context: etcd-manage environment: - TZ=Asia/Shanghai ports: - "7000:8080" # 设置容器8080端口映射指定宿主机端口,用于宿主机访问可视化web depends_on: # 依赖容器 - etcd # 在 etcd 服务容器启动后启动 networks: - backend restart: always
courseware-rpc: # 自定义容器名称 build: context: courseware # 指定构建使用的 Dockerfile 文件 dockerfile: rpc/Dockerfile environment: # 设置环境变量 - TZ=Asia/Shanghai privileged: true ports: # 设置端口映射 - "9400:9400" # 课件服务rpc端口 stdin_open: true # 打开标准输入,可以接受外部输入 tty: true networks: - backend restart: always # 指定容器退出后的重启策略为始终重启
courseware-api: # 自定义容器名称 build: context: courseware # 指定构建使用的 Dockerfile 文件 dockerfile: api/Dockerfile environment: # 设置环境变量 - TZ=Asia/Shanghai privileged: true ports: # 设置端口映射 - "8400:8400" # 课件服务api端口 stdin_open: true # 打开标准输入,可以接受外部输入 tty: true networks: - backend restart: always # 指定容器退出后的重启策略为始终重启
user-rpc: # 自定义容器名称 build: context: user # 指定构建使用的 Dockerfile 文件 dockerfile: rpc/Dockerfile environment: # 设置环境变量 - TZ=Asia/Shanghai privileged: true ports: # 设置端口映射 - "9300:9300" # 课件服务rpc端口 stdin_open: true # 打开标准输入,可以接受外部输入 tty: true networks: - backend restart: always # 指定容器退出后的重启策略为始终重启
user-api: # 自定义容器名称 build: context: user # 指定构建使用的 Dockerfile 文件 dockerfile: api/Dockerfile environment: # 设置环境变量 - TZ=Asia/Shanghai privileged: true ports: # 设置端口映射 - "8300:8300" # 课件服务api端口 stdin_open: true # 打开标准输入,可以接受外部输入 tty: true networks: - backend restart: always # 指定容器退出后的重启策略为始终重启
复制代码

6、运行 user 服务

user 目录下


go mod tidy
复制代码


到项目根目录


docker-compose up -d
复制代码

7、测试接口

http://localhost:8300/api/user/register{    "loginName": "liuyuede",    "username": "liuyuede",    "sex": 1,    "password": "123"}http://localhost:8300/api/user/login{    "loginName": "liuyuede",    "password": "123"}http://localhost:8300/api/user/userInfo{    "id": 2}
复制代码


用户头像

六月的

关注

还未添加个人签名 2019-07-23 加入

还未添加个人简介

评论

发布
暂无评论
go-zero docker-compose 搭建课件服务(五):完善user服务_Docker-compose_六月的_InfoQ写作社区