概述
随着数据量和业务量的增长,传统单体架构面临响应速度慢、扩展成本高的挑战,分布式架构可以将原本集成在一个大系统中的业务功能划分为多个微服务,凭借其高并发、高可用、高扩展的技术特性,解决这一问题。
高并发,高可用,高扩展的区别是什么?
高可用 :在分布式系统架构下,高可用是最基本的要求,即分布式集群系统中,某几个服务实例处于宕机或其他不可用状态下,系统对外还是可以提供接口响应能力。
高并发 :接下来是高并发,对于单机来谈,一般是说每秒可以承载很高的用户请求量。对于分布式系统来说,即是这些一个个的单机组合起来可以承载很高的用户请求量。
高扩展 :而为了可以实现线上高并发和高可用,可以利用高扩展的方法。如果是对业务服务来说,就是尽可能采用无状态的设计,可以随时上线更多的实例,达到动态扩展线上服务承载能力的需求;对于像 rocketmq、elasticsearch 等支持海量数据的中间件来说,就是通过数据分片、集群数据同步等机制透明化的支撑高扩展能力
应具备的分布式关键能力
分布式事务
分布式数据
分布式调度
分布式缓存
分布式消息
全局序列
- 全局序列生成器作为单独的组件部署,内部使用相关算法(例如雪花算法)生成唯一id,生成id的方法加synchronized关键字,保证线程安全。
- 可以预生成一批序列号,存储在缓存中。当需要生成序列号时,可以直接从缓存中获取,避免了每次请求都进行序列号的计算。
- 从缓存中获取id的方法视情况判断是否需要加分布式锁。
代码示例
public String getSequenceNumber() {
// 获取分布式锁
boolean acquiredLock = false;
while (!acquiredLock) {
// 尝试获取锁,设置过期时间为 1 秒,防止死锁
acquiredLock = "OK".equals(jedis.set(LOCK_KEY, "lock", "NX", "EX", 1));
if (acquiredLock) {
try {
// 检查缓存中的序列号
String sequenceNumber = jedis.rpop(SEQUENCE_KEY);
if (sequenceNumber != null) {
return sequenceNumber;
} else {
// 缓存中没有序列号,需要重新生成
generateSequenceNumbers();
}
} finally {
// 释放锁
jedis.del(LOCK_KEY);
}
} else {
// 未获取到锁,等待一段时间后重试
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// 处理中断异常
Thread.currentThread().interrupt();
}
}
}
return null;
}
private void generateSequenceNumbers() {
// 在这里实现生成一批序列号的逻辑,然后存储到缓存中
// 例如,生成一批从 1 开始的连续序列号,并存储到 Redis 缓存中
for (int number = 1; number <= 100; number++) {
jedis.lpush(SEQUENCE_KEY, String.valueOf(number));
}
}
参考链接
https://youle.zhipin.com/questions/70b79625ab383ee0tnZ5296-Elo~.html