Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Portweiterleitung mit nginx von java

Redis wurde entwickelt, um in einem sicheren Netzwerk hinter einer Backend-Anwendung zu arbeiten. Clientanwendungen sollen sich nicht direkt mit Redis verbinden. Das macht Redis zu einer schlechten Wahl für eine 2-Tier-Anwendung.

Wenn Sie dafür jetzt noch Redis verwenden möchten, haben Sie mehrere Möglichkeiten. Sie können den Redis-Server in einer HTTP-Schnittstelle kapseln. Dies bietet das nginx redis2-Modul. Vielleicht möchten Sie auch einen Blick auf webdis werfen, das ähnlich ist (und nicht von nginx abhängt). Webdis bietet einige Zugriffskontrollmechanismen. Siehe Dokumentation.

Eine andere Lösung besteht darin, einen Tunnel einzurichten, wie Sie es vorgeschlagen haben. Ich würde dafür kein nginx verwenden, sondern einfach nur altes SSH. Nehmen wir an, der Redis-Server läuft auf Maschine B (Port 6379) und der Client läuft auf Maschine A.

Auf Maschine A kann ich Folgendes ausführen:

ssh [email protected]_B -L 7008:host_B:6379 -N

Es öffnet einen Tunnel von A nach B vom lokalen Port 7008 (beliebige Wahl) und wartet. Der Benutzer sollte auf Host B deklariert und sein Passwort bekannt sein. In einer anderen Sitzung, immer noch auf Host A, können wir jetzt Folgendes ausführen:

redis-cli -p 7008 ping

Bitte beachten Sie, dass ein standardmäßiger Redis-Client verwendet wird. Der Tunnel behandelt Authentifizierung, Verschlüsselung und optional Komprimierung auf transparente Weise für den Client.

Jetzt ist Ihr Client eine Java-Anwendung, und Sie möchten wahrscheinlich keine SSH-Befehle ausführen, um den Tunnel einzurichten. Hoffentlich können Sie das Jsch-Paket verwenden, um den Tunnel direkt aus Java zu öffnen. Hier ist ein Beispiel mit 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();
    }
 }

Es funktioniert gut, aber bitte beachten Sie, dass es aufgrund des Tunnels einen Overhead gibt. Der Overhead ist sehr gering, wenn das Netzwerk langsam ist (z. B. das Internet). In einem schnellen LAN (1 GbE) macht sich das deutlich bemerkbar:Die Latenz kann bei Nutzung des Tunnels bis auf das Dreifache ansteigen. Der maximale Durchsatz, den der Redis-Server aufrechterhalten kann, ist ebenfalls betroffen. Auf der Serverseite beansprucht der sshd-Daemon etwas CPU (mehr als Redis selbst).

Abgesehen davon glaube ich nicht, dass die reine Leistung für eine 2-Tier-Anwendung von großer Bedeutung ist.