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