简体   繁体   English

AWS ElastiCache SSL 安全集群 + Spring Data Redis + Lettuce “Redis 健康检查失败”

[英]AWS ElastiCache SSL secured cluster + Spring Data Redis + Lettuce "Redis health check failed"

We are trying to secure our ElastiCache cluster to Spring Boot traffic by enabling SSL encryption.我们正在尝试通过启用 SSL 加密来保护我们的 ElastiCache 集群免受 Spring Boot 流量的影响。 Spring Boot app successfully starts, but when it tries to register on Eureka and Spring Boot Admin RedisHealthIndicator fails with an exception: Spring Boot 应用程序成功启动,但是当它尝试在 Eureka 上注册并且 Spring Boot Admin RedisHealthIndicator失败并出现异常时:

2020-02-28 12:31:32.742   WARN [app,,,] 8894 --- [nio-8081-exec-1] o.s.b.a.redis.RedisHealthIndicator       :      Redis health check failed     

org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisException: Cannot retrieve initial cluster partitions from initial URIs [RedisURI [host='my-cluster-url.amazonaws.com', port=6379]]
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1111)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1084)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getClusterConnection(LettuceConnectionFactory.java:363)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:333)
    at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:132)
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:95)
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:82)
    at org.springframework.boot.actuate.redis.RedisHealthIndicator.doHealthCheck(RedisHealthIndicator.java:56)
    at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:84)
    at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:98)
    at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:98)
    at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:50)
    at org.springframework.boot.actuate.health.HealthEndpointWebExtension.health(HealthEndpointWebExtension.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
    at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:76)
    at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:61)
    at org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$ServletWebOperationAdapter.handle(AbstractWebMvcEndpointHandlerMapping.java:294)
    at org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(AbstractWebMvcEndpointHandlerMapping.java:355)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.boot.actuate.autoconfigure.web.servlet.CompositeHandlerAdapter.handle(CompositeHandlerAdapter.java:58)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: io.lettuce.core.RedisException: Cannot retrieve initial cluster partitions from initial URIs [RedisURI [host='my-cluster-urlamazonaws.com', port=6379]]
    at io.lettuce.core.cluster.RedisClusterClient.loadPartitions(RedisClusterClient.java:865)
    at io.lettuce.core.cluster.RedisClusterClient.initializePartitions(RedisClusterClient.java:819)
    at io.lettuce.core.cluster.RedisClusterClient.connect(RedisClusterClient.java:345)
    at org.springframework.data.redis.connection.lettuce.ClusterConnectionProvider.getConnection(ClusterConnectionProvider.java:85)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1104)
    ... 62 common frames omitted
Caused by: io.lettuce.core.RedisCommandInterruptedException: Command interrupted
    at io.lettuce.core.cluster.topology.ClusterTopologyRefresh.loadViews(ClusterTopologyRefresh.java:109)
    at io.lettuce.core.cluster.RedisClusterClient.doLoadPartitions(RedisClusterClient.java:871)
    at io.lettuce.core.cluster.RedisClusterClient.loadPartitions(RedisClusterClient.java:844)
    ... 66 common frames omitted
Caused by: java.lang.InterruptedException: null
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
    at io.lettuce.core.cluster.topology.RefreshFutures.awaitAll(RefreshFutures.java:51)
    at io.lettuce.core.cluster.topology.AsyncConnections.get(AsyncConnections.java:80)
    at io.lettuce.core.cluster.topology.ClusterTopologyRefresh.loadViews(ClusterTopologyRefresh.java:73)
    ... 68 common frames omitted

Setup:设置:

  • Spring Boot version 2.1.4.RELEASE Spring Boot 版本 2.1.4.RELEASE
  • ElastiCache - Redis 5.0.3 ElastiCache - Redis 5.0.3

Workflow:工作流程:

  • App starts and connects to ElastiCache cluster应用程序启动并连接到 ElastiCache 集群
