概述

如果您没有Golang的基础,应该学习如下前置课程。

  • Golang零基础入门
  • Golang面向对象编程
  • Go Web 基础
  • Go语言开发REST API接口_20240728
  • Go语言操作MySQL开发用户管理系统API教程_20240729
  • Redis零基础快速入门_20231227
  • Go+Redis开发用户管理系统API实战_20240730
  • MongoDB快速入门_20240411
  • Go语言+MongoDB用户管理系统实战_20240730

基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。

课程特色

本教程录制于2024年7月31日,使用Go1.22版本,基于Goland2024进行开发,采用的技术栈比较新。

每节课控制在十分钟以内,课时精简,每节课都是一个独立的知识点,如果有遗忘,完全可以当做字典来查询,绝不浪费大家的时间。

整个课程从如何搭建Go语言gRPC环境讲起,然后如何创建proto文件,如何实现基本的gRPC为辅,如何开发增删改查的用户微服务,层层递进,学习路径平缓。

Golang是当前国内越来越多的企业正在全面转的一门系统级别的高性能的编程语言,比C语言写法更加的简单,比Python性能更加的好,是新时代的C语言,建议每个程序员都掌握!

视频课程

最近发现越来越多的公司在用Golang了,所以精心整理了一套视频教程给大家,这个是其中的第10部,后续还会有很多。

视频已经录制完成,完整目录截图如下:

Go语言 Vue3零基础入门全栈班10 Go语言 gRPC用户微服务项目实战 2024年07月31日 课程笔记_微服务

本套课程的特色是每节课都是一个核心知识点,每个视频控制在十分钟左右,精简不废话,拒绝浪费大家的时间。

课程目录

  • 01 概述
  • 02 搭建Go语言gRPC微服务开发环境
  • 03 下载go-grpc官方的示例代码
  • 04 编写简单的proto文件
  • 05 根据proto文件自动生成Go代码
  • 06 创建grpc的服务端
  • 07 创建grpc的客户端
  • 08 定义用户微服务的proto文件
  • 09 生成用户微服务的go代码
  • 10 开发用户微服务服务端基本代码
  • 11 开发用户微服务客户端的基本代码
  • 12 创建用户表
  • 13 连接到MySQL数据库
  • 14 实现新增用户的微服务方法并测试
  • 15 实现查询所有用户的微服务方法并测试
  • 16 实现根据ID查询用户的微服务方法并测试
  • 17 实现修改用户的微服务方法并测试
  • 18 实现删除用户的微服务方法并测试
  • 19 总结

完整代码

04 编写简单的proto文件

syntax = "proto3";

// go项目包的位置
option go_package = "grpc_demo/helloworld";

// 包名
package helloworld;

// 服务:微服务
service Greeter {
  // 方法
  rpc SayHello(HelloRequest) returns (HelloReply) {}
}

// 请求对象
message  HelloRequest{
  // 参数
  string name = 1; // 1 表示的是参数在第几个位置,从1开始
}

// 响应对象
message HelloReply{
  string message = 1;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

05 根据proto文件自动生成Go代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld/helloworld.proto
  • 1.

06 创建grpc的服务端

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 pb "grpc_demo/helloworld"
 "net"
)

// 服务对象
type server struct {
 pb.UnimplementedGreeterServer
}

// SayHello 实现方法
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
 fmt.Println("接收到的名字是:", in.Name)
 return &pb.HelloReply{Message: "你好 " + in.Name}, nil
}

func main() {
 // 创建监听器
 lis, err := net.Listen("tcp", ":8080")
 if err != nil {
  fmt.Printf("failed to listen: %v", err)
  return
 }

 // 构建grpc服务
 grpcServer := grpc.NewServer()
 pb.RegisterGreeterServer(grpcServer, &server{})

 // 启动微服务
 err = grpcServer.Serve(lis)
 if err != nil {
  fmt.Printf("failed to serve: %v", err)
 }
}
  • 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.

07 创建grpc的客户端

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/helloworld"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewGreeterClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 helloReply, err := client.SayHello(ctx, &pb.HelloRequest{Name: "李四"})
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(helloReply.GetMessage())

}
  • 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.

08 定义用户微服务的proto文件

syntax = "proto3";

// go项目包的位置
option go_package = "grpc_demo/c02_user/proto";

// 包名
package proto;

// 服务:微服务
service UserMicroService {
  rpc Add(AddRequest) returns (CommonReply) {}
  rpc Delete(IdRequest) returns (CommonReply) {}
  rpc Update(UpdateRequest) returns (CommonReply) {}
  rpc GetByID(IdRequest) returns (CommonReply) {}
  rpc GetAll(EmptyRequest) returns (CommonReply) {}
}

message  AddRequest{
  string name = 1;
  int64 age = 2;
}
message  UpdateRequest{
  int64 id = 1;
  string name = 2;
  int64 age = 3;
}
message  IdRequest{
  int64 id = 1;
}
message  EmptyRequest{
}

message CommonReply{
  bool status = 1; // 成功或者失败
  string  message = 2; // 详细信息
  string  data = 3; // 返回的数据,JSON格式
}
  • 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.

12 创建用户表

drop table if exists user;
create table user
(
    id   int primary key auto_increment,
    name varchar(36),
    age  int
);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

14 实现新增用户的微服务方法并测试

这里是微服务服务端的完整代码,后续的只是客户端测试代码。

服务端代码:

package main

import (
 "context"
 "database/sql"
 "encoding/json"
 "fmt"
 "github.com/zhangdapeng520/zdpgo_mcrud"
 _ "github.com/zhangdapeng520/zdpgo_mysql"
 "google.golang.org/grpc"
 pb "grpc_demo/c02_user/proto"
 "net"
 "strconv"
)

var (
 db  *sql.DB
 err error
)

