select + set_keepalive 组合操作引起的数据读写错误

    错误示例代码:

    如果单独执行这个用例,没有任何问题,用例是成功的。但是这段 “没问题” 的代码,却导致了诡异的现象。

    1. local red = redis:new()
    2. red:set_timeout(1000) -- 1 sec
    3. -- or connect to a unix domain socket file listened
    4. -- by a redis server:
    5. -- local ok, err = red:connect("unix:/path/to/redis.sock")
    6. local ok, err = red:connect("127.0.0.1", 6379)
    7. ngx.say("failed to connect: ", err)
    8. return
    9. end
    10. ok, err = red:set("cat", "an animal too")
    11. if not ok then
    12. ngx.say("failed to set cat: ", err)
    13. return
    14. end
    15. -- put it into the connection pool of size 100,
    16. -- with 10 seconds max idle time
    17. local ok, err = red:set_keepalive(10000, 100)
    18. if not ok then
    19. ngx.say("failed to set keepalive: ", err)
    20. return
    21. end

    这时候第二个示例代码在生产运行中,会出现 cat 偶会被写入到数据库 1 上,且几率大约 1% 左右。

    出错的原因在于 错误示例代码使用了 操作,并且使用了长连接,并且还潜伏在了连接池中。

    怎么解决这个问题?

    1. 谁制造问题,谁把问题遗留尾巴擦干净;
    2. 处理业务前,先把 “前辈” 的尾巴擦干净;

    这里明显是第一个好,对吧。