上一篇
"服务器又挂了!"凌晨两点,运维小王盯着监控大屏上飙升的CPU曲线苦笑,某当红社交APP的深夜活动引爆流量,每秒数十万登录请求让单节点Redis彻底瘫痪,这已经是本月第三次身份认证服务崩溃——是时候重新设计这套摇摇欲坠的系统了。
想象超市收银台只有一个通道:会员卡核验慢、排队越来越长,传统单体服务的认证系统就像这个场景:
2025年的真实数据显示:头部互联网应用的日均认证请求已突破百亿级,峰值QPS超过50万,要支撑这样的规模,我们需要两把利器:
# 创建6个Redis节点 for port in 7001 7002 7003 7004 7005 7006 do docker run -d --name redis-${port} \ -p ${port}:6379 -p 1${port}:16379 \ redis:7.2 redis-server --cluster-enabled yes done # 组建集群 echo "yes" | docker exec -i redis-7001 \ redis-cli --cluster create \ 172.17.0.2:6379 172.17.0.3:6379 \ 172.17.0.4:6379 172.17.0.5:6379 \ 172.17.0.6:6379 172.17.0.7:6379 \ --cluster-replicas 1
关键参数说明:
--cluster-enabled yes
:开启集群模式 16379
端口用于节点间通信 --cluster-replicas 1
:每个主节点配1个从节点 @Configuration public class RedisClusterConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { ClusterConfiguration config = new ClusterConfiguration() .clusterNode("172.17.0.2", 7001) .clusterNode("172.17.0.3", 7002); //...其他节点 return new JedisConnectionFactory(config); } }
sequenceDiagram 用户->>+认证服务: 提交用户名密码 认证服务->>+Redis集群: 写入用户权限数据(hash) Redis集群-->>-认证服务: 返回成功 认证服务->>-用户: 返回签名后的JWT 用户->>+业务服务: 携带JWT请求 业务服务->>+Redis集群: 校验令牌有效性 Redis集群-->>-业务服务: 返回用户权限 业务服务->>-用户: 返回业务数据
令牌签发(Java示例):
public String generateToken(User user) { // JWT载荷 Map<String, Object> claims = new HashMap<>(); claims.put("userId", user.getId()); // 生成令牌 String token = Jwts.builder() .setClaims(claims) .setExpiration(new Date(System.currentTimeMillis() + 3600000)) .signWith(SignatureAlgorithm.HS512, secret) .compact(); // 在Redis存储权限信息 redisTemplate.opsForHash().putAll( "auth:" + user.getId(), Map.of( "roles", String.join(",", user.getRoles()), "token", token ) ); return token; }
令牌校验中间件:
# Python Flask示例 def auth_required(f): @wraps(f) def decorator(*args, **kwargs): token = request.headers.get('Authorization') if not token: return {'error': 'Missing token'}, 401 try: # 解析JWT不验证过期 payload = jwt.decode(token, SECRET_KEY, algorithms=['HS512'], options={'verify_exp': False}) user_id = payload['userId'] # 检查Redis中的令牌有效性 redis_conn = get_redis_cluster() stored_token = redis_conn.hget(f"auth:{user_id}", "token") if stored_token != token: raise InvalidTokenError("Token revoked") except Exception as e: return {'error': str(e)}, 401 return f(*args, **kwargs) return decorator
传统JWT最大的痛点在此迎刃而解:
HSET auth:user123 status "inactive"
if ("inactive".equals(redisTemplate.opsForHash().get("auth:"+userId, "status")) { throw new TokenExpiredException("Token revoked"); }
采用读写分离策略:
CLUSTER KEYSLOT
命令保证相同用户请求总是路由到同一节点 使用JMeter模拟测试(单节点vs集群):
指标 | 单Redis节点 | Redis集群(3主3从) |
---|---|---|
认证QPS | 12,000 | 68,000 |
平均延迟 | 45ms | 8ms |
故障恢复时间 | 手动5分钟 | 自动20秒 |
redis_cluster_auth_hits
:认证缓存命中率 jwt_revoked_tokens
:主动失效令牌计数 凌晨四点的机房,新的认证集群平稳扛住了300万/分钟的登录请求,小王看着监控面板上均匀分布的节点负载,终于能安心喝口咖啡——这一次,技术跑在了业务爆发的
本文由 宋华池 于2025-08-01发表在【云服务器提供商】,文中图片由(宋华池)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/501910.html
发表评论