|
22 | 22 | import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
|
23 | 23 | import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands;
|
24 | 24 | import io.lettuce.core.codec.ByteArrayCodec;
|
| 25 | +import io.lettuce.core.resource.ClientResources; |
| 26 | +import io.lettuce.core.resource.DnsResolvers; |
| 27 | +import io.lettuce.core.resource.MappingSocketAddressResolver; |
| 28 | +import io.lettuce.core.resource.NettyCustomizer; |
| 29 | +import io.netty.bootstrap.Bootstrap; |
| 30 | +import io.netty.channel.epoll.EpollChannelOption; |
| 31 | +import java.net.InetAddress; |
| 32 | +import java.net.UnknownHostException; |
25 | 33 | import java.util.Arrays;
|
26 | 34 | import java.util.List;
|
| 35 | +import java.util.Map; |
27 | 36 | import java.util.stream.Collectors;
|
28 | 37 |
|
29 | 38 | public class RedisClusterClient implements RedisClientAdapter {
|
@@ -62,18 +71,81 @@ private RedisClusterClient(Builder builder) {
|
62 | 71 | this.asyncCommands.setAutoFlushCommands(false);
|
63 | 72 | }
|
64 | 73 |
|
| 74 | + public static String getAddressString(String host) { |
| 75 | + try { |
| 76 | + return InetAddress.getByName(host).getHostAddress(); |
| 77 | + } catch (UnknownHostException e) { |
| 78 | + throw new RuntimeException(String.format("getAllByName() failed: %s", e.getMessage())); |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + public static MappingSocketAddressResolver customSocketAddressResolver( |
| 83 | + RedisClusterStoreConfig config) { |
| 84 | + |
| 85 | + List<String> configuredHosts = |
| 86 | + Arrays.stream(config.getConnectionString().split(",")) |
| 87 | + .map( |
| 88 | + hostPort -> { |
| 89 | + return hostPort.trim().split(":")[0]; |
| 90 | + }) |
| 91 | + .collect(Collectors.toList()); |
| 92 | + |
| 93 | + Map<String, String> mapAddressHost = |
| 94 | + configuredHosts.stream() |
| 95 | + .collect( |
| 96 | + Collectors.toMap(host -> ((String) getAddressString(host)), host -> (String) host)); |
| 97 | + |
| 98 | + return MappingSocketAddressResolver.create( |
| 99 | + DnsResolvers.UNRESOLVED, |
| 100 | + hostAndPort -> |
| 101 | + mapAddressHost.keySet().stream().anyMatch(i -> i.equals(hostAndPort.getHostText())) |
| 102 | + ? hostAndPort.of( |
| 103 | + mapAddressHost.get(hostAndPort.getHostText()), hostAndPort.getPort()) |
| 104 | + : hostAndPort); |
| 105 | + } |
| 106 | + |
| 107 | + public static ClientResources customClientResources(RedisClusterStoreConfig config) { |
| 108 | + ClientResources clientResources = |
| 109 | + ClientResources.builder() |
| 110 | + .nettyCustomizer( |
| 111 | + new NettyCustomizer() { |
| 112 | + @Override |
| 113 | + public void afterBootstrapInitialized(Bootstrap bootstrap) { |
| 114 | + bootstrap.option(EpollChannelOption.TCP_KEEPIDLE, 15); |
| 115 | + bootstrap.option(EpollChannelOption.TCP_KEEPINTVL, 5); |
| 116 | + bootstrap.option(EpollChannelOption.TCP_KEEPCNT, 3); |
| 117 | + // Socket Timeout (milliseconds) |
| 118 | + bootstrap.option(EpollChannelOption.TCP_USER_TIMEOUT, 60000); |
| 119 | + } |
| 120 | + }) |
| 121 | + .socketAddressResolver(customSocketAddressResolver(config)) |
| 122 | + .build(); |
| 123 | + return clientResources; |
| 124 | + } |
| 125 | + |
65 | 126 | public static RedisClientAdapter create(RedisClusterStoreConfig config) {
|
| 127 | + |
66 | 128 | List<RedisURI> redisURIList =
|
67 | 129 | Arrays.stream(config.getConnectionString().split(","))
|
68 | 130 | .map(
|
69 | 131 | hostPort -> {
|
70 | 132 | String[] hostPortSplit = hostPort.trim().split(":");
|
71 |
| - return RedisURI.create(hostPortSplit[0], Integer.parseInt(hostPortSplit[1])); |
| 133 | + RedisURI redisURI = |
| 134 | + RedisURI.create(hostPortSplit[0], Integer.parseInt(hostPortSplit[1])); |
| 135 | + if (!config.getPassword().isEmpty()) { |
| 136 | + redisURI.setPassword(config.getPassword()); |
| 137 | + } |
| 138 | + if (config.getSsl()) { |
| 139 | + redisURI.setSsl(true); |
| 140 | + } |
| 141 | + return redisURI; |
72 | 142 | })
|
73 | 143 | .collect(Collectors.toList());
|
74 | 144 |
|
75 | 145 | io.lettuce.core.cluster.RedisClusterClient client =
|
76 |
| - io.lettuce.core.cluster.RedisClusterClient.create(redisURIList); |
| 146 | + io.lettuce.core.cluster.RedisClusterClient.create( |
| 147 | + customClientResources(config), redisURIList); |
| 148 | + |
77 | 149 | client.setOptions(
|
78 | 150 | ClusterClientOptions.builder()
|
79 | 151 | .socketOptions(SocketOptions.builder().keepAlive(true).tcpNoDelay(true).build())
|
|
0 commit comments