首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用java的nginx进行端口转发

使用java的nginx进行端口转发
EN

Stack Overflow用户
提问于 2013-05-28 10:28:04
回答 2查看 1.6K关注 0票数 2

我正在尝试制作一个java应用程序,它使用redis作为后端。因为Redis是一个非常快速的密钥值存储,我想使用它,但是redis是与一个客户端一起使用的,因此它没有一个用户选项:通过身份验证。我想找到一种实现某种身份验证的方法,所以我尝试了nginxredis2扩展。我这么做是因为我可以使用客户端证书和HTTPS。但这让我的应用程序变慢了。

我正在考虑使用某种隧道,它通过nginx代理连接到redis。为此,redis将在localhost上侦听,并且有一个地址,我希望使用它来访问redis,但使用https身份验证。所以基本上我现在的方法

代码语言:javascript
复制
JAVA - Jedis - LAN - REDIS ,would be 
JAVA - Jedis(with localhost as the tunnel entrance?)-
-SSL LAN - Nginx(tunnel exit) - Redis

有什么建议可以做到吗?在过去的几天里,我一直在谷歌上搜索网络,但是我想不出任何只会给本机连接增加一点点开销的东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-28 18:35:06

Redis设计用于在后端应用程序后面的安全网络上工作。客户端应用程序不应该直接连接到Redis。这使得Redis成为2层应用程序的糟糕选择。

现在,如果您仍然希望在这方面使用Redis,那么您有几个选项。您可以将Redis服务器封装在HTTP接口中。这就是nginx redis2模块提供的内容。您可能还想看看webdis,它类似(并且不依赖于nginx)。Webdis提供了一些访问控制机制。请看文件。

另一种解决办法是建立一条隧道,正如你所提议的。我不会用nginx来做这件事,只是普通的老SSH。假设Redis服务器运行在机器B上(端口6379),客户端运行在机器A上。

在A机上,我可以跑:

代码语言:javascript
复制
ssh user@host_B -L 7008:host_B:6379 -N

它将打开一个隧道从A到B从本地端口7008 (任意选择),并等待。用户应该在主机B上声明,并且它的密码已知。在另一个仍在主机A上的会话中,我们现在可以运行:

代码语言:javascript
复制
redis-cli -p 7008 ping

请注意使用标准的Redis客户端。隧道以透明的方式为客户端处理身份验证、加密和可选压缩。

现在,您的客户端是一个Java应用程序,您可能不希望运行SSH命令来设置隧道。希望您可以使用杰希包直接从Java打开隧道。下面是Jedis的一个例子:

代码语言:javascript
复制
import redis.clients.jedis.*;
import java.util.*;
import com.jcraft.jsch.*;

public class TestTunnel {

    Jedis jedis;  
    Session session;
    JSch jsch = new JSch(); 
    int port;

    // None of the following should be hardcoded
    static String USER = "user";          // SSH user on the redis server host
    static String PASSWD = "XXXXXXXX";    // SSH user password
    static String HOST = "192.168.1.62";  // Redis server host
    static int PORT = 6379;               // Redis server port

    public TestTunnel() {
      try {
        // Open the SSH session
        session = jsch.getSession( USER, HOST, 22 );
        session.setPassword( PASSWD );
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        config.put("Compression", "yes");
        config.put("ConnectionAttempts","3");
        session.setConfig(config);
        session.connect();
        // Setup port forwarding from localhost to the Redis server
        // Local port is ephemeral (given by the OS)
        // Jedis connects to localhost using the local port
        port = session.setPortForwardingL( 0, HOST, PORT );
        jedis = new Jedis( "127.0.0.1", port );
      } catch ( JSchException e ) {
        // Proper error handling omitted
        System.out.println(e);
      }
    } 

    public void disconnect() {
      jedis.disconnect();
      try {
        session.delPortForwardingL( port );
        session.disconnect();            
      } catch ( JSchException e ) {
        // Proper error handling omitted
        System.out.println(e);
      } 
    }

    public void mytest( int n ) {
     for ( int k = 0; k < n; k++) {
      jedis.set("k" + k, "value"+k);
     }
     System.out.println("Read: "+jedis.get("k0") );
    }

    public static void main(String[] args) {
      TestTunnel obj = new TestTunnel();
      obj.mytest(10);
      obj.disconnect();
    }
 }

它运行良好,但请注意,由于隧道有一个开销。当网络速度慢时,开销非常低(例如Internet )。在快速局域网(1 GbE)上,这是更值得注意的:当隧道被使用时,延迟可以乘以3。Redis服务器可以维持的最大吞吐量也会受到影响。在服务器端,sshd守护进程需要一些CPU (比Redis本身更多)。

尽管如此,我认为对于2层应用程序来说,原始性能并没有多大关系。

票数 3
EN

Stack Overflow用户

发布于 2013-06-06 13:20:24

注意:有一个名为SSL的SSL版本,可以在github:https://github.com/bbroerman30/ssl-redis 2.6ish上找到。

https://github.com/tritondigital/ssl-redis 2.4ish

通过修改Jedis客户端,可以实现SSL身份验证。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16789727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档