0%

I have to learn how too find the error

无语的一晚

无语到想要直接用中文写……

因为最近在啃 React ,翻到了某站一个关于 React、TypeScript 的教程。作者给出的API接口是用 Docker 镜像做的。我就顺手看了之前下的 Docker 视频。大概学了 Docker 和 docker-compose ,然后把作者的项目拉到土豆机上跑。跑起来问题很大……

200!但报错

首先我自以为服务正常启动了,因为启动时敲了参数 -d ,后台运行。没有看到日志输出状况。然后我访问土豆机的公网地址,想看一下swagger文档,发现有个 swagger-ui-bundle.js 文件一直报错。

错误显示为 net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)

我搜了一下,怎么说的都有,有说磁盘空间不够的,有说加载时间太长超时被阻止了,有说nginx配置不对的。我折腾了半天,发现问题是……作者自己把nginx配置写错了,少写了分号。这还是我查看了 error.log 才发现……

自行编译 go 🈶

然后问题来了,swagger文档无法正常读取接口数据,因为作者写死了地址是 localhost ,而我是在公网访问。于是我就只能自己去把作者的 go 代码拉到土豆机上自己尝试编译。

具体代码逻辑不研究,我大概看了下导入导出模块之类的规则,然后找了一下 swagger 定义的地方。这中间我还手贱删掉了一行代码,因为我自以为它不需要…… 当然,事实是没删也没用,docs还是得我自己整出来。

修改好了地址,我尝试编译。第一次编译的时候下载模块信息很多,我自以为成功了…… 翻了半天没看到编译产物,又迷茫了很久。于是再次编译看了一下输出。发现一个校验模块的中文翻译库无法找到。我就只能各种搜索如何正确引入。但是找不到例子,我就只能去看 github 上官方的文件。于是我发现作者的引入路径弄错了一个大写,不知道是更新所致还是本来就写错了。

成功编译?

因为我是单独拉一个文件夹放后端源码,编译后我copy到了根目录,然后火速 docker-compose up 。问题又来了。

简单讲,第一,我没有引入 swagger 文档需要的 json 数据。第二,目录中本来就没有 json 数据。我需要下载 swag 库进行docs生成。这个下载又废了我九牛二虎之力,下载是从 github 上下,但是下载了之后我也看不出到底成功没,反正二进制文件是没有的,command 也是 not find。于是我从 github 上下了预编译的二进制文件自己扔进 /usr/bin 。再生成文档。

万事俱备(个屁)

看起来只欠东风了,我跑起 docker ,再一看,还是疯狂 200 但报错。但这个我大胆猜测是因为依赖文件太大了。(也是因为我不想再看了)因为我多次刷新后终究是刷出来了。

研究 viper

成功读出接口文档后,我测了一下登录接口,报了500错误。打开土豆机的输出日志看了看,有问题。于是我又回想起了启动时 go 报错无法连接 mysql 。我以为它已经自动重连上了,然而并没有。经过我一番排查,config 无法读取本地的数据库配置值,导致连接不成功。

简单总结,作者把 env.yaml 加入了 git 的忽略文件中,同时我还发现了 docs 即上方那个 swagger 的文档也被忽略了。配置文件忽略就算了,swagger 文档也忽略掉什么意思……好歹给个模板在这儿吧。

然后自己新建配置文件让 viper 读取。

“admin.admins doesn’t exists”

再跑,还是报错。看了一下是提示数据表不存在。我以为启动就会自动建表,还是我太年轻太天真。查了一下,自动建表需要调用 AutoMigrate 方法。搜索了一下,发现作者确实写了自动建表,但需要自行加参数调用一次。……

按序执行

中途我想让 docker-compose 的三个任务按顺序执行。比如 go 需要连接数据库,但是数据库启动得慢,我想让数据库先启动好再让 go 去连接。然后我试了一下用 wait-for-it.sh 脚本。

问题又来了,首先是 permision denied ,这个好说,修改一下权限就好。

然后再执行,提示 wait-for-it.sh 不存在。我:?

思考一番后,放弃了这个脚本。直接使用 depends_on 字段。但是依然跑不了。

读取变量

又是一番排查,问题来了,因为没有读取到数据库变量配置。

image-20210516155436430

把 env.yaml 映射到容器内。解决。然后还是报错。

image-20210516155456248

go 尝试连接 127.0.0.1:3306 的数据库,但是 connection refused 。查询了一下,因为这里 go 和 mysql 配置到了同一个网络下,应该用容器名称来进行DNS解析实现局域网访问。但是我觉得问题应该不在这里,毕竟 mysql 也映射到了本地3306端口的。

image-20210516155341450

我觉得问题应该还是数据库拒绝了访问。查了一下此类问题,大抵都是说修改用户访问权限一类的,但是我基本上复制来的代码都报了语法错误。最终在这个地方我看到了一个可能是问题关键的点。每个user都对应一个可访问host,我进入mysql 容器,查询了一下,果然发现问题。

image-20210516155259221

很无奈,delete 语句写了半天没写对,还得查一下怎么写。

root用户存在两条记录,一条是通配符,一条限定了 localhost 。我想问题就出在这里,导致了局域网的访问被拒绝。删掉那条限定本地的记录后,再跑服务,就没有报错了。

又报错了……哈哈,我选择放弃。