func initMySQL() {
 dbUrl := "root:root@tcp(127.0.0.1:3306)/test"
 db, err = sql.Open("mysql", dbUrl)
 if err != nil {
  fmt.Println(err)
  return
 }
}

func closeMySQL() {
 db.Close()
}

type User struct {
 Id   int64  `json:"id"`
 Name string `json:"name"`
 Age  int    `json:"age"`
}

// 服务对象
type server struct {
 pb.UnimplementedUserMicroServiceServer
}

func (s *server) Add(ctx context.Context, in *pb.AddRequest) (*pb.CommonReply, error) {
 fmt.Println("接收到的名字是:", in.Name, in.Age)
 zdpgo_mcrud.Add(
  db,
  "user",
  []string{"name", "age"},
  []interface{}{in.Name, in.Age},
 )
 result := &pb.CommonReply{
  Status:  true,
  Message: "success",
 }
 return result, nil
}

func (s *server) GetAll(ctx context.Context, in *pb.EmptyRequest) (*pb.CommonReply, error) {
 data, _ := zdpgo_mcrud.GetBy(
  db,
  "user",
  []string{"id", "name", "age"},
  nil,
 )
 jsonData, _ := json.Marshal(data)
 result := &pb.CommonReply{
  Status:  true,
  Message: "success",
  Data:    string(jsonData),
 }
 return result, nil
}

func (s *server) GetByID(ctx context.Context, in *pb.IdRequest) (*pb.CommonReply, error) {
 data, _ := zdpgo_mcrud.GetBy(
  db,
  "user",
  []string{"id", "name", "age"},
  map[string]interface{}{"id": in.Id},
 )
 jsonData, _ := json.Marshal(data)
 result := &pb.CommonReply{
  Status:  true,
  Message: "success",
  Data:    string(jsonData),
 }
 return result, nil
}

func (s *server) Update(ctx context.Context, in *pb.UpdateRequest) (*pb.CommonReply, error) {
 zdpgo_mcrud.Update(
  db,
  "user",
  strconv.FormatInt(in.Id, 10),
  []string{"name", "age"},
  []interface{}{in.Name, in.Age},
 )
 result := &pb.CommonReply{
  Status:  true,
  Message: "success",
 }
 return result, nil
}

func (s *server) Delete(ctx context.Context, in *pb.IdRequest) (*pb.CommonReply, error) {
 zdpgo_mcrud.Delete(
  db,
  "user",
  strconv.FormatInt(in.Id, 10),
 )
 result := &pb.CommonReply{
  Status:  true,
  Message: "success",
 }
 return result, nil
}

func main() {
 initMySQL()
 defer closeMySQL()

 // 创建监听器
 lis, err := net.Listen("tcp", ":8080")
 if err != nil {
  fmt.Printf("failed to listen: %v", err)
  return
 }

 // 构建grpc服务
 grpcServer := grpc.NewServer()
 pb.RegisterUserMicroServiceServer(grpcServer, &server{})

 // 启动微服务
 err = grpcServer.Serve(lis)
 if err != nil {
  fmt.Printf("failed to serve: %v", err)
 }
}
  • 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.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.

客户端代码:

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/c02_user/proto"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewUserMicroServiceClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 commonReply, err := client.Add(ctx, &pb.AddRequest{Name: "张三", Age: 23})
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(commonReply.GetStatus())
 fmt.Println(commonReply.GetMessage())
}
  • 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.

15 实现查询所有用户的微服务方法并测试

服务端代码看地14节课的。

客户端代码:

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/c02_user/proto"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewUserMicroServiceClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 commonReply, err := client.GetAll(ctx, &pb.EmptyRequest{})
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(commonReply.GetStatus())
 fmt.Println(commonReply.GetMessage())
 fmt.Println(commonReply.GetData())
}
  • 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.

16 实现根据ID查询用户的微服务方法并测试

服务端代码看地14节课的。

客户端代码:

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/c02_user/proto"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewUserMicroServiceClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 commonReply, err := client.GetByID(ctx, &pb.IdRequest{Id: 1})
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(commonReply.GetStatus())
 fmt.Println(commonReply.GetMessage())
 fmt.Println(commonReply.GetData())
}
  • 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.

17 实现修改用户的微服务方法并测试

服务端代码看地14节课的。

客户端代码:

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/c02_user/proto"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewUserMicroServiceClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 commonReply, err := client.Update(ctx, &pb.UpdateRequest{
  Id:   1,
  Name: "李四333",
  Age:  24,
 })
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(commonReply.GetStatus())
 fmt.Println(commonReply.GetMessage())
}
  • 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.

18 实现删除用户的微服务方法并测试

服务端代码看地14节课的。

客户端代码:

package main

import (
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
 pb "grpc_demo/c02_user/proto"
 "time"
)

func main() {
 // 创建客户端
 conn, err := grpc.NewClient("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // 创建指定微服务的客户端
 client := pb.NewUserMicroServiceClient(conn)

 // 调用微服务的方法
 ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancelFunc()
 commonReply, err := client.Delete(ctx, &pb.IdRequest{Id: 1})
 if err != nil {
  fmt.Println(err)
  return
 }

 // 处理响应
 fmt.Println(commonReply.GetStatus())
 fmt.Println(commonReply.GetMessage())
}
  • 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.

总结

整个课程从如何搭建Go语言gRPC环境讲起,然后如何创建proto文件,如何实现基本的gRPC为辅,如何开发增删改查的用户微服务,层层递进,学习路径平缓。

通过本套课程,能帮你入门Go语言通过gRPC开发微服务项目的技术。

如果您需要完整的源码,打赏20元即可。

人生苦短,我用PyGo,我是您身边的Python私教~

本文使用  markdown.com.cn 排版