Jedis客户端通过HAProxy连接Redis服务器失败求助
我来帮你排查这个通过HAProxy连接Redis失败的问题,结合你给出的信息,咱们一步步来分析解决:
1. 先确认HAProxy的核心配置是否正确
Redis用的是专属TCP协议,如果HAProxy默认用HTTP模式来转发,肯定会和Redis的协议不兼容,这是最常见的坑。你得检查HAProxy配置里有没有明确设置TCP模式:
正确的Redis转发配置应该是这样的:
# 前端监听80端口,用TCP模式 frontend redis_frontend bind *:80 mode tcp # 必须加这行,告诉HAProxy这是TCP转发,不是HTTP default_backend redis_backend # 后端指向你的Redis服务器 backend redis_backend mode tcp # 这里也要对应设置成TCP server redis_node <你的EC2实例IP>:6379 check inter 5000 rise 2 fall 3
如果你的配置里没加mode tcp,HAProxy会把Redis的请求当成HTTP请求解析,直接导致连接失败,改完配置重启HAProxy再试。
2. 先跳过Jedis,直接验证HAProxy的连通性
先不用客户端代码,用最基础的工具测试HAProxy能不能正确转发Redis请求:
# 用telnet测试 telnet <HAProxy的EC2公网IP> 80 # 连接成功后输入PING,正常会收到+PONG PING
或者用nc工具:
nc <HAProxy的EC2公网IP> 80
如果输入PING没收到PONG,那说明HAProxy的转发有问题,先排查这些点:
- 确认HAProxy所在EC2的安全组,80端口是否允许你的客户端IP访问;
- 确认Redis所在EC2的安全组,6379端口是否允许HAProxy的IP访问;
- 检查Redis的
redis.conf里的bind配置,如果是bind 127.0.0.1,HAProxy会连不上,要改成bind 0.0.0.0或者HAProxy的私有IP。
3. 检查Jedis客户端的连接代码
确保Jedis是用纯TCP方式连接HAProxy的80端口,不要加任何HTTP相关的配置。比如正确的连接代码应该是:
import redis.clients.jedis.Jedis; public class RedisTest { public static void main(String[] args) { try (Jedis jedis = new Jedis("<HAProxy的EC2 IP>", 80)) { String pong = jedis.ping(); System.out.println("连接成功:" + pong); } catch (Exception e) { e.printStackTrace(); } } }
如果你的代码里之前有设置HTTP代理、或者用了错误的连接方式(比如试图用HTTP协议访问),那肯定会抛出连接异常。
4. 根据异常信息精准定位
你提到抛出的是redis.clients.jedis相关异常,常见的两种情况:
- JedisConnectionException: Could not get a resource from the pool:说明根本连不上HAProxy,大概率是网络不通或者HAProxy配置错误,回到步骤2排查;
- JedisConnectionException: Unexpected end of stream:这几乎就是HAProxy用了HTTP模式导致的,Redis的响应被HAProxy当成HTTP响应截断了,赶紧去改HAProxy的
mode tcp配置。
最后一招:看HAProxy日志找线索
HAProxy的日志(通常在/var/log/haproxy.log或者/var/log/haproxy/haproxy.log)里会记录每一次连接的状态,比如转发失败、连接拒绝、协议不匹配等信息,直接看日志能快速定位问题。
内容的提问来源于stack exchange,提问作者Sandeep Singh
相关产品推荐
相关产品推荐

