go-zero docker-compose 搭建课件服务(五):完善user服务
0、转载
go-zero docker-compose 搭建课件服务(五):完善user服务
0.1源码地址
https://github.com/liuyuede123/go-zero-courseware
1、生成model
到项目根目录下创建model目录,并新建user.sql
mkdir user/rpc/model
touch 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/model
goctl 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 init
go mod tidy
user/rpc/etc/user.yaml中增加数据源和缓存配置
Name: user.rpc
ListenOn: 127.0.0.1:8300
Etcd:
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: user
Host: 0.0.0.0
Port: 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
}
go-zero docker-compose 搭建课件服务(五):完善user服务的更多相关文章
- Docker Compose 搭建 Redis Cluster 集群环境
在前文<Docker 搭建 Redis Cluster 集群环境>中我已经教过大家如何搭建了,本文使用 Docker Compose 再带大家搭建一遍,其目的主要是为了让大家感受 Dock ...
- Istio入门实战与架构原理——使用Docker Compose搭建Service Mesh
本文将介绍如何使用Docker Compose搭建Istio.Istio号称支持多种平台(不仅仅Kubernetes).然而,官网上非基于Kubernetes的教程仿佛不是亲儿子,写得非常随便,不仅缺 ...
- 利用 Docker Compose 搭建 SpringBoot 运行环境(超详细步骤和分析)
0.前言 相信点进来看这篇文章的同学们已经对 Docker Dompose 有一定的了解了,下面,我们拿最简单的例子来介绍如何使用 Docker Compose 来管理项目. 本文例子: 一个应用服务 ...
- 使用Docker Compose搭建Service Mesh
使用Docker Compose搭建Service Mesh 本文将介绍如何使用Docker Compose搭建Istio.Istio号称支持多种平台(不仅仅Kubernetes).然而,官网上非基于 ...
- Docker Compose搭建Redis一主二从三哨兵高可用集群
一.Docker Compose介绍 https://docs.docker.com/compose/ Docker官方的网站是这样介绍Docker Compose的: Compose是用于定义和运行 ...
- docker compose搭建redis7.0.4高可用一主二从三哨兵集群并整合SpringBoot【图文完整版】
一.前言 redis在我们企业级开发中是很常见的,但是单个redis不能保证我们的稳定使用,所以我们要建立一个集群. redis有两种高可用的方案: High availability with Re ...
- docker快速搭建几个常用的第三方服务
本次和大家分享的内容是使用docker快速搭建工作中常用的第三方的服务,对于有一些互联网背景的公司来说,以下几个服务都是很需要的:redis,rabbit,elasticsearch: 本篇涉及内容深 ...
- 基于Docker Compose搭建mysql主从复制(1主2从)
系统环境 * 3 Ubuntu 16.04 mysql 8.0.12 docker 18.06.1-ce docker-compose 1.23.0-rc3 *3 ==> PS ###我用的是 ...
- Docker Compose搭建ELK
Elasticsearch默认使用mmapfs目录来存储索引.操作系统默认的mmap计数太低可能导致内存不足,我们可以使用下面这条命令来增加内存: sysctl -w vm.max_map_count ...
- Docker Compose部署GitLab服务,搭建自己的代码托管平台(图文教程)
场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
随机推荐
- mybatis 02: 添加并简单使用mybatis
三层架构 项目开发时,遵循的一种设计模式,分为三层 界面层:用来接收客户端输入的数据,调用业务逻辑层进行功能处理,返回结果给客户端 过去的servlet就完成了界面层的功能(但是他做的更多) 业务逻辑 ...
- LuoguP4219 [BJOI2014]大融合(LCT)
早上考试想用\(LCT\)维护联通块\(size\),现在才发现\(LCT\)的\(size\)有虚实之分 \(Link\)与\(Acess\)中虚实变,干他丫的 \(Splay\)中只是相对关系,没 ...
- Dart 导包时类名冲突
import 'package:qingyuo_mobile/pages/slices/home_page/tech_slice.dart'; import 'package:qingyuo_mobi ...
- Hadoop集群搭建的详细过程
Hadoop集群搭建 一.准备 三台虚拟机:master01,node1,node2 时间同步 1.date命令查看三台虚拟机时间是否一致 2.不一致时间同步:ntpdate ntp.aliyun.c ...
- 【HMS core】【FAQ】典型问题合集7
1.[HMS core][Account Kit][问题描述] 集成华为帐号服务后,登录服务异常,无法获取用户信息,报statusCode为907135001,抓取报错日志:Failed to re ...
- k8s命令补全方法
正常安装了k8s后,使用kubect 工具后接的命令不能直接tab补全 命令补全方法: yum -y install bash-completionsource /usr/share/bash-com ...
- 如何在 C# 程序中注入恶意 DLL?
一:背景 前段时间在训练营上课的时候就有朋友提到一个问题,为什么 Windbg 附加到 C# 程序后,程序就处于中断状态了?它到底是如何实现的? 其实简而言之就是线程的远程注入,这一篇就展开说一下. ...
- RTSP播放器开发填坑之道
好多开发者提到,在目前开源播放器如此泛滥的情况下,为什么还需要做自研框架的RTSP播放器,自研和开源播放器,到底好在哪些方面?以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延 ...
- Vmware虚拟主机访问外网设置
本手册使用10.4.7.0/24网段 重点在于虚拟主机的网关和宿主机上的Vmnet8的IP和虚拟网络编辑器的NET网关保持一致 1.设置宿主机网络适配器 选择允许Vmware网络共享 配置VMnet8 ...
- 【读书笔记】C#高级编程 第二十二章 安全性
(一)身份验证和授权 安全性的两个基本支柱是身份验证和授权.身份验证是标识用户的过程,授权在验证了所标识用户是否可以访问特性资源之后进行的. 1.标识和Principal 使用标识可以验证运行应用程序 ...