go-zero初体验
2024-02-26 15:13:18

最近由于参与了一个社区项目,需要用到 go-zero,也需要用到 grpc。在群里听大佬们聊了很久的微服务,这次终于自己上手试试了。

环境

微服务框架:go-zero
数据库:postgresql
缓存:redis
注册中心:etcd

开发环境搭建

go-zero 根据官网安装一下就好了,同时也会自动把 goctl 工具装好。
pg、redis、etcd 都使用 docker 启动就 ok。
时隔几年,又用上了数据库,真怀恋啊,可惜 SQL 都已经忘完了,导致在部署环境的时候还是浪费了不少时间。

使用 pg 来创建数据库、创建表。参考 https://www.runoob.com/postgresql/postgresql-autoincrement.html
不得不说,菜鸟教程是真的好使。
通过 docker exec 或者 kubectl exec 进入容器。然后可以使用 psql 命令进入 pg 的命令行。此时有可能会出现以下错误

1
psql: error: could not connect to server: FATAL: role "root" does not exist

出现这个错误的原因是目前是以 root 用户登陆,但是 pg 默认是没有 root 用户的,在 pg 中默认的超级管理员用户是 postgres ,因此要指定使用 postgres 用户登陆。

1
psql -u postgres

还有一点需要注意,pg 的连接方式应当是这样的

1
postgres://{user}:{password}@172.16.238.20:5432/go-zero-devops?sslmode=disable

补充一点,pg 中创建用户并授权

  1. 创建数据库新用户:
    1
    CREATE USER dbuser WITH PASSWORD '<CUSTOM PASSWORD>';
  2. 创建数据库:
    1
    CREATE DATABASE exampledb OWNER dbuser;
  3. 将 exampledb 数据库的搜索权限都赋予给 dbuser :
    1
    GRANT ALL PRIVILEGES ON DATABASE exampledb TO dbuser;

GRPC 开发

使用 go-zero 来进行 grpc 开发,我愿称之为傻瓜式开发,熟悉 go 开发的人,花上几个小时看看文档,就足够开始进行 CRUD 了,然后遇到问题再查问题,解决问题。

API 服务

跟着 go-zero 官网文档 ,把 goctl 装好,定义好 .api 文件– “.api” 文件是 go-zero 特有的文件格式,用于定义接口的方法和数据结构,goctl 工具可以通过这个 “.api” 一键生成相应的方法,我们所要做的就是在方法里补充业务逻辑即可。

个人认为初期的时候程序员不应该过于依赖这样的工具,业务开发确实省事,但是缺少了从零到一的过程,如果从一开始就从别人搭建好的完整的架子上进行开发,等后面换一个框架,又得恶补一波知识,并且永远只能跟着用别人的框架。总之,我不喜欢这样大而全的框架。

RPC 服务

和 API 服务需要放到不同的文件下,定义该服务的 .proto 文件,通过 goctl 或者 protoc-gen-go-grpc 这些工具来生成对应的代码,这里由于是使用 go-zero,所以我们需要使用 goctl 来生成,并且这里我不会给出示例代码。go-zero 一直在更新迭代,可能会导致旧的使用方式无效,所以在任何时候,都建议去看官方文档怎么写的,以及官方的 demo 代码仓库;这样很累,很麻烦,但是写代码就是这样的,无论是中文互联网,还是国外,很多时候搜到的答案可能都是过时的。

这里插一个遇到的小坑,go-zero 项目中,API 服务的 etc 目录下的配置文件,和 RPC 目录下 etc 的配置文件,在填写注册中心的时候不一样,当然本来就不应该一样,但是我当时太大意了,第一眼以为就是一样的,然后直接 cv 过去,导致后来一直访问不到 etcd。。。

看下两个的区别

rpc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Name: user.rpc

ListenOn: 0.0.0.0:8080

Etcd:

Hosts:

- 172.16.238.10:2379

Key: user.rpc

DataSource: postgres://postgres:[email protected]:5432/go-zero-devops?sslmode=disable

Table: user

Cache:

- Host: 172.16.238.30:6379

api

注意,这里的 etcd,是在 user 服务下的,如果按这样的逻辑,是不是这个框架可以支持多个微服务使用多个注册中心呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Name: user-api

Host: 0.0.0.0

Port: 8888

User:

Etcd:

Hosts:

- 172.16.238.10:2379

Key: user.rpc

k8s 部署

部署到 k8s 就比较简单了,通过 helm 将 redis、etcd、pg 都安装好,参考上面的步骤进入 pg 把数据库和表都建好。通过 goctl 生成 k8s deploy 所需的配置文件。这里要注意, goctl 生成的文件中不包含 configmap,我们为了方便修改服务的配置,所以额外增加了一个 configmap 来修改配置。

使用 ConfigMap 挂载文件

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#understanding-configmaps-and-pods

示例: https://github.com/zaunist/go-zero-devops/tree/main/deploy

ingress

部署到 k8s 之后,为了让集群外部也能访问到,所以还需要创建一个 ingress 资源,这种类似的资源,可以去看下集群中其他的 ingress,拷贝一个下来,把 label 和注解都删掉,配置好 host、path 以及 namespace 就行了。

总结

go-zero 确实方便,一键生成代码,一键生成 Dockerfile,一键生成 k8s deploy 文件;可是如果没有能够 debug 的能力,在执行一键的操作中如果发生错误,那开发者会直接变麻瓜。这样的框架适合公司开发,约束所有人使用同一套规范,使用同一套风格;但是这种开发方式对个人来说是弊大于利,依赖于工具给人提供的便利,会让人变得越来越懒,越来越不愿意思考,而开发中最重要的就是思考。