当前位置: 首页 > 面试题库 >

使用Java从Nginx转发端口

窦华晖
2023-03-14
问题内容

我正在尝试制作一个使用 Redis* 作为后端的 Java应用程序 。由于 Redis 是一个非常快速的键值存储,我想使用它,但是
redis 可以与1个客户端一起使用,因此它没有user:pass身份验证的选项。我想找到一种实现某种身份验证的方法,因此我尝试了带有
redis2 扩展名的 nginx 。我这样做是因为我可以使用 客户端证书 和HTTPS。但这使我的应用程序非常慢。

*

我正在考虑使用某种通过 nginx proxy
连接到redis的隧道。对于此redis,将在localhost上侦听,并且会有一个我想用来访问redis的地址,但具有https身份验证。所以基本上我目前的方法

JAVA - Jedis - LAN - REDIS ,would be 
JAVA - Jedis(with localhost as the tunnel entrance?)-
-SSL LAN - Nginx(tunnel exit) - Redis

有什么秘诀可以做到这一点吗?最近几天,我一直在Google上搜索Google,但是我想不出任何能增加本机连接开销的事情。


问题答案:

Redis旨在在后端应用程序后面的安全网络上工作。客户端应用程序不应直接连接到Redis。对于2层应用程序,它使Redis成为糟糕的选择。

现在,如果您仍要使用Redis,则有几种选择。您可以将Redis服务器封装在HTTP接口中。这就是nginx
redis2模块所提供的。您可能还想看看webdis,这是相似的(并且不依赖于nginx)。Webdis提供了一些访问控制机制。请参阅文档。

另一个解决方案是按照您的建议建立隧道。我不会为此使用nginx,而只会使用普通的旧SSH。假设Redis服务器在计算机B(端口6379)上运行,而客户端在计算机A上运行。

在机器A上,我可以运行:

ssh user@host_B -L 7008:host_B:6379 -N

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

redis-cli -p 7008 ping

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

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

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)时,开销非常低。在快速的LAN(1
GbE)上,它更加引人注目:使用隧道时,延迟最多可以乘以3。Redis服务器可以承受的最大吞吐量也受到影响。在服务器端,sshd守护程序占用一些CPU(比Redis本身更多)。

也就是说,对于2层应用程序,原始性能并不重要。



 类似资料:
  • 本文向大家介绍Mac中使用Nginx实现80端口转发8080端口,包括了Mac中使用Nginx实现80端口转发8080端口的使用技巧和注意事项,需要的朋友参考一下 由于项目本身的原因,开发必须使用80端口实现,而在Unix内核中非Root用户无法直接使用1024以下的端口,最初作者找到了pfctl的方式实现80端口转发到8080端口实现访问,经过亲测出现了最为严重的问题,按照当时的方法配置好之后发

  • null 因此,发生的事情可以在环回中解决,但不会通过ssh隧道。如何从docker调用,使其通过ssh隧道? 附:我用的是macOS High Sierra

  • 问题内容: 我正在尝试利用Vagrant 1.6的Docker提供程序,但似乎遇到了麻烦。我可以成功启动Docker容器和来宾操作系统,但随后无法从主机OS访问容器中已启动的服务。这是我的Vagrantfile: 我的理解是,在OS X上运行将启动运行boot2docker的VM,然后再运行我的容器。运行似乎可以确认我的容器已创建并且服务已启动,但是现在我一生无法弄清楚如何从OS X主机访问该服务

  • 问题内容: 我已经构建了一个打开ServerSocket的简单应用程序,并在连接时将其自身连接到远程计算机上的另一个服务器套接字。为了实现端口转发,我使用了两个线程,一个线程从本地输入流读取并向远程套接字输出流读取流,反之亦然。 该实现感觉有点差劲,所以我问您是否知道更好的实现策略,或者是否有一些代码可以以高效的方式实现。 PS:我知道我可以在Linux上使用IPTables,但是必须在Windo

  • 我用头盔部署了格拉法纳,现在它正在吊舱中运行。我可以访问它,如果我代理端口3000到我的笔记本电脑。我试图指向一个域,以便我可以从外部访问该pod。我在route53中有一个域,可以连接到负载平衡器(应用程序负载平衡器、网络负载平衡器、经典负载平衡器)。该负载平衡器可以将流量从端口80转发到端口80,再转发到一组节点(让我们稍后保留端口443)。我真的很难设置这个。我肯定少了些什么,但我不知道是什

  • 我正在根据我们通过简单的图像信标收集的仪器数据,为我们的网站属性提供分析。我们的数据管道从Flume开始,我需要尽可能快的方法来解析查询字符串参数,形成一条简单的文本消息并将其推入Flume。 出于性能原因,我倾向于使用nginx。由于已经支持从内存提供静态映像,所以我的任务减少到处理查询字符串并将消息转发到Flume。因此,问题是: nginx和Flume集成最简单可靠的方法是什么?我在考虑使用