2020-02-28 12:29:31.786  DEBUG [app,,,] 8894 --- [nfoReplicator-0] io.lettuce.core.RedisClient              :      Connecting to Redis at my-cluster-url.amazonaws.com:6379  
2020-02-28 12:29:32.633  DEBUG [app,,,] 8894 --- [ioEventLoop-8-1] io.lettuce.core.RedisClient              :      Connecting to Redis at my-cluster-url.amazonaws.com:6379: Success  
  • After some time 10-20s Redis health check failed warning is logged and App is marked as dead in Eureka even though it still tries to reconnect to ElastiCache and is able to see the cluster.一段时间后,系统会记录 10-20 秒Redis health check failed警告,并且应用程序在 Eureka 中被标记为死机,即使它仍然尝试重新连接到 ElastiCache 并且能够看到集群。
2020-02-28 12:31:48.159  DEBUG [app,,,] 30409 --- [nio-8081-exec-1] o.s.d.redis.core.RedisConnectionUtils    :      Opening RedisConnection     
2020-02-28 12:31:48.162  DEBUG [app,,,] 30409 --- [nio-8081-exec-1] i.l.c.c.PooledClusterConnectionProvider  :      getConnection(WRITE, my-cluster-url.amazonaws.com, 6379)         
2020-02-28 12:31:48.165  DEBUG [app,,,] 30409 --- [ioEventLoop-9-1] i.l.core.protocol.RedisStateMachine      :      Decoded LatencyMeteredCommand [type=CLUSTER, output=StatusOutput [output=cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:4
cluster_size:2
cluster_current_epoch:3
cluster_my_epoch:3
cluster_stats_messages_ping_sent:2468227
cluster_stats_messages_pong_sent:2527673
cluster_stats_messages_meet_sent:3
cluster_stats_messages_sent:4995903
cluster_stats_messages_ping_received:2527667
cluster_stats_messages_pong_received:2468229
cluster_stats_messages_meet_received:3
cluster_stats_messages_fail_received:1
cluster_stats_messages_received:4995900
, error='null'], commandType=io.lettuce.core.protocol.AsyncCommand], empty stack: true  

Configuration:配置:

LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().useSsl().disablePeerVerification().build();

return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);

Tried to set .startTls() - didn't helped.试图设置.startTls() - 没有帮助。 Tried to set .pingBeforeActivateConnection(true) - didn't helped.试图设置.pingBeforeActivateConnection(true) - 没有帮助。

I guess problem is inside spring-boot-actuator it self, so one of possible solutions could be to try to override RedisHealthIndicator .我想问题出在spring-boot-actuator内部,所以可能的解决方案之一是尝试覆盖RedisHealthIndicator

在 ElastiCache 集群上添加密码并配置 Lettuce 驱动程序以进行 AUTH 调用而不是 NO_AUTH 后,在 ElastiCache 和 Spring 应用程序之间建立了连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Azure Redis SSL群集+生菜Java(编辑:生菜版本&lt;4.2) - Azure Redis SSL Cluster + Lettuce Java (EDIT: lettuce version < 4.2) Lettuce 无法使用 SSL 连接到 Redis 集群,但可以通过将其视为独立节点来使用 SSL 连接到同一 Redis 服务器 - Lettuce can't connect to Redis Cluster using SSL but can connect to same Redis server using SSL by treating it as a Standalone node 在集群模式下访问 AWS elasticache redis 时出错)+ 从 django 服务启用 TLS - Error accessing AWS elasticache redis in cluster mode) + TLS Enabled from django service 如果 redis 集群在 aws 私有网络中,需要多少 SSL 用于 aws redis? - How much is needed to use SSL for aws redis if the redis cluster is in aws private network? 在哪里可以找到 elasticache redis 集群的 TLS 证书 - Where can I find TLS certificates for elasticache redis cluster 将 SSL 与 Redis 和 Spring 数据 ZE111446745A1825BCEZ276 一起使用时“无法获得 Jedis 连接” - "Cannot get Jedis connection" when using SSL with Redis and Spring Data Redis SSL 认证验证失败 Heroku Redis - SSL Certification Verify Failed on Heroku Redis 从 spring 模板连接到加密的 Redis 集群 - Connect to an encrypted Redis cluster from spring template 使用传输中加密 + 身份验证从 redis-cli+stunnel 以外的客户端连接到 AWS ElastiCache - Connect to AWS ElastiCache with In-Transit Encryption + Auth from client other than redis-cli+stunnel 应用AWS SSL证书后的Load Balancer运行状况检查 - Load Balancer Health Check After Applying AWS SSL certificates
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM