关于使用Jedis通过SOCKS代理连接Redis的技术咨询
Great question! The short answer is yes, you can connect to Redis via a SOCKS proxy using Jedis—though Jedis doesn’t include native SOCKS proxy support out of the box, you can work around this by implementing a custom SocketFactory to handle proxy tunneling.
Here’s a step-by-step guide to make this work smoothly:
1. Add Required Dependencies
First, you’ll need a library to handle SOCKS proxy connections. A reliable choice is JSch (Java Secure Channel), which supports both SOCKS4 and SOCKS5 proxies. Add this to your project’s build file:
For Maven:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> <!-- Use the latest stable version available --> </dependency>
For Gradle:
implementation 'com.jcraft:jsch:0.1.55'
2. Create a Custom SOCKS Socket Factory
Next, build a custom SocketFactory that uses JSch to establish connections through your SOCKS proxy. This factory will handle the tunneling logic behind the scenes:
import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import javax.net.SocketFactory; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; public class SocksSocketFactory extends SocketFactory { private final String proxyHost; private final int proxyPort; private final String proxyUser; // Optional, for proxies requiring authentication private final String proxyPassword; // Optional public SocksSocketFactory(String proxyHost, int proxyPort) { this(proxyHost, proxyPort, null, null); } public SocksSocketFactory(String proxyHost, int proxyPort, String proxyUser, String proxyPassword) { this.proxyHost = proxyHost; this.proxyPort = proxyPort; this.proxyUser = proxyUser; this.proxyPassword = proxyPassword; } @Override public Socket createSocket(String host, int port) throws IOException { try { JSch jsch = new JSch(); Session session = jsch.getSession(proxyUser, proxyHost, proxyPort); // Set proxy credentials if required if (proxyPassword != null) { session.setPassword(proxyPassword); } // Disable strict host key checking for simplicity (adjust based on your security needs) session.setConfig("StrictHostKeyChecking", "no"); session.connect(); // Create a socket tunneled through the SOCKS proxy return session.getSocketFactory().createSocket(host, port); } catch (JSchException e) { throw new IOException("Failed to establish connection via SOCKS proxy", e); } } // Required overrides for SocketFactory (use default implementations for these) @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { return createSocket(host, port); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return createSocket(host.getHostAddress(), port); } @Override public Socket createSocket(InetAddress host, int port, InetAddress localHost, int localPort) throws IOException { return createSocket(host.getHostAddress(), port); } }
3. Configure Jedis to Use the Custom Socket Factory
Now, wire up your Jedis client or pool to use the custom factory. Here’s an example with JedisPool (the most common production setup):
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Protocol; public class JedisSocksProxyDemo { public static void main(String[] args) { // Proxy configuration String proxyHost = "your-socks-proxy-host"; int proxyPort = 1080; // Default SOCKS5 port String proxyUser = "your-proxy-username"; // Omit if no auth is needed String proxyPassword = "your-proxy-password"; // Omit if no auth is needed // Redis server configuration String redisHost = "your-redis-server-host"; int redisPort = 6379; String redisPassword = "your-redis-password"; // Omit if Redis has no password // Initialize the custom SOCKS socket factory SocksSocketFactory socksSocketFactory = new SocksSocketFactory(proxyHost, proxyPort, proxyUser, proxyPassword); // Configure Jedis pool settings JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(10); // Adjust based on your workload poolConfig.setMaxIdle(5); // Create and use the Jedis pool try (JedisPool jedisPool = new JedisPool( poolConfig, redisHost, redisPort, Protocol.DEFAULT_TIMEOUT, redisPassword, socksSocketFactory )) { // Test the connection try (var jedis = jedisPool.getResource()) { jedis.set("proxy-test", "success"); System.out.println("Connection test result: " + jedis.get("proxy-test")); } } catch (Exception e) { System.err.println("Error connecting to Redis via proxy:"); e.printStackTrace(); } } }
Key Tips
- SOCKS Version: JSch works with both SOCKS4 and SOCKS5. For SOCKS4, you can skip the username/password fields since it doesn’t support authentication.
- Security: The example disables strict host key checking for ease of use—for production, consider setting this to
yesoraskto verify the proxy’s host key. - Timeouts: Adjust the connection timeout value (replace
Protocol.DEFAULT_TIMEOUT) if you need longer/shorter wait times for proxy connections.
内容的提问来源于stack exchange,提问作者Michel Foucault

