字节跳动微服务框架Kitex学习之kitex-examples构建踩坑

495 阅读3分钟

field-533541.jpg 题图来自 Pixabay

我是游戏耀西

今天要分享的是 kitex-examples 中的 easy_note 例子。

这个例子的有其对应的文档,github.com/cloudwego/k…

但在实际操作的过程中主要遇到了两个问题,希望能够帮助其他朋友解决这些报错和坑。

一、docker build 有报错

在 kitex-example 仓库的 Readme 中写道:

读过上一篇的朋友应该知道我的开发环境是 Windows 上搭建的,并且借助了 Docker Desktop。

既然这里说可以 docker build,就先 git clone下来,执行 docker build。

git clone https://github.com/cloudwego/kitex-examples.git
cd kitex-examples
docker build -t kitex-examples .

但是。。

报错了。

 ......(执行到7/8报错)
 => [6/8] RUN go env -w GO111MODULE=on                                                                                                                                           0.4s 
 => ERROR [7/8] RUN go build -o hello-client ./hello/client                                                                                                                     55.2s 
------
 > [7/8] RUN go build -o hello-client ./hello/client:
30.84 go: downloading github.com/cloudwego/kitex v0.5.0
30.84 go: downloading github.com/apache/thrift v0.13.0
......(下载很多库)
36.42 go: downloading golang.org/x/text v0.7.0
43.12 # golang.org/x/sys/unix
43.12 /go/pkg/mod/golang.org/x/sys@v0.5.0/unix/syscall.go:83:16: undefined: unsafe.Slice
43.12 /go/pkg/mod/golang.org/x/sys@v0.5.0/unix/syscall_linux.go:2271:9: undefined: unsafe.Slice
43.12 /go/pkg/mod/golang.org/x/sys@v0.5.0/unix/syscall_unix.go:118:7: undefined: unsafe.Slice
43.12 /go/pkg/mod/golang.org/x/sys@v0.5.0/unix/sysvshm_unix.go:33:7: undefined: unsafe.Slice
43.12 note: module requires Go 1.17
------
Dockerfile:25
--------------------
  23 |     RUN go env -w GOPROXY=https://goproxy.io,direct
  24 |     RUN go env -w GO111MODULE=on
  25 | >>> RUN go build -o hello-client ./hello/client
  26 |     RUN go build -o hello-server  ./hello
  27 |
--------------------
ERROR: failed to solve: process "/bin/sh -c go build -o hello-client ./hello/client" did not complete successfully: exit code: 2

解决方案:

修改kitex-example/Dockerfile中的golang版本,1.16.6 ==> 1.18.10

- FROM golang:1.16.6-alpine
+ FROM golang:1.18.10-alpine

感谢 shiw-yang 的 issue 救了一命,希望官方仓库中也能修正一下。

好了,docker build 终于顺利完成,可以在 Docker Desktop 中可以看到编译出来的 image。

从 Dockerfile 和构建过程可以看到,最后是编译了 hello 目录下的 client 和 server,分别输出了可执行文件 hello-client 和 hello-server。

我们开两个 terminal,通过下方的命令行运行一下编译出来的成果。

服务端运行:

docker run --network host kitex-examples ./hello-server
2023/07/28 09:44:45.203311 server.go:81: [Info] KITEX: server listen at addr=[::]:8888

客户端运行

docker run --network host kitex-examples ./hello-client
2023/07/28 09:45:16 Response({Message:my request})
2023/07/28 09:45:17 Response({Message:my request})
2023/07/28 09:45:18 Response({Message:my request})
......(循环输出Response)

hello 运行没问题,我们开始专注于 bizdemo/easy_note 的工程。

二、bridge网络惹的祸

easy_note 的 Readme 文档中提供了一个 Deploy with docker 部分

第一步,没问题。

看下我们的 setup 结果

第二步,需要注意一下,原文说是通过 inspect 命令,获得一个 gateway ip,会用在第三步。 这个 gateway ip 不要找错。

docker inspect easy_note_default

第三步,需要将三个 Dockerfile 的相关IP,替换成第二步这个 IP,这步也问题不大。

第四步,开始出问题了。

粗看是sh语法有问题,实际去看其实没啥问题。

解决方法:

将所有build.sh文件第一行改为: #!/bin/sh

重新执行第四步的 docker build,问题解决。

最终能够构建出三个 image,以备后用

第五步,该启动容器了。有问题。

这一步先要为三个服务创建桥接网络,然后分别在该桥接网络下启动三个服务容器。

然而当我们执行 API 请求的时候,会发现 easy_note/user 和 easy/note 两个服务会宕机。

日志中显示连接不到 172.22.0.1:9910。

9910 端口是啥?我们在 docker desktop 中可以看到,9910 是 mysql 的映射端口。

这里是为啥?思考 5 秒钟。

问题就出在第五步的新建桥接网络 easy_note,并绑定 easy_note 网络创建容器。

在早先第二步,曾经 docker inspect easy_note_default,看到的网段是 172.22.0.0/16,对应的 IP 段是172.22.0.1 到 172.22.255.254。

但第五步我们用 easy_note 网络创建了容器,同样 inspect 一下

docker inspect easy_note

easy_note 和 easy_note_default 对应的网段都不一样,相当于两个子网,所以 ping 都 ping 不通的。

这样我们捋顺了,既然要联通 172.22.0.1:9901,那么我们第五步就在 docker run 的时候直接用 easy_note_default 网络即可。

需要这样:

docker run -d --name user --network easy_note_default easy_note/user
docker run -d --name note --network easy_note_default easy_note/note
docker run -d -p 8080:8080 --name api --network easy_note_default easy_note/api

最终,我们使用 curl 请求接口成功,说明服务没有问题了。

curl --location --request POST '127.0.0.1:8080/v1/user/register'
    "username":"kinggo",
    "password":"123456"
}'

# 请求成功
{"code":0,"message":"Success","data":null}