Redis部署在AWS - localhost SpringBoot应用程序连接超时



关于Redis部署在AWS(不是AWS弹性缓存)和连接到它的一个问题。

下面是部署在AWS中的Redis的设置:(只粘贴Kubernetes的statfulset和Service)

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

pod是健康的,我可以执行它并执行操作。下面是get all:

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

服务描述:

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"

然后我尝试连接到它,即插入一些数据与一个非常简单的Spring Boot应用程序。应用程序没有业务逻辑,只是试图插入数据。以下是相关部分:


@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]

这特别令人费解,因为我很确定Spring Boot应用程序的代码是正常工作的。当我将return new LettuceConnectionFactory("10.51.5.2", 30315);:的IP更改为

  1. 我的笔记本电脑上的常规Redis ("localhost", 6379),
  2. 我的笔记本电脑上的dockerized Redis,
  3. 一个dockerized Redis在prem上,所有工作正常。

因此,我很困惑我在AWS中设置这个Redis时做错了什么。我该怎么做才能正确地连接到它。能帮我一下吗?

谢谢

默认情况下,Redis将自身绑定到IP地址127.0.0.1::1,不接受非本地接口的连接。很有可能这是你的主要问题,你可能想检查你的redis.conf文件,将Redis绑定到你需要的接口或通用的* -::*,正如配置文件本身的注释所解释的那样(我在上面链接过)。

话虽如此,如果默认用户没有密码,Redis也不接受非本地接口上的连接——一个名为保护模式的安全层。因此,您应该给您的默认用户一个密码或禁用保护模式在您的redis.conf文件。

不确定这是否适用于你的情况,但是,作为旁注,我建议始终避免将Redis暴露在互联网上。

你把两件事混在一起了。要为不同名称空间中的pod启用此服务,您不需要外部负载平衡器,您可以尝试使用redis. namspace -name:6379 dns name,它将正常工作。这样的dns存在于您创建的每个服务中(但仅在kubernetes中工作)Kubernetes将确保您的流量将路由到适当的pod(假设有多个pod)。

如果你想从kubernetes外部公开redis,那么你需要确保有来自外部的连接,然后你需要网络负载均衡器将流量转发到你的kubernetes服务(在你的情况下节点端口,所以你需要NLB与周工作节点:30315作为目标)

如果你的工作节点有公共IP,并且它们的SecurityGroups允许直接连接到它们,你可以尝试直接连接到工作节点的IP,只是为了测试一下(没有LB)。

无论你的设置如何,你都可以通过kubectl

创建代理
kubectl port-forward -n redisNS svc/redis 6379:6379

并从spring boot应用程序连接到localhost:6379

你想在最后的设置中如何从app连接到redis ?

相关内容

  • 没有找到相关文章

最新更新