概要

用户服务基本是每个互联网产品里必备的一个服务了,因为没有用户基本是什么也干不了。所以他的重要性不言而喻。本文主要介绍下如何开发一个用户微服务,以及他的详细开发流程。

目录

调用流程图

技术栈

接口开发

使用proto方式定义,主要包含以下接口

开发步骤

这里详细的记录了开发的步骤,方便参看本项目的同学知道其实现过程。

1、生成proto模板文件

  1. eagle proto add api/user/v1/user.proto

内容如下

  1. syntax = "proto3";
  2. package api.user.v1;
  3. option go_package = "github.com/go-microservice/user-service/api/user/v1;v1";
  4. option java_multiple_files = true;
  5. option java_package = "api.user.v1";
  6. service UserService {
  7. rpc CreateUser (CreateUserRequest) returns (CreateUserReply);
  8. rpc UpdateUser (UpdateUserRequest) returns (UpdateUserReply);
  9. rpc DeleteUser (DeleteUserRequest) returns (DeleteUserReply);
  10. rpc GetUser (GetUserRequest) returns (GetUserReply);
  11. rpc ListUser (ListUser1Request) returns (ListUserReply);
  12. }
  13. message CreateUser1Request {}
  14. message CreateUser1Reply {}
  15. message UpdateUserRequest {}
  16. message UpdateUserReply {}
  17. message DeleteUserRequest {}
  18. message DeleteUserReply {}
  19. message GetUserRequest {}
  20. message GetUserReply {}
  21. message ListUserRequest {}
  22. message ListUserReply {}

2、为proto填充业务方法及字段定义

  1. vim api/user/v1/user.proto

3、生成pb文件

  1. # 生成所有proto
  2. make grpc
  3. # 或者
  4. # 生成指定proto的pb文件
  5. eagle proto client api/user/v1/user.proto
  6. # Output
  7. ll api/user/v1/
  8. user.pb.go #新增
  9. user.proto
  10. user_grpc.pb.go #新增

会生成两个文件 api/user/v1/user.pb.goapi/user/v1/user.pb.go

4、生成server骨架代码

  1. # 生成骨架代码
  2. eagle proto server api/user/v1/user.proto
  3. # 默认会输出到 internal/service
  4. # 如果需要指定到对应的目录,可以使用 -t 参数, eg:
  5. # eagle proto server -t internal/logic
  6. # 查看
  7. internal/service/user_svc.go

5、注册服务到gRPC Server

  1. // internal/server/grpc.go
  2. import (
  3. ...
  4. v1 "github.com/go-microservice/user-service/api/user/v1"
  5. ...
  6. )
  7. ...
  8. // NewGRPCServer creates a gRPC server
  9. func NewGRPCServer(
  10. cfg *app.ServerConfig,
  11. // 新增
  12. svc *service.UserServiceServer,
  13. ) *grpc.Server {
  14. grpcServer := grpc.NewServer(
  15. grpc.Network("tcp"),
  16. grpc.Address(cfg.WriteTimeout),
  17. grpc.Timeout(cfg.WriteTimeout),
  18. )
  19. // register biz service
  20. // 新增
  21. v1.RegisterUserServiceServer(grpcServer, svc)
  22. return grpcServer
  23. }

6、在生成的server中编写业务逻辑

  1. // vim internal/service/user_svc.go
  2. package service
  3. import (
  4. "context"
  5. pb "github.com/go-microservice/moment-service/api/user/v1"
  6. )
  7. var (
  8. _ pb.UserServiceServer = (*UserServiceServer)(nil)
  9. )
  10. type UserServiceServer struct {
  11. pb.UnimplementedUserServiceServer
  12. }
  13. func NewUserServiceServer() *UserServiceServer {
  14. return &UserServiceServer{
  15. }
  16. }
  17. func (s *UserServiceServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserReply, error) {
  18. return &pb.CreateUserReply{}, nil
  19. }
  20. func (s *UserServiceServer) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserReply, error) {
  21. return &pb.UpdateUserReply{}, nil
  22. }
  23. func (s *UserServiceServer) DeleteUser(ctx context.Context, req *pb.DeleteUserRequest) (*pb.DeleteUserReply, error) {
  24. return &pb.DeleteUserReply{}, nil
  25. }
  26. func (s *UserServiceServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserReply, error) {
  27. return &pb.GetUserReply{}, nil
  28. }
  29. func (s *UserServiceServer) ListUser(ctx context.Context, req *pb.ListUserRequest) (*pb.ListUserReply, error) {
  30. return &pb.ListUserReply{}, nil
  31. }

后面就可以在这里补充具体的业务逻辑处理了。

7、启动服务

  1. # 在根目录下运行
  2. go run main.go

确保运行gRPC server

  1. // main.go
  2. ...
  3. eagle.WithServer(
  4. // init gRPC server
  5. gs,
  6. ),
  7. ...

8、接口调试

