laravel redis Error while reading line from the server.

代码运行一段时间后,会报下面的错误。php

[Predis\Connection\ConnectionException]                              redis

Error while reading line from the server. [tcp://127.0.0.1:6379]服务器

 

最初的怀疑是链接数过多,致使链接不上服务器,出现上述错误。查看进程,发现大量redis状态为TIME_WAIT的tcp链接。tcp

 

首先考虑的是,减小TIME_WAIT的进程,保持随时能够链接到服务器。因此想到的减小TIME_WAIT状态的进程,将进程快速回收。修改内核参数sysctl.conf,net.ipv4.tcp_timestamps=1(1为开启),开启快速回收net.ipv4.tcp_tw_recycle=1。tw_recycle是经过时间戳判断哪一个是最新的进程,将不是最新的TIME_WAIT的进程回收,因此须要先开启tcp_timestamps。php-fpm

修改后观察,果真没有继续报错。server

 

可是使能快速回收TIME_WAIT进程,可能会丢包,致使没有收到应答,不能成功创建链接。但这种办法也不是最佳解决办法,尤为修改内核参数,涉及环节太多,需深刻了解才可修改。进程

 

底层不去修改,就从predis客户端入手,源码发现有read_write_timeout这个参数,能够设置超时时间,这样读取流数据时就不会报错。Predis做者建议设置关闭redis.conf中timeout(修改timeout 0),表示不关闭与客户端的链接,我感受这样比较耗费资源,能够适当增长timeout时间。ip

 

因此此次暂时是这样解决的,设置read_write_timeout=-1和redis.conf的timeout参数。资源

其实有不少解决方式,后续能够继续寻找一个更优的方案。源码

 

比较了常见的两个php链接redis客户端,phpredis和predis。Laravel中使用的predis,其中链接redis使用connect,当请求结束链接关闭。而phpredis使用pconnect链接,依赖于php-fpm,php-fpm不关闭,链接一直都在。再次使用pconnect,链接会被重用,不会再次新建。

 

后来查看predis源码发现,persistent这个参数,手册说明都没有提到,可是看字面意思,可能相似于pconnect方式的持久链接,这个后续再研究一下。

相关文章
相关标签/搜索