这两天在学习 Redis,因为 Redis 在 Windows 上的表现并不好,而且线上环境基本上都是 Linux,所以选择在 CentOS 7 上跑跑例子。在安装完 Redis 的 PHP 客户端 phpredis ,测试连接时,碰到这个问题,特此记录。
问题
开始在 Redis 上使用 redis-cli 跟着敲命令还没出现问题,后来需要使用 Redis 的 PHP 客户端 phpredis,在测试连接时,出现了问题。
phpredis 是作为 PHP 的模块安装的,安装完以后,可以在 phpinfo 里看到,模块已经加载成功。
打开 redis-server 服务,通过浏览器,使用下面的代码测试连接 Redis 时,死活连不上,打开 F12,点击 Network,报 500。
1 |
|
解决
过程
开始出现这个问题时,我最先想到是版本的问题,因为 PHP 是直接通过 yum 安装的,装完才发现是 5.4 的版本,比较老, 而 phpredis 是使用源码安装的最新版。猜测到可能是版本问题后,我把 PHP 5.4 及其所有的模块都卸载了,然后换源,安装上了 PHP 7.0,同时再次装上了 phpredis。通过浏览器访问测试代码时,依旧连不上,依旧 500,排除掉版本的问题,我已经不知道可能的原因了。
说一下,我的电脑是 Windows + Ubuntu 的双系统,CentOS 7 是在 Windows 下通过 VMware 访问的。我想着在 Ubuntu 里试一下,重启,切换到 Ubuntu,装 phpredis,测试,直接就连接成功了。CentOS 7 里的问题没有解决,于是再次切换回来。
不通过浏览器也能执行 PHP 文件,我试着在终端直接执行测试文件,也成功输出了
1 | onnection to server sucessfully, Server is running: +PONG |
直接执行可以输出,通过浏览器就不行,报的错误也是 500,基本能确定不是 PHP 和 phpredis 的问题,而是服务器的问题了。服务器的问题,可以查看日志,执行下面的命令可以查看服务器的错误日志。
1 | cat /var/log/httpd/error_log |
执行后可以看到,测试文件报了 Redis 的错误
1 | PHP Fatal error: Uncaught RedisException: Redis server went away in... |
有了报错,直接搜索报错信息即可。
方案
网上给出的结果:SELinux 的访问控制导致了这个错误,可以通过改变 SELinux 的运行模式或者禁用 SElinux 解决。
执行下面的命令,找到 SELinux 的配置文件
1 | vim /etc/selinux/config |
找到 SELINUX=enforcing 这一项,改为 SELINUX=disabled,如果还不行,执行下面的命令
1 | /usr/sbin/setsebool httpd_can_network_connect=1 |
即可解决问题。
总结
这次碰到的问题,不是一个大问题,但是却耽误了一些时间。SELinux 之前听到过,只是知道它是一个类似防火墙的东西,没有去深究,这次碰上了。准备看一下 SELinux,却在知乎上看到了 Linux 下为何要关闭 SELinux? 这个问题,我表示很气,不过还是打算了解一下。还有 Ubuntu 上为什么没出现这个问题,了解了一下,原来 CentOS、RedHat 等几个 Linux 发行版默认启用了 SELinux,而 Ubuntu 默认没有安装 SELinux。