亿级分布式系统架构演进实战(一)- 总体概要
亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(三)- 横向扩展(数据库读写分离)
亿级分布式系统架构演进实战(四)- 横向扩展(负载均衡与弹性伸缩)
亿级分布式系统架构演进实战(五)- 横向扩展(缓存策略设计)
亿级分布式系统架构演进实战(六)- 横向扩展(监控与日志体系)
保障系统免受攻击,确保数据安全
技术方案:
• 云厂商高防IP:
# 阿里云高防IP配置示例
aliyun ddoscoo add-domain --domain www.example.com --instance-id ddoscoo-xxxx
• Web应用防火墙(WAF):
# Nginx WAF规则(ModSecurity)
SecRuleEngine On
SecRule REQUEST_URI "@contains /api" "id:1001,deny,status:403"
防护策略:
• 流量清洗:自动过滤畸形报文(SYN Flood、UDP反射攻击)
• 速率限制:基于IP的请求速率限制(如单IP QPS < 100)
熔断与降级(Sentinel):
// 定义流控规则:每秒最多1000次请求
FlowRule rule = new FlowRule("api/resource")
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(1000);
FlowRuleManager.loadRules(Collections.singletonList(rule));
// 异常降级处理
@SentinelResource(value = "api/resource", blockHandler = "handleBlock")
public String getResource() {
// 业务逻辑
}
动态权重调整:
# Spring Cloud Gateway限流配置
spring:
cloud:
gateway:
routes:
- id: api_route
uri: lb://api-service
predicates:
- Path=/api/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100 # 每秒100请求
redis-rate-limiter.burstCapacity: 200
多维度限流:
| 维度 | 实现方式 | 示例规则 |
|---|---|---|
| IP | Redis计数器(INCR + EXPIRE) | 单IP每秒最多50次请求 |
| 用户 | 结合Token Bucket算法 | 用户级每秒最多10次请求 |
Redis实现IP限流:
-- KEYS[1]=ip, ARGV[1]=限流阈值
local count = redis.call('INCR', KEYS[1])
if count == 1 then
redis.call('EXPIRE', KEYS[1], 1)
end
if count > tonumber(ARGV[1]) then
return 0
end
return 1
生产级配置:
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
}
证书管理:
• 使用Let’s Encrypt自动续签
• 密钥存储于HashiCorp Vault,动态加载
敏感数据脱敏:
// 日志脱敏处理(示例)
public String maskSensitiveData(String data) {
return data.replaceAll("(\d{3})\d{4}(\d{4})", "$1****$2"); // 手机号脱敏
}
加密存储:
-- MySQL加密字段
CREATE TABLE users (
id INT PRIMARY KEY,
mobile VARBINARY(128) -- 使用AES加密存储
);
-- 加密示例
INSERT INTO users VALUES (1, AES_ENCRYPT('13800138000', 'encryption_key'));
令牌生成与验证:
// JWT生成
String token = Jwts.builder()
.setSubject("user123")
.signWith(SignatureAlgorithm.HS256, "secret_key")
.compact();
// 网关鉴权
public class AuthFilter implements GatewayFilter {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
Jwts.parser().setSigningKey("secret_key").parseClaimsJws(token);
return chain.filter(exchange);
}
}
数据库最小权限原则:
-- 创建只读账户
CREATE USER 'readonly'@'%' IDENTIFIED BY 'password';
GRANT SELECT ON db.* TO 'readonly'@'%';
RBAC模型实现:
# 权限配置文件
roles:
admin:
- "CREATE"
- "DELETE"
user:
- "READ"
- "UPDATE"
问题:主从同步延迟导致脏读
解决方案:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
@Transactional(readOnly = true)
@Hint("force_master") // 自定义注解
public User getUser(String id) {
return userRepository.findById(id);
}
SET user:profile:1001 "data" EX 30 # 过期时间缩短至30秒
问题:热点用户请求倾斜
解决方案:
upstream backend {
hash $request_uri consistent; # Nginx配置
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
spring:
cloud:
loadbalancer:
configurations: weighted
weights:
service1: 3
service2: 1
问题:多级缓存间数据不一致
解决方案:
数据库更新 → 删除Redis → 广播失效本地缓存
String version = redis.incr("cache_version:user:1001");
redis.set("user:1001:v" + version, data);
问题:跨服务事务失败
解决方案:
@Saga
public void createOrder(Order order) {
saga.begin()
.step(() -> inventoryService.lockStock(order))
.step(() -> paymentService.deductBalance(order))
.onRollback(() -> notificationService.notifyFailure(order))
.commit();
}
CREATE TABLE outbox (
id BIGINT PRIMARY KEY,
payload JSON,
status ENUM('pending', 'sent')
);
问题:细粒度指标缺失
解决方案:
Counter counter = Metrics.counter("api.request.count", "uri", "/api/users");
counter.increment();
spring:
sleuth:
sampler:
probability: 1.0 # 100%采样
问题:DDoS攻击
解决方案:
iptables -A INPUT -p tcp --dport 80 -m limit --limit 1000/minute -j ACCEPT
spring:
cloud:
gateway:
routes:
- id: api_route
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@remoteAddrKeyResolver}"
redis-rate-limiter.replenishRate: 100
问题:数据库主库故障
解决方案:
# 使用ProxySQL配置故障转移
mysql_replication_hostgroups:
- writer_hostgroup: 10
reader_hostgroup: 20
comment: "cluster1"
vitessctl -- ApplySchema --sql "ALTER VSCHEMA ADD TABLE users" keyspace