• 微服务(一) go kratos 用户服务


    因为前端业务需求的多样性与敏捷性,我们可能考虑需要用php 作为client,实现数据的组装与拼接,以应对前端的多边的需求;用go 来实现server端。我们采用laravel 作为client的框架,kratos 作为server

    创建项目及目录架构

    在$GOPATH 的src 下创建项目目录并初始化

    # 创建目录
    $ mkdir -p kratos-tiway
    # 初始化
    $ go mod init
    
    • 1
    • 2
    • 3
    • 4

    我们准备创建app目录作为server目录,api 作为proto 和client 文件目录

    $ mkdir -p app
    $ mkdir -p api
    
    • 1
    • 2

    在app目录下使用 --nomod 添加服务,共用 go.mod ,
    创建user 服务
    创建user proto

    kratos new app/user --nomod
    kratos proto add api/user/v1/user.proto
    
    • 1
    • 2

    我们现在看下我们项目的整体架构
    在这里插入图片描述

    用户模块

    编辑用户的proto

    syntax = "proto3";
    
    package user.v1;
    
    option go_package = "kratos-tiway/api/user/v1;v1";
    
    service User {
    	rpc GetUserList(SearchUser) returns (UserListResponse){}; // 用户列表
    	rpc GetUserByMobile(MobileRequest) returns (UserInfoResponse){}; // 通过 mobile 查询用户
    	rpc GetUserByNickname(NicknameRequest) returns (UserInfoResponse){}; // 通过 昵称 查询用户
    	rpc GetUserById(IdRequest) returns (UserInfoResponse){}; // 通过 Id 查询用户
    	rpc CreateUser(CreateUserInfo) returns (UserInfoResponse){}; // 创建用户
    	rpc UpdateUser(UpdateUserInfo) returns (UpdateUserResponse){}; // 更新用户
    	rpc CheckPassword(PasswordCheckInfo) returns (CheckResponse){}; // 检查用户密码
    }
    
    message SearchUser {
    	int32 page = 1;
    	int32 limit = 2;
    	int64 id = 3;
    	string name = 4;
    	string nickname = 5;
    	string email = 6;
    	string mobile = 7;
    	int32 status = 8;
    	int64 created_at = 9;
    }
    
    message UserInfoResponse{
    	int64 id = 1;
    	string name = 2;
    	string mobile = 3;
    	string nickName = 4;
    	string email = 5;
    	string password = 6;
    	int32 status = 7;
    	int64 created_at = 8;
    }
    
    message UserListResponse{
    	int32 total = 1;
    	repeated UserInfoResponse data = 2;
    }
    
    message MobileRequest{
    	string mobile = 1;
    }
    
    message NicknameRequest{
    	string nickname = 1;
    }
    
    message IdRequest{
    	int64 id = 1;
    }
    
    // 创建用户
    message  CreateUserInfo{
    	string mobile = 1;
    	string nickname = 2;
    	string password = 3;
    }
    
    message  UpdateUserInfo{
    	int64 id = 1;
    	string nickname = 2;
    	string name = 3;
    	string mobile = 4;
    	string email = 5;
    }
    
    message PasswordCheckInfo{
    	string Mobile = 1;
    	string password = 2;
    }
    
    message CheckResponse{
    	bool success = 1;
    }
    
    message UpdateUserResponse {
    	bool success = 1;
    	string message = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    生成client

    kratos proto client api/user/v1/user.proto
    
    • 1

    在这里插入图片描述
    生成server

    $ kratos proto server api/user/v1/user.proto -t app/user/internal/service
    app/user/internal/service/user.go
    
    • 1
    • 2

    删除多余文件

    rm app/user/internal/biz/greeter.go
    rm app/user/internal/data/greeter.go
    rm app/user/internal/server/http.go
    rm app/user/internal/service/greeter.go
    
    • 1
    • 2
    • 3
    • 4

    创建数据数据库与表结构

    CREATE DATABASE [IF NOT EXISTS]  kratos-tiway;
    
    CREATE TABLE `users` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
      `name` varchar(50) NOT NULL COMMENT '用户名',
      `nickname` varchar(150) DEFAULT NULL COMMENT '昵称',
      `avatar` varchar(150) DEFAULT NULL COMMENT '头像',
      `password` varchar(100) DEFAULT NULL COMMENT '密码',
      `salt` varchar(40) DEFAULT NULL COMMENT '加密盐',
      `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
      `mobile` varchar(100) DEFAULT NULL COMMENT '手机号',
      `status` tinyint DEFAULT NULL COMMENT '状态  0:禁用   1:正常',
      `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更细时间',
      `deleted_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '删除时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='用户表';
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    链接数据库kratos-tiway/app/user/internal/data/data.go

    package data
    
    import (
    	"github.com/go-kratos/kratos/v2/log"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/google/wire"
    	"gorm.io/driver/mysql"
    	"gorm.io/gorm"
    	"gorm.io/gorm/logger"
    	"kratos-tiway/app/user/internal/conf"
    )
    
    // ProviderSet is data providers.
    var ProviderSet = wire.NewSet(
    	NewData,
    	NewDB,
    	NewUserRepo,
    )
    
    // Data .
    type Data struct {
    	db  *gorm.DB
    	log *log.Helper
    }
    
    func NewDB(conf *conf.Data, logger1 log.Logger) *gorm.DB {
    	log := log.NewHelper(log.With(logger1, "module", "ums-service/data/gorm"))
    
    	db, err := gorm.Open(mysql.Open(conf.Database.Source), &gorm.Config{
    		Logger: logger.Default.LogMode(logger.Info),
    	})
    	if err != nil {
    		log.Fatalf("failed opening connection to mysql: %v", err)
    	}
    	return db
    }
    
    // NewData .
    func NewData(db *gorm.DB, logger log.Logger) (*Data, func(), error) {
    	log := log.NewHelper(log.With(logger, "module", "order-service/data"))
    
    	d := &Data{
    		db:  db,
    		log: log,
    	}
    	return d, func() {
    
    	}, nil
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    修改app/user/internal/server/grpc.go

    func NewGRPCServer(c *conf.Server, user *service.UserService, logger log.Logger) *grpc.Server {
    	var opts = []grpc.ServerOption{
    		grpc.Middleware(
    			recovery.Recovery(),
    		),
    	}
    	if c.Grpc.Network != "" {
    		opts = append(opts, grpc.Network(c.Grpc.Network))
    	}
    	if c.Grpc.Addr != "" {
    		opts = append(opts, grpc.Address(c.Grpc.Addr))
    	}
    	if c.Grpc.Timeout != nil {
    		opts = append(opts, grpc.Timeout(c.Grpc.Timeout.AsDuration()))
    	}
    	srv := grpc.NewServer(opts...)
    	v1.RegisterUserServer(srv, user)
    	return srv
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    app/user/internal/server/server.go 去除http server 依赖声明

    var ProviderSet = wire.NewSet(NewGRPCServer)
    
    • 1

    参考代码https://github.com/tiway-deng/kratos-tiway

  • 相关阅读:
    禅道如何编辑项目模块
    grep扩展正则使用
    探索LLM在图上学习的潜力10.14 暂停
    《进程状态》
    可道云:像Windows操作一样的企业网盘
    【Rust日报】2022-11-07 使用 Tauri 构建桌面托盘应用
    C++类模板再学习
    服务器数据恢复—误还原虚拟机快照后如何恢复之前的数据?
    [git] git diff
    BIOMOD2模型、MaxEnt模型物种分布模拟,生物多样性生境模拟,论文写作
  • 原文地址:https://blog.csdn.net/qq_39941141/article/details/127424214