下面是一个完整的 Spring Boot + Kubernetes Redis Cluster 示例项目,包含:
- ✅ Spring Boot 应用(使用 Redisson 连接 Redis Cluster)
- ✅ Dockerfile(多阶段构建,轻量镜像)
- ✅ Kubernetes Deployment + Service(应用部署)
- ✅ Redis Cluster 部署(基于 Bitnami Helm)
- ✅ 端到端测试方法
你可以直接克隆、构建、部署到你的 K8s 集群。
📁 项目结构
springboot-redis-cluster-k8s/
├── src/
│ └── main/
│ ├── java/com/example/redlock/
│ │ ├── RedlockApplication.java
│ │ ├── config/RedissonConfig.java
│ │ ├── controller/OrderController.java
│ │ └── service/impl/OrderServiceImpl.java
│ └── resources/
│ ├── application.yml
│ └── bootstrap.yml (可选)
├── Dockerfile
├── k8s/
│ ├── app-deployment.yaml
│ └── app-service.yaml
├── redis-cluster-values.yaml
└── README.md
1️⃣ Spring Boot 应用代码
pom.xml(关键依赖)
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.25.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml
yaml
spring:
application:
name: springboot-redis-cluster-app
# Redis Cluster 配置(通过环境变量覆盖)
redisson:
cluster-servers-config:
node-addresses:
- "redis://redis-cluster-0.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
- "redis://redis-cluster-1.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
- "redis://redis-cluster-2.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
- "redis://redis-cluster-3.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
- "redis://redis-cluster-4.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
- "redis://redis-cluster-5.redis-cluster-headless.redis-cluster.svc.cluster.local:6379"
password: ${REDIS_PASSWORD:MySecureRedisPass123!}
connect-timeout: 10000
timeout: 3000
retry-attempts: 3
retry-interval: 1500
server:
port: 8080
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: always
💡 说明:
- 使用
redis://协议(非 rediss://,除非启用 TLS)- 密码通过
REDIS_PASSWORD环境变量注入(安全)
业务代码(略,参考前文 OrderServiceImpl)
2️⃣ Dockerfile(多阶段构建)
dockerfile
# springboot-redis-cluster-k8s/Dockerfile
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-alpine
RUN addgroup -g 1001 -S app && adduser -u 1001 -S app -G app
USER app
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
✅ 镜像大小约 200MB,安全无 root 用户
3️⃣ 构建并推送镜像(示例)
bash
# 构建
docker build -t your-registry/springboot-redis-cluster-app:v1.0 .
# 推送(替换为你的 registry)
docker push your-registry/springboot-redis-cluster-app:v1.0
🔁 如果使用 Minikube,可直接加载:
bashminikube image load springboot-redis-cluster-app:v1.0
4️⃣ Kubernetes 应用部署文件
k8s/app-deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-redis-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: springboot-redis-app
template:
metadata:
labels:
app: springboot-redis-app
spec:
containers:
- name: app
image: your-registry/springboot-redis-cluster-app:v1.0
ports:
- containerPort: 8080
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: password
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
k8s/app-service.yaml
yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-redis-app-svc
namespace: default
spec:
selector:
app: springboot-redis-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP # 或 LoadBalancer(云环境)
5️⃣ 创建 Redis 密码 Secret
bash
# 创建 Secret(与 Redis Cluster 密码一致)
kubectl create secret generic redis-secret \
--from-literal=password='MySecureRedisPass123!' \
-n default
⚠️ 必须与
redis-cluster-values.yaml中的密码相同
6️⃣ 部署 Redis Cluster(使用 Helm)
bash
# 创建命名空间
kubectl create namespace redis-cluster
# 安装 Redis Cluster(使用前文的 redis-cluster-values.yaml)
helm install redis-cluster bitnami/redis-cluster \
-n redis-cluster \
-f redis-cluster-values.yaml
✅ 确保
redis-cluster-values.yaml中auth.password与 Secret 一致
7️⃣ 部署 Spring Boot 应用
bash
# 应用部署
kubectl apply -f k8s/app-deployment.yaml
kubectl apply -f k8s/app-service.yaml
# 查看状态
kubectl get pods
kubectl get svc springboot-redis-app-svc
8️⃣ 端到端测试
方法 1:通过 Service 访问
bash
# 获取 Service IP(或使用 NodePort/Ingress)
APP_IP=$(kubectl get svc springboot-redis-app-svc -o jsonpath='{.spec.clusterIP}')
# 发起请求(模拟并发)
for i in {1..5}; do
curl "http://$APP_IP/create-order?userId=U1&orderId=O1001" &
done
方法 2:查看日志(验证分布式锁)
bash
kubectl logs -l app=springboot-redis-app --tail=50
预期日志(串行执行):
线程 http-nio-8080-exec-1 获取锁成功...
订单 O1001 创建成功
线程 http-nio-8080-exec-2 获取锁成功... # 下一个请求
🔒 安全与生产建议
| 项目 | 建议 |
|---|---|
| 镜像仓库 | 使用私有 Registry(如 Harbor、ECR) |
| Secret 管理 | 集成 Vault 或 Sealed Secrets |
| 网络策略 | 限制只有 app Pod 能访问 redis-cluster |
| 资源配额 | 为 namespace 设置 ResourceQuota |
| 监控 | 启用 Prometheus + Grafana 监控 Redis 和应用 |
🧪 故障排查命令
bash
# 检查 Redis Cluster 状态
kubectl exec -it redis-cluster-0 -n redis-cluster -- redis-cli -a MySecureRedisPass123! CLUSTER INFO
# 检查应用能否解析 Redis Headless Service
kubectl exec -it <app-pod> -- nslookup redis-cluster-headless.redis-cluster
# 查看应用连接错误
kubectl logs <app-pod> | grep -i redis
📦 一键部署脚本(可选)
创建 deploy-all.sh:
bash
#!/bin/bash
# 1. 部署 Redis Cluster
helm install redis-cluster bitnami/redis-cluster -n redis-cluster -f redis-cluster-values.yaml
# 2. 创建 Secret
kubectl create secret generic redis-secret --from-literal=password='MySecureRedisPass123!'
# 3. 部署应用
kubectl apply -f k8s/
✅ 至此,你已拥有一个完整的、生产就绪的 Spring Boot + Redis Cluster on K8s 解决方案!