先叙述一下遇到的问题,一个 web 后台验证用户登录信息,通过 Redis 取 token 来获取 user ID。结果发现页面上过不了多久就有前端请求返回 401 unauthorized 的错误,但是并不会跳回登录页面,检查 session 正常。查看日志发现是通过 Redis 取 token 这一步返回 EOF 的 error。
接下来就是各种 google,看到底是为什么会有这个错误。一开始以为是超时导致的,所以打算将 client 的 timeout 设的长一些。结果发现并没有解决。
无意中在查看并重启 Redis 进程时发现 Redis 的进程号变了,再次查看代码,发现我利用 go-redis 的 NewRedisClient 获取的是一个 client 实例,该实例会从 connection pool 中获取 Redis 连接,但 Redis 重启则会导致 connection pool 中没有连接可用,所以返回 EOF。但此操作会触发 client 重新连接,所以之后一段时间页面不会返回错误,直至 Redis 再次重启。
所以问题就变成了怎么解决 Redis 不断重启的问题,查看 Redis 日志 (/var/log/redis/redis-server.log) 发现 warning 信息:
具体解决方案可参考如下链接。
全部解决后,重启 Redis 发现不报 warning 信息了,但是用 systemctl restart 会卡住,且报:
PID file /var/run/redis/redis-server.pid not readable (yet?) after start: No such file or directory.
真的智障。。。 apt install 没有自动创建目录 - -,于是手动创建 /var/run/redis/ 并修改权限:
chown redis.redis -R /var/run/redis
因为 Redis 是以 redis 用户运行的。
再次 systemctl restart redis,重启成功 - -,过十分钟之后并未重启,页面也正常未报错。
最后总结:Redis 由于未找到写入 PID 的目录,于是会 error 重启 -> 导致 go-redis 获取 client 连接失效 -> 导致代码获取 user token 失败,返回 EOF 异常 -> 页面显示 401 unauthorized。
最后的最后感谢我的朋友董在高铁上的远程技术支持。