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

news2025/1/12 21:04:41

概述

如果您没有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部,后续还会有很多。

视频已经录制完成,完整目录截图如下:
在这里插入图片描述

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

课程目录

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

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

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

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)
	}
}

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())

}

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格式
}

12 创建用户表

drop table if exists user;
create table user
(
    id   int primary key auto_increment,
    name varchar(36),
    age  int
);

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)
	}
}

客户端代码:

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())
}

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())
}

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())
}

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())
}

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())
}

总结

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1968678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型下的视频理解video understanding

数据集 Learning Video Context as Interleaved Multimodal Sequences Motivation: 针对Narrative videos, like movie clips, TV series, etc.:因为比较复杂 most top-performing video perception models 都是研究那种原子动作or人or物 understandin…

C++ 布隆过滤器

1. 布隆过滤器提出 我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉 那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用 户看过的所有历史…

OpenStack——存储服务

存储侧: 块存储 文件存储 对象存储 存储简介 特点: 1、OS盘只能使用块存储 2、不能实现共享【不能解决两个主机同时去读写同一个block的问题】 3、性能最优 filesystem——文件存储 VIMS:高可用文件系统 ——提供了锁机制 对象存储 ——解…

MySQL搭建主从复制和读写分离(数据库管理与高可用)

集群: 高可用; 负载均衡; 高性能 1、MySQL主库在事务提交时把数据变更(insert、delet、update)作为事件日志记录在二进制日志表(binlog)里面。 2、主库上有一个工作线程 binlog dump thread…

蓝桥杯 DNA序列修正

今天再刷蓝桥的题目时,发现这道题目的第二种更为简洁的做法; 首先题目描述如下: 样例输入 5 ACGTG ACGTC 样例输出 2 对于这道题目,我们想的是用两个数组将其分别存储下来,然后再根据A-T、G-C的配对关系将数组二&a…

【C语言】堆排序

堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1. 建堆 升序:建大堆 降序:建小堆 原因分析: 若升序建小堆时间复杂度是O(N^2) 升序建大堆,时间复杂度O(N*logN) 所以升序建大堆…

记一次对HTB:Carpediem的渗透测试

信息收集 端口扫描 通过nmap对靶机端口进行探测,发现存在22和80端口。 访问web页面。发现是一个静态页面,没有可利用的部分。 目录扫描 子域枚举 通过对域名进行fuzz子域名,发现存在portal一级域名。 将它加入/etc/hosts,访问之…

vue3+gsap实现圆形路径动画

同学们可以私信我加入学习群! 正文开始 前言一、引入并使用gsap二、详解gsap.to的各参数三、路径svg四、其他路径文字路径动画总结 前言 我开发的桌面端软件最近增加了在线更新功能,其中更新动画部分是由gsap实现的,整体实现思路已经在elect…

用Python打造精彩动画与视频,3.2 基本的剪辑和合并操作

3.2 基本的剪辑和合并操作 在这一节中,我们将学习如何使用 MoviePy 库对视频进行基本的剪辑和合并操作。MoviePy 是一个用于视频编辑的 Python 库,可以轻松地实现视频的剪辑、合并、添加音频等操作。 准备工作 首先,确保你已经安装了 Movi…

花几千上万学习Java,真没必要!(三十九)

1、BufferedReader的使用: 测试代码: package test.com; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class FileReadToList { pu…

OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI基本开发步骤(三)

引言 前面文章OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI(一) 和 OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI 常见的函数详解(二)介绍了NAPI的基础理论知识,今天重点介绍下如何去开发一个自己的NAP…

maven插件2(spring-api-auth-valid-plugin)

https://maven.apache.org/guides/mini/guide-configuring-plugins.htmlhttps://maven.apache.org/plugin-testing/maven-plugin-testing-harness/getting-started/index.html plugin-desc 业务功能 所有的endpoint,必须带有指定的安全校验标签,如spring-security的PreAuthori…

RabbitMQ 集群安装

在 linux 下手动安装 RabbitMQ 集群。 准备 安装之前的准备工作。 准备内容说明其他3 台服务器centos、redhat 等ErlangRabbitMQ 运行需要的基础环境socatRabbitMQ 运行需要的基础环境logrotateRabbitMQ 运行需要的基础环境这个服务器一般自带了 下面的安装示例中使用的版本…

一键测量仪,能否彻底解决燃气灶配件缺陷问题?

燃气灶配件是指用于燃气灶的附件或零部件,用于安装、维护或改进燃气灶的功能和性能。这些配件通常包括各种零部件、附件和替换件,以确保燃气灶的正常运行和安全使用。燃气灶的火焰头是产生火焰的部件,通常根据不同的燃气类型和火力需求选择合…

python-求四位数(赛氪OJ)

[题目描述] 3025 这个数具有一种独特的性质:将它平分为二段,即 30 和 25,使之相加后求平方,即 (3025)^2,恰好等于 3025 本身。请求出具有这样性质的全部四位数。输入格式: 此题没有输入。输出格式&#xff…

详解并掌握AXI4总线协议(一)、AXI4-FULL接口介绍

系列文章目录 文章目录 系列文章目录一、AXI介绍二、AXI4、AXI-Lite、AXI4-Stream区别三、AXI4读写架构3.1 通道定义3.2 读突发时序3.3 写突发时序 四、AXI4-FULL 总线信号介绍4.1全局信号4.2 写地址通道信号4.3 写数据通道信号4.4 写响应通道信号4.5 读地址通道信号4.6 读数据…

Animate软件基础:在时间轴中添加或插入帧

FlashASer:AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer:实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer:Animate教程及作品源文件https://zhuanlan.zhihu.co…

抖音爆火的“拆盲盒”直播,是如何将昂贵的废品卖给消费者的?

抖音直播间掀起了一股“拆盲盒”热潮。 最初,这股热潮主要集中在拆卡直播间。一盒10包起卖的卡牌,价格在100~200不等。拆卡主播拿起剪刀行云流水的开盒、拆卡、过牌,一晚上能轻松跑出数万元的营业额。数据显示,头部卡牌公司卡游仅…