哈哈哈哈,兜兜转转还是接触到了 Go。其实 Go 语言很早就知道了,但是一直没有上手体验过,一方面是当时没有太多时间 (好吧,其实是打游戏去了)。另一方面是因为 Go 的依赖下载以及语法,当时浅浅看了一下,觉得接受不了,然后就没有再看过了。
一个偶然的机会,在电鸭平台看到了远程开发的项目,使用的是 Go 语言。自己正好没有工作,觉得可以试试,就加入了。还好,经过简单的面试,团队的小伙伴接受了我这个 Java 系的菜鸡。于是就有了现在的整理。
Go 虽然也是 GC 语言,但是它的速度是秒杀 Java 的,而且在系统资源占用方面甩 Java 十条街。这都得益于 Go 语言的优化,貌似之前听过有位大佬讲过 Go 的语法丑就是为了效率而妥协的设计。
配置
- Go 1.23+
- VsCode latest
首先就是环境配置了,这是每门语言入门的第一步,官网下载 适合自己操作系统的安装包进行安装,然后设置代理,没办法,Go 的依赖包都在 Github 上,国内直接拉取的话emmm,你懂的。
1$ go env -w GO111MODULE=on
2$ go env -w GOPROXY=https://goproxy.cn,direct
浪子这次使用 VsCode 作为开发 Go 语言的 IDE。个人现在越来越觉得破解麻烦了,几乎所有的工具都找了开源替代,而且 Go 比较轻量,就不用 JB 家的 Golang 了。不过 JB 家的 IDEA 一直在用,这个有 EAP 就 EAP,没有就先 community 顶上,习惯了。
VsCode 安装以下插件:
Go :这是官方提供的一个插件; vscode-proto3 :proto 的支持;
插件安装完后,在 VsCode 中使用快捷键 Ctrl+Shift+P,在输入框中输入 go install,然后选择 Go:Install/Update Tools。这一步最好是代理设置完之后再下载,否则很有可能因网络问题而失败。
Go 的基础知识
Go 在 1.16 版本是 mod 的一个分水岭,包含大量的更新,命令有较大的变化。重要的就是使用 go install
来全局安装二进制执行文件,而不推荐使用 go get
。
常用命令:
1# 初始化目录
2go mod init
3
4# 更该 go.mod 依赖
5go get
6
7# 维护和更新依赖
8go mod tidy
9
10# 安装二进制文件,这是全局安装的
11go install
12
13# 打包
14go build
15
16# 运行测试
17go test
- mod 就是 module(模块) 的意思。
go.mod
所在的目录就是一个模块,一个模块可以有多个包(package)。 go mod tidy
命令是经常使用的,用于维护和更新项目的go.mod
和go.sum
文件,以保证依赖的完整性和正确性。go install
是全局安装的,所以这样安装的工具命令行可以直接使用。类似于npm i -g
安装的二进制程序。
go-zero
gin、gorm、gRPC、go-zero 这四件套非常有名,gRPC 甚至都能在 Java 打出不同凡响的名声,由于它自身是 Go 语言编写的,自然更加的逃不了。
go-zero 是 Go 生态的一个微服务框架,用了之后你会发现它确实很香,Go 中的微服务搭建真是太太太简单了,还有 gPRC 的集成,简直甩 Java 百千条街。。。
想要学好 go-zero,官方文档 是逃不掉的,最重要的也是最基础的就是 goctl 的使用。
首先我们要下载 goctl 到本地,这个东西就像 cargo/npm/pnpm/yarn 一样,是 go-zero 的总管,开发过程中几乎所有步骤都离不开它。
1# go 1.16+ 使用该命令
2$ go install github.com/zeromicro/go-zero/tools/goctl@latest
只安装这一个就行了,其它的如 protoc、go-gen 等工具用到的时候使用 goctl 会自动下载。
一个简单的 RPC demo
最直观的体验就是上手实操一个小 demo,注意,这个 demo 属于 gPRC 的,而不是创建的 api 服务,这点需要注意。
1mkdir demo
2cd demo
3
4touch user.proto
写一点儿内容:
1syntax = "proto3";
2
3package demo;
4
5option go_package = "./demo";
6
7message User {
8 int32 id = 1;
9 string name = 2;
10 string address = 3;
11 string bir = 4;
12}
13
14message UserRequest {
15 int32 id = 1;
16}
17
18message UserResponse {
19 User user = 1;
20}
21
22service UserService {
23
24 rpc GetUserById(UserRequest) returns (UserResponse);
25
26}
保存后,继续命令,这里使用了 goctl rpc protoc 命令,具体的选项说明查看官方的文档说明。由于本文上面只安装了 goctl,所以这一步会自动下载需要的组件。
1goctl rpc protoc user.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=. --client=false
2
3# 整理依赖
4go mod tidy
此时还不能运行,需要打开 ./etc/user.yaml
文件注释掉下面的几行内容,否则在未安装 ETCD 的情况下该服务无法启动,ETCD 是一个微服务注册中心。
1Name: user.rpc
2ListenOn: 0.0.0.0:8080
3# Etcd:
4# Hosts:
5# - 127.0.0.1:2379
6# Key: user.rpc
这是因为 goctl 生成最小化 gRPC 服务默认启动会向 ETCD 注册中心注册当前服务的信息,本次演示就不需要注册中心,所以删除了配置文件中的注册中心配置。
1# 运行
2go run user.go
然后使用支持 rpc 调用的工具测试即可。
一个简单的 API demo
新建文件 user.api
,加入以下内容。关于 API 的语法本文不再赘述,请查看 官方文档
,有详细的说明
1syntax = "v1"
2
3type LoginReq {
4 Usename string `json:"username"`
5 Password string `json:"password"`
6}
7
8type LoginResp {
9 Id int64 `json:"id"`
10 Name string `json:"name"`
11 Token string `json:"token"`
12 Expire string `json:"expire"`
13}
14
15// 定义接口服务:请求方式、请求路径、调用方法
16service user {
17 @handler Login
18 post /user/login (LoginReq) returns (LoginResp)
19}
然后执行以下命令生成 API 内容并完善返回信息:
1goctl api go -api user.api -dir .
1
2...omit other
3
4func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
5 // 打印接收的 json 请求体
6 fmt.Println(req.Usename, req.Password)
7
8 return &types.LoginResp{
9 Id: 1,
10 Name: req.Usename,
11 Token: req.Password,
12 Expire: "2022-01-01",
13 }, nil
14}
接下来就到了激动人心的整理依赖、启动,开始测试的环节喽!
1# 整理依赖
2go mod tidy
3# 运行
4go run user.go
5# 测试
6curl http://localhost:8888/user/login -X POST -H 'Content-Type: application/json' -d '{"username":"jhlz", "password":"123"}'
评论