题图来自 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}