You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS自建Redis(非ElastiCache)本地SpringBoot连接超时求助

自建Redis集群(AWS Kubernetes)连接超时问题排查

一、部署架构与配置

在AWS环境中通过Kubernetes StatefulSet+LoadBalancer(MetalLB)部署自建Redis集群,核心配置如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      initContainers:
        - name: config
          image: redis:7.0.5-alpine
          command: [ "sh", "-c" ]
          args:
            - |
              cp /tmp/redis/redis.conf /etc/redis/redis.conf
              
              echo "finding master..."
              MASTER_FDQN=`hostname  -f | sed -e 's/redis-[0-9]\./redis-0./'`
              if [ "$(redis-cli -h sentinel -p 5000 ping)" != "PONG" ]; then
                echo "master not found, defaulting to redis-0"
              
                if [ "$(hostname)" = "redis-0" ]; then
                  echo "this is redis-0, not updating config..."
                else
                  echo "updating redis.conf..."
                  echo "slaveof $MASTER_FDQN 6379" >> /etc/redis/redis.conf
                fi
              else
                echo "sentinel found, finding master"
                MASTER="$(redis-cli -h sentinel -p 5000 sentinel get-master-addr-by-name mymaster | grep -E '(^redis-\d{1,})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})')"
                echo "master found : $MASTER, updating redis.conf"
                echo "slaveof $MASTER 6379" >> /etc/redis/redis.conf
              fi
          volumeMounts:
            - name: redis-config
              mountPath: /etc/redis/
            - name: config
              mountPath: /tmp/redis/
      containers:
        - name: redis
          image: redis:7.0.5-alpine
          command: ["redis-server"]
          args: ["/etc/redis/redis.conf"]
          ports:
            - containerPort: 6379
              name: redis
          volumeMounts:
            - name: data
              mountPath: /data
            - name: redis-config
              mountPath: /etc/redis/
      volumes:
        - name: redis-config
          emptyDir: {}
        - name: config
          configMap:
            name: redis-config
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: nfs-1
        resources:
          requests:
            storage: 50Mi
---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  ports:
    - port: 6379
      targetPort: 6379
      name: redis
  selector:
    app: redis
  type: LoadBalancer

二、集群资源状态

所有Redis Pod运行正常,资源信息如下:

NAME          READY   STATUS    RESTARTS   AGE
pod/redis-0   1/1     Running   0          22h
pod/redis-1   1/1     Running   0          22h
pod/redis-2   1/1     Running   0          22h

NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/redis   LoadBalancer   192.168.45.55   10.51.5.2     6379:30315/TCP   26h

NAME                     READY   AGE
statefulset.apps/redis   3/3     22h

三、Redis Service详情

Name:                     redis
Namespace:                Namespace
Labels:                   <none>
Annotations:              <none>
Selector:                 app=redis
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       192.168.22.33
IPs:                      192.168.22.33
LoadBalancer Ingress:     10.51.5.2
Port:                     redis  6379/TCP
TargetPort:               6379/TCP
NodePort:                 redis  30315/TCP
Endpoints:                192.xxx:6379,192.xxx:6379,192.xxx:6379
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason        Age                From                Message
  ----    ------        ----               ----                -------
  Normal  IPAllocated   68s                metallb-controller  Assigned IP ["10.51.5.2"]
  Normal  nodeAssigned  58s (x5 over 66s)  metallb-speaker     announcing from node "someaddress.com" with protocol "bgp"
  Normal  nodeAssigned  58s (x5 over 66s)  metallb-speaker     announcing from node "someaddress.com" with protocol "bgp"

四、SpringBoot连接代码

本地SpringBoot应用通过Lettuce连接Redis的核心代码:

@Configuration
public class RedisConfiguration {

    @Bean
    public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
        return new LettuceConnectionFactory("10.51.5.2", 30315);
    }
}

@Repository
public class RedisRepository {

    private final ReactiveRedisOperations<String, String> reactiveRedisOperations;

    public RedisRepository(ReactiveRedisOperations<String, String> reactiveRedisOperations) {
        this.reactiveRedisOperations = reactiveRedisOperations;
    }

    public Mono<RedisPojo> save(RedisPojo redisPojo) {
        return reactiveRedisOperations.opsForValue().set(redisPojo.getInput(), redisPojo.getOutput()).map(__ -> redisPojo);
    }
}

五、连接超时错误日志

每次请求均出现连接超时异常:

2022-12-02T20:20:08.015+08:00 ERROR 1184 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [8f16a752-1]  500 Server Error for HTTP POST "/save"

org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1602) ~[spring-data-redis-3.0.0.jar:3.0.0]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler com.redis.controller.RedisController#test(RedisRequest) [DispatcherHandler]
    *__checkpoint ⇢ HTTP POST "/save" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1602) ~[spring-data-redis-3.0.0.jar:3.0.0]

Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 10.51.5.2/<unresolved>:30315
    at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) ~[lettuce-core-6.2.1.RELEASE.jar:6.2.1.RELEASE]
    at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) ~[lettuce-core-6.2.1.RELEASE.jar:6.2.1.RELEASE]
    at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:350) ~[lettuce-core-6.2.1.RELEASE.jar:6.2.1.RELEASE]
    at io.lettuce.core.RedisClient.connect(RedisClient.java:216) ~[lettuce-core-6.2.1.RELEASE.jar:6.2.1.RELEASE]

Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /10.51.5.2:30315
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
    at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98) ~[netty-common-4.1.85.Final.jar:4.1.85.Final]

排查与解决步骤

1. 修正端口使用错误

代码中误用了NodePort(30315)连接LoadBalancer IP,LoadBalancer对外暴露的是Service端口6379,应修改连接配置:

@Bean
public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
    return new LettuceConnectionFactory("10.51.5.2", 6379);
}

2. 检查AWS网络安全规则

  • 确认LoadBalancer安全组开放6379端口给本地SpringBoot应用的公网IP;
  • 若坚持使用NodePort,需确保集群节点安全组开放30315端口给本地IP。

3. 验证Redis绑定配置

进入Redis Pod检查redis.conf的绑定规则:

kubectl exec -it redis-0 -- cat /etc/redis/redis.conf | grep bind

若结果为bind 127.0.0.1,需修改Redis ConfigMap,设置bind 0.0.0.0,然后重启StatefulSet:

kubectl rollout restart statefulset redis

4. 测试LoadBalancer连通性

在本地执行以下命令,验证IP和端口的可达性:

telnet 10.51.5.2 6379
# 或使用redis-cli测试
redis-cli -h 10.51.5.2 -p 6379 ping

若不通,检查MetalLB的BGP路由配置,以及AWS路由表是否包含该LoadBalancer IP的路由条目。

5. 调整外部流量策略

当前Service的ExternalTrafficPolicy为Cluster,流量会经过kube-proxy转发,可改为Local减少转发环节:
修改Service YAML:

spec:
  externalTrafficPolicy: Local

应用配置:

kubectl apply -f <service-yaml-path>

内容的提问来源于stack exchange,提问作者PatPanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:55:20