Golang go-redis 包 client 返回 EOF

闻人昊昊
2023-12-01

先叙述一下遇到的问题,一个 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 信息:

  • The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
  • overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
  • you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix thisissue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain thesetting after a reboot. Redis must be restarted after THP is disabled.

具体解决方案可参考如下链接。

redis安装后修改三个地方

全部解决后,重启 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。

最后的最后感谢我的朋友董在高铁上的远程技术支持。

 类似资料: