Nginx无法原生透传Redis协议,必须通过间接方式实现:一、启用stream模块做TCP四层代理(推荐);二、代理至Redis Unix Socket;三、用socat+Supervisor转发;四、ThinkPHP直连Redis(最简)。

如果您在Nginx环境下运行ThinkPHP应用,并希望将Redis请求通过Nginx透传至后端Redis服务,需明确一点:Nginx本身不支持Redis协议代理,无法像HTTP或TCP流代理那样直接转发Redis命令。因此,所谓“Nginx透传Redis请求”在技术上并不存在原生实现,必须通过间接方式达成目标。以下是几种可行的替代方案:
一、使用Nginx Stream模块代理Redis TCP连接
Nginx Stream模块可实现四层TCP/UDP代理,适用于Redis客户端直连Nginx IP+端口后,由Nginx将原始TCP流量转发至真实Redis服务器。该方式不解析Redis协议,仅做连接透传,低延迟且兼容所有Redis客户端。
1、确认Nginx已编译启用stream模块:执行nginx -V 2>&1 | grep -o with-stream,输出with-stream表示支持。
2、在Nginx主配置文件(如/etc/nginx/nginx.conf)的顶层(http块之外)添加stream段:
立即学习“PHP免费学习笔记(深入)”;
3、定义上游Redis服务器:
upstream redis_backend {
server 127.0.0.1:6379 weight=1 max_fails=2 fail_timeout=30s;
4、配置监听端口并透传:
server {
listen 6380;
proxy_pass redis_backend;
proxy_timeout 1s;
proxy_responses 1;
}
5、重启Nginx:sudo nginx -t && sudo systemctl reload nginx。
6、修改ThinkPHP配置文件config/cache.php中的Redis连接地址为127.0.0.1:6380,端口需与Nginx stream监听端口一致。
二、通过Unix Socket文件代理Redis连接
当Nginx与Redis同机部署时,可利用Nginx Stream模块代理到Redis的Unix Socket路径,避免TCP网络栈开销,提升本地通信效率。此方式要求Redis配置启用unixsocket参数并设置合理权限。
1、编辑Redis配置文件/etc/redis/redis.conf,取消注释并修改:
unixsocket /var/run/redis/redis.sock
unixsocketperm 755
2、创建Socket目录并赋权:sudo mkdir -p /var/run/redis && sudo chown redis:redis /var/run/redis,然后重启Redis。
3、在Nginx stream块中新增server块:
server {
listen 6381;
proxy_pass unix:/var/run/redis/redis.sock;
proxy_timeout 1s;
}
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
4、确保Nginx主进程以能访问该Socket的用户运行(如redis或www-data),可在nginx.conf中设置user redis;。
5、ThinkPHP中将Redis host设为127.0.0.1、port设为6381,或直接使用tcp://127.0.0.1:6381格式连接串。
三、使用Supervisor托管socat实现透明代理
在Nginx不支持stream模块或版本过旧时,可用socat工具创建TCP-to-Unix-Socket或TCP-to-TCP转发器,再由Supervisor守护其进程。该方式无需修改Nginx核心配置,灵活性高,但引入额外依赖。
1、安装socat:sudo apt install socat(Debian/Ubuntu)或yum install socat(CentOS)。
2、测试手动启动转发(临时验证):
socat TCP-LISTEN:6382,fork,reuseaddr UNIX-CONNECT:/var/run/redis/redis.sock
3、创建Supervisor配置文件/etc/supervisor/conf.d/redis-proxy.conf:
[program:redis-proxy]
command=socat TCP-LISTEN:6382,fork,reuseaddr UNIX-CONNECT:/var/run/redis/redis.sock
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/var/log/redis-proxy.log
4、重载Supervisor:sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl start redis-proxy。
5、ThinkPHP中配置Redis host为127.0.0.1、port为6382,连接即被socat转发至Redis Unix Socket。
四、修改ThinkPHP底层驱动绕过Nginx,直连Redis
若实际需求仅为“在Nginx环境中让ThinkPHP使用Redis”,而非强制经Nginx透传,则最简方案是放弃代理思路,改为ThinkPHP直连Redis服务。此时需确保Redis绑定地址开放、防火墙放行、认证配置匹配,Nginx仅作为Web服务器存在,不参与缓存链路。
1、检查Redis是否监听非127.0.0.1地址:确认bind配置包含127.0.0.1或0.0.0.0,且protected-mode no(若关闭保护模式)。
2、开放系统防火墙端口:sudo ufw allow 6379或firewall-cmd --permanent --add-port=6379/tcp。
3、在ThinkPHP的config/cache.php中显式指定Redis连接参数:
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
4、若Redis启用密码认证,将password字段设为对应字符串;若使用哨兵或集群,需切换为think\cache\driver\RedisSentinel或RedisCluster驱动类。
5、验证连接:php think optimize:clear后,在控制器中调用cache('test_key', 'test_value', 3600),再用redis-cli get test_key确认写入成功。


















