From c88297da2b59093577bcf7d18b68a6c7d3cd111e Mon Sep 17 00:00:00 2001 From: caojiajun Date: Mon, 23 Oct 2023 17:26:18 +0800 Subject: [PATCH] optimize UpstreamAddrConverter (#152) --- .../DefaultUpstreamAddrConverter.java | 48 +++++++++++++++---- .../upstream/connection/RedisConnection.java | 19 ++++++-- .../connection/UpstreamAddrConverter.java | 16 ++++++- .../other/upstream-addr-converter.md | 32 ++++++++++++- 4 files changed, 98 insertions(+), 17 deletions(-) diff --git a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/DefaultUpstreamAddrConverter.java b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/DefaultUpstreamAddrConverter.java index 6e0fd50d7..fc7463d28 100644 --- a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/DefaultUpstreamAddrConverter.java +++ b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/DefaultUpstreamAddrConverter.java @@ -55,13 +55,25 @@ public UpstreamAddrConverterResult convert(UpstreamAddrConverterContext context) String udsPath = context.getUdsPath(); for (Config config : configList) { if (host != null && config.getOriginalHost() != null) { - if (config.getOriginalHost().equals(CURRENT_HOST)) { - if (host.equals(currentHost)) { - return result(context, config); + if (config.getOriginalPort() <= 0) { + if (config.getOriginalHost().equals(CURRENT_HOST)) { + if (host.equals(currentHost)) { + return result(context, config); + } + } else { + if (host.equals(config.getOriginalHost())) { + return result(context, config); + } } } else { - if (host.equals(config.getOriginalHost())) { - return result(context, config); + if (config.getOriginalHost().equals(CURRENT_HOST) && config.getOriginalPort() == context.getPort()) { + if (host.equals(currentHost)) { + return result(context, config); + } + } else { + if (host.equals(config.getOriginalHost()) && config.getOriginalPort() == context.getPort()) { + return result(context, config); + } } } } @@ -79,7 +91,7 @@ public UpstreamAddrConverterResult convert(UpstreamAddrConverterContext context) private UpstreamAddrConverterResult result(UpstreamAddrConverterContext context, Config config) { if (config.getTargetHost() != null) { if (SocketChannel.class.isAssignableFrom(context.getChannelClass())) { - return new UpstreamAddrConverterResult(config.getTargetHost(), null, context.getChannelClass(), ChannelType.tcp); + return new UpstreamAddrConverterResult(config.getTargetHost(), config.getTargetPort(), null, context.getChannelClass(), ChannelType.tcp); } Class socketChannel = null; if (context.getEventLoop().parent() instanceof EpollEventLoopGroup) { @@ -92,14 +104,14 @@ private UpstreamAddrConverterResult result(UpstreamAddrConverterContext context, socketChannel = NioSocketChannel.class; } if (socketChannel != null) { - return new UpstreamAddrConverterResult(config.getTargetHost(), null, socketChannel, ChannelType.tcp); + return new UpstreamAddrConverterResult(config.getTargetHost(), config.getTargetPort(), null, socketChannel, ChannelType.tcp); } } if (config.getTargetUdsPath() != null) { if (context.getEventLoop().parent() instanceof EpollEventLoopGroup) { - return new UpstreamAddrConverterResult(null, config.getTargetUdsPath(), EpollDomainSocketChannel.class, ChannelType.uds); + return new UpstreamAddrConverterResult(null, -1, config.getTargetUdsPath(), EpollDomainSocketChannel.class, ChannelType.uds); } else if (context.getEventLoop().parent() instanceof KQueueEventLoopGroup) { - return new UpstreamAddrConverterResult(null, config.getTargetUdsPath(), KQueueDomainSocketChannel.class, ChannelType.uds); + return new UpstreamAddrConverterResult(null, -1, config.getTargetUdsPath(), KQueueDomainSocketChannel.class, ChannelType.uds); } } return null; @@ -128,8 +140,10 @@ private void reloadConfig() { private static class Config { private String originalHost; + private int originalPort; private String originalUdsPath; private String targetHost; + private int targetPort; private String targetUdsPath; public String getOriginalHost() { @@ -140,6 +154,14 @@ public void setOriginalHost(String originalHost) { this.originalHost = originalHost; } + public int getOriginalPort() { + return originalPort; + } + + public void setOriginalPort(int originalPort) { + this.originalPort = originalPort; + } + public String getOriginalUdsPath() { return originalUdsPath; } @@ -156,6 +178,14 @@ public void setTargetHost(String targetHost) { this.targetHost = targetHost; } + public int getTargetPort() { + return targetPort; + } + + public void setTargetPort(int targetPort) { + this.targetPort = targetPort; + } + public String getTargetUdsPath() { return targetUdsPath; } diff --git a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/RedisConnection.java b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/RedisConnection.java index 70443b994..3a8537c17 100644 --- a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/RedisConnection.java +++ b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/RedisConnection.java @@ -129,17 +129,26 @@ public void start() { return; } String host = this.host; + int port = this.port; String udsPath = this.udsPath; UpstreamAddrConverter upstreamHostConverter = config.getUpstreamHostConverter(); if (upstreamHostConverter != null) { - UpstreamAddrConverter.UpstreamAddrConverterContext context = new UpstreamAddrConverter.UpstreamAddrConverterContext(host, udsPath, eventLoop, channelClass); + UpstreamAddrConverter.UpstreamAddrConverterContext context = new UpstreamAddrConverter.UpstreamAddrConverterContext(host, port, udsPath, eventLoop, channelClass); UpstreamAddrConverter.UpstreamAddrConverterResult result = upstreamHostConverter.convert(context); if (result != null) { - logger.info("upstream addr convert, old.host = {}, new.host = {}, old.udsPath = {}, new.udsPath = {}, old.socketChannel = {}, new.socketChannel = {}, old.channelType = {}, new.channelType = {}", - host, result.getHost(), udsPath, result.getUdsPath(), channelClass.getSimpleName(), + logger.info("upstream addr convert, old.host = {}, new.host = {}, old.port = {}, new.port = {}," + + " old.udsPath = {}, new.udsPath = {}, old.socketChannel = {}, new.socketChannel = {}, old.channelType = {}, new.channelType = {}", + host, result.getHost(), udsPath, result.getUdsPath(), port, result.getPort(), channelClass.getSimpleName(), result.getChannelClass().getSimpleName(), channelType, result.getChannelType()); - host = result.getHost(); - udsPath = result.getUdsPath(); + if (result.getHost() != null) { + host = result.getHost(); + } + if (result.getPort() > 0) { + port = result.getPort(); + } + if (result.getUdsPath() != null) { + udsPath = result.getUdsPath(); + } channelClass = result.getChannelClass(); channelType = result.getChannelType(); } diff --git a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/UpstreamAddrConverter.java b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/UpstreamAddrConverter.java index 9a5eac948..ca7adc1ee 100644 --- a/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/UpstreamAddrConverter.java +++ b/camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/connection/UpstreamAddrConverter.java @@ -15,12 +15,14 @@ default UpstreamAddrConverterResult convert(UpstreamAddrConverterContext context public static class UpstreamAddrConverterResult { private final String host; + private final int port; private final String udsPath; private final Class channelClass; private final ChannelType channelType; - public UpstreamAddrConverterResult(String host, String udsPath, Class socketChannel, ChannelType channelType) { + public UpstreamAddrConverterResult(String host, int port, String udsPath, Class socketChannel, ChannelType channelType) { this.host = host; + this.port = port; this.udsPath = udsPath; this.channelClass = socketChannel; this.channelType = channelType; @@ -30,6 +32,10 @@ public String getHost() { return host; } + public int getPort() { + return port; + } + public String getUdsPath() { return udsPath; } @@ -45,12 +51,14 @@ public ChannelType getChannelType() { public static class UpstreamAddrConverterContext { private final String host; + private final int port; private final String udsPath; private final EventLoop eventLoop; private final Class channelClass; - public UpstreamAddrConverterContext(String host, String udsPath, EventLoop eventLoop, Class channelClass) { + public UpstreamAddrConverterContext(String host, int port, String udsPath, EventLoop eventLoop, Class channelClass) { this.host = host; + this.port = port; this.udsPath = udsPath; this.eventLoop = eventLoop; this.channelClass = channelClass; @@ -60,6 +68,10 @@ public String getHost() { return host; } + public int getPort() { + return port; + } + public String getUdsPath() { return udsPath; } diff --git a/docs/redis-proxy/other/upstream-addr-converter.md b/docs/redis-proxy/other/upstream-addr-converter.md index 86a368961..d7da1b40d 100644 --- a/docs/redis-proxy/other/upstream-addr-converter.md +++ b/docs/redis-proxy/other/upstream-addr-converter.md @@ -57,8 +57,38 @@ camellia-redis-proxy: ```properties upstream.addr.converter.enable=true -upstream.addr.converter.config=[{"originalHost": "@CurrentHost@", "targetUdsPath": "/Users/caojiajun/temp/redis.sock"}] +upstream.addr.converter.config=[{"originalHost": "@CurrentHost@", "originalPort": 6601, "targetUdsPath": "/Users/caojiajun/temp/redis.sock"}] ``` 假设proxy部署在10.189.31.13这个节点上,则proxy访问本机的redis-server会走uds,而不是走10.189.31.13 + +#### 允许的配置字段 +```java +private static class Config { + private String originalHost; + private int originalPort; + private String originalUdsPath; + private String targetHost; + private int targetPort; + private String targetUdsPath; +} +``` + +匹配: +* 如果originalPort大于0,先匹配originalHost+originalPort +* 如果originalPort缺失或者小于等于0,则只匹配originalHost +* 如果originalHost为空,则匹配originalUdsPath + +备注:如果originalHost为特殊的@CurrentHost@字符串,则会检查originalHost会使用本机ip去匹配 +本机ip默认自动获取,如果要手动指定,则可以配置: +```properties +current.proxy.host=10.189.31.13 +``` + +返回: +* 如果targetHost不为空,targetPort大于等于0,则替换为targetHost+targetPort +* 如果targetHost不为空,targetPort缺失或者小于等于0,则替换为targetHost+originalPort +* 如果targetHost为空,则替换为targetUdsPath +* 否则,保持不变 +