调试工具,这里使用 [grpcurl](https://github.com/fullstorydev/grpcurl)

  1. # 查看服务列表
  2. grpcurl -plaintext localhost:9090 list
  3. # Output
  4. api.user.v1.UserService
  5. grpc.health.v1.Health
  6. grpc.reflection.v1alpha.ServerReflection
  7. # 访问列表
  8. grpcurl -plaintext -d '{"user_id":2}' localhost:9090 api.user.v1.UserService/ListUser

参数说明

  • -d 提交的参数, json格式
  • -plaintext 使用纯文本连接,跳过TLS

也可以使用以下工具进行本地测试

部署

两种部署方式

  • docker
  • k8s (本地部署可以使用minikube)

部署步骤

  • 构建docker镜像

    1. docker build -t user-service:v1.0.0 -f deploy/docker/Dockerfile .
  • 打docker tag

    1. docker tag user-service:v1.0.0 qloog/user-service:v1.0.0
  • push tag 到 docker hub

    1. docker push qloog/user-service:v1.0.0
  • 部署到k8s

    1. kubectl apply -f deploy/k8s/go-deployment.yaml
    2. kubectl apply -f deploy/k8s/go-service.yaml

以上命令都是一步一步执行的,为了方便期间,这里也提供了一件部署脚本,执行如下

  1. sh deploy/deploy.sh

项目源码

最终源码在这里:https://github.com/go-microservice/user-service

完结

到此,开发、测试、部署已经操作完了,后面会继续完善链路追踪和监控相关的部分。

感谢阅读, 祝大家 Happy coding~

Go微服务实战 - 用户服务开发(gRPC+Protocol Buffer)的更多相关文章

  1. SpringCloud Alibaba微服务实战三 - 服务调用

    导读:通过前面两篇文章我们准备好了微服务的基础环境并让accout-service 和 product-service对外提供了增删改查的能力,本篇我们的内容是让order-service作为消费者远 ...

  2. 微服务实战——微服务架构选型SpringCloud / Dubbo / K8S比较(一)

    ## 说在前面 大概是三年前,因一些原因公司原项目最初为单体结构部署,所有业务模块都在一个项目里面,而后随着业务的不断膨胀以及模块之间的耦合,导致后面增加或修改一些简单业务时的成本都会变的极大.新入职 ...

  3. Spring Cloud 微服务实战——nacos 服务注册中心搭建(附源码)

    作为微服务的基础功能之一的注册中心担任重要的角色.微服务将单体的服务拆分成不同的模块下的服务,而不同的模块的服务如果进行通信调用呢?这就需要服务注册与发现.本文将使用阿里开源项目 nacos 搭建服务 ...

  4. 微服务实战(六):选择微服务部署策略 - DockOne.io

    原文:微服务实战(六):选择微服务部署策略 - DockOne.io [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺点.随后的文章讨论了微服务不同 ...

  5. 微服务实战(三):深入微服务架构的进程间通信 - DockOne.io

    原文:微服务实战(三):深入微服务架构的进程间通信 - DockOne.io [编者的话]这是采用微服务架构创建自己应用系列第三篇文章.第一篇介绍了微服务架构模式,和单体式模式进行了比较,并且讨论了使 ...

  6. 微服务实战(一):微服务架构的优势与不足 - DockOne.io

    原文:微服务实战(一):微服务架构的优势与不足 - DockOne.io [编者的话]本文来自Nginx官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战 ...

  7. 微服务实战(三):落地微服务架构到直销系统(构建基于RabbitMq的消息总线)

    从前面文章可以看出,消息总线是EDA(事件驱动架构)与微服务架构的核心部件,没有消息总线,就无法很好的实现微服务之间的解耦与通讯.通常我们可以利用现有成熟的消息代理产品或云平台提供的消息服务来构建自己 ...

  8. 微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io

    原文:微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io 这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三 ...

  9. ASP.NET Core微服务实战系列

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. 前言 这里记录的是个人奋斗和成长的地方,该篇只是一个系列目录和构想 ...

随机推荐

  1. 这样优化Spring Boot,启动速度快到飞起!

    微服务用到一时爽,没用好就呵呵啦,特别是对于服务拆分没有把控好业务边界.拆分粒度过大等问题,某些 Spring Boot 启动速度太慢了,可能你也会有这种体验,这里将探索一下关于 Spring Boo ...

  2. 队列Q_via牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28537/L 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语 ...

  3. static关键字和代码块

    static关键字 static修饰的变量称为静态变量/共享变量/类变量 用于修饰类的成员,如成员变量.成员方法以及代码块等,内static修饰的成员具备一些特殊性 1.静态变量 在java类中使用s ...

  4. odoo14 button 事件调用python方法如何传递参数

    1 <field name="user_ids" 2 mode="kanban" 3 nolabel="1" 4 options=&q ...

  5. 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(11)-Fiddler设置安卓手机抓包,不会可是万万不行的!

    1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求. Fiddler能截获 Android 和 Windows Phone 等 ...

  6. 【常见】CSS3进度条Loading动画

    现在,GIF 格式的进度条已经越来越少,CSS 进度条如雨后春笋般涌现.CSS3的崛起,更使得动态效果得以轻松实现,未来,必定是CSS3的天下,所以今天我就来分享一下几个常见的CSS3进度条Loadi ...

  7. CF208E Blood Cousins(DSU,倍增)

    倍增求出祖先,\(\text{DSU}\)统计 本来想用树剖求\(K\)祖,来条链复杂度就假了 #include <cstring> #include <cstdio> #in ...

  8. WPF中使用System.Windows.Interactivity实现事件绑定的替代方法

    一.问题描述 对于 Button 等控件,在 MVVM 中我们能通过 Command 绑定解决 Click 事件.具体如下所示: <Button Margin="10" He ...

  9. ArkUI 组件 Props

    在上一篇博客文章中简单地提到了 Props . 在使用 Props 时需要注意到一个点,子组件从寄主页面传递过来的值是单向的,也就是子组件不能直接修改传递下来的值,即单向性. 以上篇文章定义的头像组件 ...

  10. B/S结构通信系统原理

    本文介绍JavaWeb的B/S结构通信原理 概念:        Javaweb中B/S架构是一种系统架构形式,这里的B是Browser(浏览器),S是Server(服务器),是一种系统的架构形式,有 ...