欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis【有与无】【Lettuce】L7.SSL连接、Unix Domain Sockets、本机传输

程序员文章站 2022-05-01 08:12:19
...

本文章基于Redis 6.0.9版本,Lettuce 6.0.1.RELEASE版本

目录

1.SSL连接

例子1. stunnel.conf

示例2.使用RedisURI通过SSL连接到Redis

示例3.使用字符串RedisURI通过SSL连接到Redis

例子4.使用RedisURI通过SSL连接到Redis集群

1.1.局限性

1.2.连接步骤和重新连接

1.3.证书链/根(Root)证书/自签名证书

例子5.通过客户端选项配置SslOptions

例子6.通过系统属性配置自定义信任库

1.4.主机/对等(Host/Peer)验证

1.5.StartTLS

2.Unix域套接字(Unix Domain Sockets)

示例1.使用RedisURI连接到Redis

示例2.使用字符串RedisURI连接到Redis

3.本机传输

3.1.局限性


1.SSL连接

从Redis Standalone连接上的3.1版和Redis群集上的4.2版开始,Lettuce支持SSL连接。 Redis不支持本地SSL,通常使用stunnel实现SSL。

stunnel配置示例如下所示:

例子1. stunnel.conf

cert=/etc/ssl/cert.pem
key=/etc/ssl/key.pem
capath=/etc/ssl/cert.pem
cafile=/etc/ssl/cert.pem
delay=yes
pid=/etc/ssl/stunnel.pid
foreground = no

[redis]
accept = 127.0.0.1:6443
connect = 127.0.0.1:6479

下一步是通过SSL将lettuce连接到Redis。

示例2.使用RedisURI通过SSL连接到Redis

RedisURI redisUri = RedisURI.Builder.redis("localhost")
                                 .withSsl(true)
                                 .withPassword("authentication")
                                 .withDatabase(2)
                                 .build();

RedisClient client = RedisClient.create(redisUri);

示例3.使用字符串RedisURI通过SSL连接到Redis

RedisURI redisUri = RedisURI.create("rediss://[email protected]/2");
RedisClient client = RedisClient.create(redisUri);

例子4.使用RedisURI通过SSL连接到Redis集群

RedisURI redisUri = RedisURI.Builder.redis("localhost")
                                 .withSsl(true)
                                 .withPassword("authentication")
                                 .build();

RedisClusterClient client = RedisClusterClient.create(redisUri);

1.1.局限性

Lettuce仅在Redis Standalone和Redis Cluster连接上以及从5.2开始支持SSL,还支持使用Redis Sentinel或Redis Upstream/Replicas进行Upstream解析。

1.2.连接步骤和重新连接

使用SSL连接时,Lettuce必须先进行SSL握手,然后才能使用连接。 纯文本连接不执行握手。 握手期间的错误引发RedisConnectionExceptions。

重新连接行为也与纯文本连接不同。 如果重新连接时SSL握手失败(由于对等方/证书验证或对等方不使用SSL),则连接将被禁用重新连接。 你还会在日志中找到错误日志条目。

1.3.证书链/根(Root)证书/自签名证书

Lettuce使用Java缺省值作为信任库,该缺省值通常在jre/lib/security目录中是cacerts,并带有通过Client选项可定制的SSL选项。 如果需要添加自己的根证书,则可以配置SslOptions,将其导入cacerts或提供自己的信任库并设置必要的系统属性:

例子5.通过客户端选项配置SslOptions

SslOptions sslOptions = SslOptions.builder()
        .jdkSslProvider()
        .truststore(new File("yourtruststore.jks"), "changeit")
        .build();

ClientOptions clientOptions = ClientOptions.builder().sslOptions(sslOptions).build();

例子6.通过系统属性配置自定义信任库

