如何通过SSH隧道使用Jedis连接Redis?
解决Jedis通过SSH隧道连接Redis时的"Unknown reply: S"错误
你当前的写法错误,Jedis本身不支持直接通过ssh://格式的URL创建SSH隧道,它会把这个地址当作Redis服务器地址去发起连接,而SSH服务器返回的握手响应(以"S"开头)不符合Redis协议格式,所以会报"Unknown reply: S"错误。
下面是两种正确的解决方式:
方式一:手动建立SSH本地端口转发
先通过终端命令建立SSH端口转发,将本地端口映射到远程Redis服务器的端口:
# 格式:ssh -L 本地端口:Redis服务器地址:Redis端口 ssh用户名@SSH服务器地址 -p SSH端口 ssh -L 63790:localhost:6379 sshuser@sshhost -p sshport
执行命令后输入SSH密码,保持终端窗口处于运行状态。
然后在Java代码中,用Jedis连接本地的转发端口:
Jedis jedis = new Jedis("localhost", 63790); // 测试连接 System.out.println(jedis.ping());
方式二:在Java代码内实现SSH隧道(无需手动执行命令)
借助JSch库在代码中创建SSH隧道,步骤如下:
- 引入JSch依赖(Maven示例):
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency>
- 编写代码实现SSH隧道+Jedis连接:
import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import redis.clients.jedis.Jedis; public class JedisWithSshTunnel { public static void main(String[] args) throws Exception { // SSH服务器配置 String sshUser = "sshuser"; String sshPassword = "sshpassword"; String sshHost = "sshhost"; int sshPort = 22; // Redis服务器配置(SSH服务器可访问的地址和端口) String redisHost = "localhost"; int redisPort = 6379; // 本地转发端口(选择未被占用的端口) int localForwardPort = 63790; // 创建SSH会话并建立端口转发 JSch jsch = new JSch(); Session sshSession = jsch.getSession(sshUser, sshHost, sshPort); sshSession.setPassword(sshPassword); // 生产环境建议关闭此配置,改用SSH密钥认证 sshSession.setConfig("StrictHostKeyChecking", "no"); sshSession.connect(); // 绑定本地端口到远程Redis端口 sshSession.setPortForwardingL(localForwardPort, redisHost, redisPort); // 连接Redis Jedis jedis = new Jedis("localhost", localForwardPort); System.out.println("Redis连接测试:" + jedis.ping()); // 关闭资源 jedis.close(); sshSession.disconnect(); } }
注意事项
- 生产环境不要使用
StrictHostKeyChecking=no,应配置SSH公钥认证,提升安全性。 - 确保SSH服务器允许端口转发,且Redis服务器的防火墙规则允许SSH服务器的IP访问(若Redis不在SSH服务器本地)。
内容的提问来源于stack exchange,提问作者00Pflaume
相关产品推荐
相关产品推荐

