Smart-SSO分布式部署踩坑实录:从POM依赖改写到Nginx配置的那些‘坑’
Smart-SSO分布式部署实战:从POM依赖到Nginx配置的深度避坑指南
去年我们团队在推进Smart-SSO分布式改造时,原以为按照官方文档两小时就能搞定,结果整整折腾了三天。这篇文章不是标准教程,而是我们踩过的坑和填坑经验。如果你正在实施类似项目,这些实战细节或许能帮你省下不少时间。
1. 环境准备阶段的隐藏陷阱
很多人以为环境搭建就是装个Redis和Nginx,但实际部署时我们发现版本兼容性是个大坑。官方文档写着Redis 6.2.1和Nginx 1.23.2,但我们的测试环境跑的是Redis 6.0.10,结果出现了诡异的连接超时问题。
关键组件版本对照表:
| 组件 | 官方推荐版本 | 实测兼容版本范围 | 不兼容表现 |
|---|---|---|---|
| Redis | 6.2.1 | 6.0.16+ / 7.0.0以下 | 连接池频繁超时 |
| Nginx | 1.23.2 | 1.21.0+ | X-Forwarded-For头丢失 |
| Spring Boot | - | 2.7.x | 自动配置冲突 |
提示:生产环境强烈建议使用Docker固定版本,避免"在我的机器上能跑"的问题。我们最终采用的组合是Redis 6.2.6 + Nginx 1.23.3。
本地Hosts配置也是个暗坑。文档里用的server.smart-sso.com和demo.smart-sso.com,但实际开发时:
# 错误配置(缺少IPv6条目) 127.0.0.1 server.smart-sso.com # 正确配置(需包含IPv6) 127.0.0.1 server.smart-sso.com ::1 server.smart-sso.com少了IPv6条目会导致某些浏览器随机性解析失败,特别是MacOS下的Chrome。
2. POM依赖的血泪教训
依赖替换看起来简单,但实际远比smart-sso-starter-client改成smart-sso-starter-client-redis复杂。我们遇到了三个典型问题:
- 依赖顺序问题:必须确保redis-starter在spring-boot-starter-data-redis之前
- 版本锁定缺失:多模块项目需要统一管理版本号
- 测试依赖污染:spring-boot-starter-test会引入内存Redis
这是我们的最终配置方案:
<!-- 正确依赖顺序示例 --> <dependency> <groupId>com.smart-sso</groupId> <artifactId>smart-sso-starter-client-redis</artifactId> <version>${smart-sso.version}</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>最坑的是smart-sso-starter-client-redis的自动配置会在特定条件下失效。当你的应用同时有@EnableCaching注解时,必须在application.yaml显式声明:
smart: sso: redis: enable: true # 必须显式开启3. Redis配置的魔鬼细节
官方示例的Redis配置过于简单,实际生产环境需要关注更多参数。我们经历过连接泄漏导致的生产事故,最终总结出这些关键配置项:
高可用Redis连接配置模板:
spring: redis: host: redis-cluster.example.com port: 6379 timeout: 3000ms # 重要!默认无限等待 lettuce: pool: max-active: 20 max-wait: 1000ms max-idle: 8 min-idle: 2 shutdown-timeout: 100ms cluster: nodes: - 10.0.0.1:6379 - 10.0.0.2:6379 max-redirects: 3注意:Smart-SSO的Token存储使用单独的Redis DB,不要和其他业务数据混用。我们曾因为DB冲突导致Token莫名失效。
连接超时问题排查时,这几个命令很有用:
# 查看Redis连接数 redis-cli info clients # 监控Redis命令 redis-cli monitor # 测试网络延迟 redis-cli --latency -h your-redis-host4. Nginx配置的进阶技巧
反向代理配置不当会导致一系列诡异问题,特别是获取真实IP和Session保持。这是我们的优化版配置:
upstream sso_servers { zone sso_servers 64k; server 10.31.88.96:8090 weight=3; server 10.31.88.96:8091; keepalive 32; # 长连接提升性能 } server { listen 80; server_name server.smart-sso.com; # 真实IP传递(多层代理场景) set_real_ip_from 10.0.0.0/8; real_ip_header X-Forwarded-For; real_ip_recursive on; location / { proxy_pass http://sso_servers; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 超时设置 proxy_connect_timeout 3s; proxy_read_timeout 10s; # 健康检查 health_check interval=5s fails=3 passes=2 uri=/health; } }特别提醒几个容易忽略的点:
proxy_http_version 1.1和Connection ""必须配合使用才能启用keepalive- 权重分配(weight)可以配合金丝雀发布
- 健康检查路径需要与后端应用匹配
我们在压力测试时发现,缺少real_ip_recursive on会导致某些场景下获取的IP是内网代理IP而非真实客户端IP。
5. 分布式验证的完整方案
验证环节不能只检查是否能登录,需要系统性地验证:
基础功能验证:
- 多浏览器同时登录/登出
- 跨子域名的单点登录
- Token过期自动刷新
分布式场景验证:
// 验证代码示例 @Test public void testTokenSync() { // 实例1写入 String token = ssoClient1.login("user1", "pass"); // 实例2读取 UserInfo user = ssoClient2.validate(token); assertNotNull(user); // 实例1注销 ssoClient1.logout(token); // 实例2验证失效 assertThrows(SsoException.class, () -> ssoClient2.validate(token)); }性能测试要点:
- 模拟Redis网络抖动时的降级表现
- 高并发Token续期场景
- Nginx reload时的请求无损
我们自研了一套验证工具集,关键指标包括:
- Token同步延迟 ≤ 50ms
- 故障转移时间 ≤ 3s
- 99%登录响应时间 ≤ 300ms
6. 监控与排错体系建设
上线后我们建立了完整的监控体系,这几个指标最为关键:
Smart-SSO核心监控指标:
| 指标名称 | 采集方式 | 报警阈值 | 应对措施 |
|---|---|---|---|
| Token生成QPS | Prometheus | 突增50% | 检查是否遭到爬虫 |
| Redis连接池等待数 | Micrometer | 持续>5 | 扩容连接池或Redis集群 |
| Nginx upstream响应时间 | Nginx Plus | P99>500ms | 优化后端服务或增加节点 |
| 跨DC同步延迟 | 自定义探针 | >200ms持续5min | 检查专线网络 |
排错时这个命令组合能快速定位问题:
# 查看Nginx路由情况 tail -f /var/log/nginx/access.log | grep '502\|503\|504' # 检查Redis键状态 redis-cli --scan --pattern 'smart:sso:*' | xargs redis-cli ttl # 追踪Java应用请求 arthas trace com.smart.sso.SsoController login7. 生产环境特别注意事项
经过三个月的生产运行,我们总结出这些经验:
冷启动问题:当Redis集群全部重启后,所有Token失效。解决方案是逐步重启应用实例,或者实现本地Token缓存降级。
地域延迟:跨国部署时,建议采用区域化Redis集群+中心同步的方案。我们在东京和法兰克福节点就曾因为150ms+的网络延迟导致登录超时。
安全加固:
- 禁用Redis的CONFIG命令
- 为Smart-SSO的Redis键设置单独密码
- Nginx配置WAF规则防护暴力破解
灰度发布策略:
- 先更新1个服务端实例
- 观察15分钟无异常再全量
- 客户端保持向后兼容
文档陷阱:官方文档的
proxy_set_header配置在某些Nginx版本会导致Host头重复。我们最终采用的方案是:
proxy_set_header Host $http_host; # 替代原来的$host在阿里云环境还遇到个特别案例:他们的SLB会修改X-Forwarded-For,需要额外配置:
set_real_ip_from 100.64.0.0/10; # 阿里云内网段