System.setProperty("javax.net.ssl.trustStore", "yourtruststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

1.4.主机/对等(Host/Peer)验证

默认情况下,Lettuce根据所连接的Redis主机(host)的有效性和公用名(Java 1.6不支持名称验证,仅Java 1.7及更高版本可用)验证证书。 可以关闭此行为:

RedisURI redisUri = ...
redisUri.setVerifyPeer(false);

或者

RedisURI redisUri = RedisURI.Builder.redis(host(), sslPort())
                                 .withSsl(true)
                                 .withVerifyPeer(false)
                                 .build();

1.5.StartTLS

如果需要发布StartTLS才能使用SSL,请将RedisURI 的startTLS属性设置为true。 默认情况下,禁用StartTLS。

RedisURI redisUri = ...
redisUri.setStartTls(true);

或者

RedisURI redisUri = RedisURI.Builder.redis(host(), sslPort())
                                 .withSsl(true)
                                 .withStartTls(true)
                                 .build();

2.Unix域套接字(Unix Domain Sockets)

Lettuce从3.2版Unix域套接字开始支持本地Redis连接。

示例1.使用RedisURI连接到Redis

RedisURI redisUri = RedisURI.Builder
                             .socket("/tmp/redis")
                             .withPassword("authentication")
                             .withDatabase(2)
                             .build();

RedisClient client = RedisClient.create(redisUri);

示例2.使用字符串RedisURI连接到Redis

RedisURI redisUri = RedisURI.create("redis-socket:///tmp/redis");
RedisClient client = RedisClient.create(redisUri);

Unix域套接字是POSIX兼容系统上的进程间通信通道。 它们允许在同一主机(host)操作系统上的进程之间交换数据。 使用通常是网络服务的Redis时,只有在本地连接到单个实例时,才能使用Unix域套接字。 Redis Sentinel和Redis Cluster,维护远程或本地节点的表,因此充当注册表。 Unix域套接字对Redis Sentinel和Redis Cluster不利。

RedisClusterClient与Unix域套接字一起使用,套接字将使用套接字连接到本地节点,并打开与所有其他主机(hosts)的TCP连接。 一个很好的例子是在本地连接到独立或单个群集节点以提高性能。

3.本机传输(Native Transports)

Netty提供了三种特定于平台的JNI传输:

  • epoll on Linux
  • io_uring on Linux (Incubator)
  • kqueue on MacOS/BSD

如果适当的库在其运行时可用,则Lettuce默认为本机传输。 与基于NIO的传输相比,使用本机传输会添加特定于特定平台的功能,产生更少的垃圾,并通常会提高性能。 通过Unix域套接字连接本机传输是必需的,并且也适用于TCP连接。

本机传输可用于:

  • 最低Netty版本为4.0.26.Final的Linux epoll x86_64系统,需要netty-transport-native-epoll,分类器linux-x86_64

 

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-epoll</artifactId>
    <version>${netty-version}</version>
    <classifier>linux-x86_64</classifier>
</dependency>
  • Linux io_uring x86_64系统的最低Netty版本为4.1.54.Final,需要netty-incubator-transport-native-io_uring,分类器为linux-x86_64。 请注意,此传输仍处于实验阶段。
<dependency>
    <groupId>io.netty.incubator</groupId>
    <artifactId>netty-incubator-transport-native-io_uring</artifactId>
    <version>0.0.1.Final</version>
    <classifier>linux-x86_64</classifier>
</dependency>
  • 最低Netty版本为4.1.11.Final的MacOS kqueue x86_64系统,需要netty-transport-native-kqueue,分类器osx-x86_64
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-kqueue</artifactId>
    <version>${netty-version}</version>
    <classifier>osx-x86_64</classifier>
</dependency>

你可以通过系统属性禁用本机传输。 将io.lettuce.core.epollio.lettuce.core.iouring设置为false(如果未设置,则默认为true)。

3.1.局限性

由于以下两个原因,本机传输支持不适用于Lettuce的阴影版本:

  1. netty-transport-native-epollnetty-transport-native-kqueue未包装到有阴影的jar中。 因此,将jar添加到类路径将解析为不同的netty基类(例如io.netty.channel.EventLoopGroup而不是com.lambdaworks.io.netty.channel.EventLoopGroup
  2. 支持将epoll/kqueue与带阴影的netty一起使用需要netty 4.1和netty的所有部分都带有阴影。

另请参阅有关本机传输的Netty文档