1. 百万级用户高并发架构概述

在互联网时代,支撑百万级用户的高并发系统是企业核心竞争力的体现。本文将详细介绍如何设计、实现和优化支撑百万级用户的Java高并发架构,包括系统架构设计、性能优化、缓存策略、数据库优化等完整解决方案。

1.1 核心挑战

  1. 高并发访问: 同时处理大量用户请求
  2. 数据一致性: 保证数据在并发环境下的正确性
  3. 系统稳定性: 确保系统在高负载下稳定运行
  4. 性能优化: 提升系统响应速度和吞吐量
  5. 可扩展性: 支持系统水平扩展和垂直扩展

1.2 技术架构

1
2
3
4
5
用户请求 → 负载均衡 → 应用集群 → 缓存层 → 数据库集群
↓ ↓ ↓ ↓ ↓
CDN加速 → 网关服务 → 微服务 → Redis集群 → 读写分离
↓ ↓ ↓ ↓ ↓
静态资源 → 服务治理 → 异步处理 → 消息队列 → 分库分表

2. 高并发架构设计

2.1 Maven依赖配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!-- pom.xml -->
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Spring Boot Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>

<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>

<!-- RabbitMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

<!-- Guava缓存 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>

<!-- Caffeine缓存 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.1</version>
</dependency>

<!-- HikariCP连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>

2.2 应用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# application.yml
server:
port: 8080
tomcat:
threads:
max: 200
min-spare: 10
max-connections: 8192
accept-count: 100
connection-timeout: 20000

spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 10
min-idle: 10
max-active: 100
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20

redis:
host: localhost
port: 6379
password:
database: 0
timeout: 5000
lettuce:
pool:
max-active: 200
max-idle: 20
min-idle: 5
max-wait: 10000

rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
connection-timeout: 15000
publisher-confirm-type: correlated
publisher-returns: true
listener:
simple:
acknowledge-mode: manual
concurrency: 10
max-concurrency: 20
prefetch: 1

# MyBatis Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
jdbc-type-for-null: 'null'
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0

3. 缓存架构设计

3.1 多级缓存配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
* 缓存配置类
* 实现多级缓存架构:本地缓存 + Redis缓存
*/
@Configuration
@EnableCaching
public class CacheConfig {

/**
* 本地缓存配置 - Caffeine
*/
@Bean
public CacheManager localCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(10000) // 最大缓存数量
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.expireAfterAccess(5, TimeUnit.MINUTES) // 访问后5分钟过期
.recordStats()); // 开启统计
return cacheManager;
}

/**
* Redis缓存配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);

// 设置序列化器
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);

template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);

template.afterPropertiesSet();
return template;
}

/**
* 缓存键生成器
*/
@Bean
public KeyGenerator cacheKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(":");
sb.append(method.getName());
for (Object obj : params) {
sb.append(":").append(obj.toString());
}
return sb.toString();
};
}
}

3.2 缓存服务实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* 缓存服务实现类
* 提供多级缓存操作接口
*/
@Service
public class CacheService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private CacheManager localCacheManager;

/**
* 获取缓存数据
* 先查本地缓存,再查Redis缓存
*/
public <T> T get(String key, Class<T> clazz) {
// 1. 先查本地缓存
Cache localCache = localCacheManager.getCache("localCache");
if (localCache != null) {
Cache.ValueWrapper wrapper = localCache.get(key);
if (wrapper != null) {
return (T) wrapper.get();
}
}

// 2. 再查Redis缓存
Object value = redisTemplate.opsForValue().get(key);
if (value != null) {
// 写入本地缓存
if (localCache != null) {
localCache.put(key, value);
}
return (T) value;
}

return null;
}

/**
* 设置缓存数据
* 同时写入本地缓存和Redis缓存
*/
public void set(String key, Object value, long timeout, TimeUnit unit) {
// 1. 写入Redis缓存
redisTemplate.opsForValue().set(key, value, timeout, unit);

// 2. 写入本地缓存
Cache localCache = localCacheManager.getCache("localCache");
if (localCache != null) {
localCache.put(key, value);
}
}

/**
* 删除缓存数据
* 同时删除本地缓存和Redis缓存
*/
public void delete(String key) {
// 1. 删除Redis缓存
redisTemplate.delete(key);

// 2. 删除本地缓存
Cache localCache = localCacheManager.getCache("localCache");
if (localCache != null) {
localCache.evict(key);
}
}

/**
* 批量获取缓存数据
*/
public <T> Map<String, T> multiGet(Set<String> keys, Class<T> clazz) {
Map<String, T> result = new HashMap<>();

for (String key : keys) {
T value = get(key, clazz);
if (value != null) {
result.put(key, value);
}
}

return result;
}

/**
* 批量设置缓存数据
*/
public void multiSet(Map<String, Object> keyValues, long timeout, TimeUnit unit) {
for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
set(entry.getKey(), entry.getValue(), timeout, unit);
}
}
}

4. 数据库优化

4.1 数据库连接池配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* 数据库配置类
* 优化数据库连接池性能
*/
@Configuration
public class DatabaseConfig {

/**
* 主数据源配置
*/
@Bean
@Primary
@ConfigurationProperties("spring.datasource.druid")
public DataSource masterDataSource() {
return DruidDataSourceBuilder.create().build();
}

/**
* 从数据源配置
*/
@Bean
@ConfigurationProperties("spring.datasource.slave")
public DataSource slaveDataSource() {
return DruidDataSourceBuilder.create().build();
}

/**
* 动态数据源配置
*/
@Bean
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceMap.put("master", masterDataSource());
dataSourceMap.put("slave", slaveDataSource());

dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());

return dynamicDataSource;
}

/**
* JPA配置
*/
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dynamicDataSource());
factory.setPackagesToScan("com.example.entity");

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(false);

factory.setJpaVendorAdapter(vendorAdapter);

Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
properties.setProperty("hibernate.hbm2ddl.auto", "none");
properties.setProperty("hibernate.jdbc.batch_size", "50");
properties.setProperty("hibernate.order_inserts", "true");
properties.setProperty("hibernate.order_updates", "true");
properties.setProperty("hibernate.jdbc.batch_versioned_data", "true");

factory.setJpaProperties(properties);
return factory;
}
}

4.2 读写分离实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* 读写分离数据源路由
*/
public class DynamicDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}

/**
* 数据源上下文持有者
*/
public class DataSourceContextHolder {

private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

/**
* 设置数据源类型
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}

/**
* 获取数据源类型
*/
public static String getDataSourceType() {
return contextHolder.get();
}

/**
* 清除数据源类型
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}

/**
* 数据源切换注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value() default "master";
}

/**
* 数据源切换AOP
*/
@Aspect
@Component
public class DataSourceAspect {

@Pointcut("@annotation(com.example.annotation.DataSource)")
public void dataSourcePointcut() {}

@Around("dataSourcePointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class);

if (dataSource != null) {
DataSourceContextHolder.setDataSourceType(dataSource.value());
}

try {
return point.proceed();
} finally {
DataSourceContextHolder.clearDataSourceType();
}
}
}

5. 异步处理架构

5.1 消息队列配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* 消息队列配置类
* 配置RabbitMQ消息队列
*/
@Configuration
@EnableRabbit
public class RabbitMQConfig {

/**
* 用户注册队列
*/
@Bean
public Queue userRegisterQueue() {
return QueueBuilder.durable("user.register.queue")
.withArgument("x-message-ttl", 60000) // 消息TTL
.withArgument("x-max-length", 10000) // 队列最大长度
.build();
}

/**
* 用户注册交换机
*/
@Bean
public DirectExchange userRegisterExchange() {
return new DirectExchange("user.register.exchange");
}

/**
* 绑定用户注册队列和交换机
*/
@Bean
public Binding userRegisterBinding() {
return BindingBuilder.bind(userRegisterQueue())
.to(userRegisterExchange())
.with("user.register");
}

/**
* 消息转换器
*/
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}

/**
* 连接工厂配置
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setConnectionTimeout(15000);
factory.setRequestedHeartBeat(60);
factory.setPublisherConfirms(true);
factory.setPublisherReturns(true);
return factory;
}

/**
* RabbitTemplate配置
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(messageConverter());
template.setMandatory(true);
template.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
log.info("消息发送成功: {}", correlationData);
} else {
log.error("消息发送失败: {}, 原因: {}", correlationData, cause);
}
});
template.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
log.error("消息返回: {}, 回复码: {}, 回复文本: {}, 交换机: {}, 路由键: {}",
message, replyCode, replyText, exchange, routingKey);
});
return template;
}
}

5.2 异步消息处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* 用户服务实现类
* 处理用户注册等业务逻辑
*/
@Service
public class UserService {

@Autowired
private UserMapper userMapper;

@Autowired
private RabbitTemplate rabbitTemplate;

@Autowired
private CacheService cacheService;

/**
* 用户注册
* 同步处理核心业务,异步处理非核心业务
*/
@Transactional
public void registerUser(User user) {
// 1. 同步处理核心业务
userMapper.insert(user);

// 2. 异步处理非核心业务
UserRegisterEvent event = new UserRegisterEvent();
event.setUserId(user.getId());
event.setUsername(user.getUsername());
event.setEmail(user.getEmail());
event.setRegisterTime(new Date());

rabbitTemplate.convertAndSend("user.register.exchange", "user.register", event);

// 3. 更新缓存
cacheService.set("user:" + user.getId(), user, 30, TimeUnit.MINUTES);
}

/**
* 获取用户信息
* 先查缓存,再查数据库
*/
public User getUserById(Long userId) {
// 1. 先查缓存
User user = cacheService.get("user:" + userId, User.class);
if (user != null) {
return user;
}

// 2. 再查数据库
user = userMapper.selectById(userId);
if (user != null) {
// 写入缓存
cacheService.set("user:" + userId, user, 30, TimeUnit.MINUTES);
}

return user;
}

/**
* 批量获取用户信息
*/
public List<User> getUsersByIds(List<Long> userIds) {
List<User> users = new ArrayList<>();
List<Long> notInCacheIds = new ArrayList<>();

// 1. 批量查缓存
Set<String> cacheKeys = userIds.stream()
.map(id -> "user:" + id)
.collect(Collectors.toSet());
Map<String, User> cacheUsers = cacheService.multiGet(cacheKeys, User.class);

// 2. 找出缓存中没有的用户ID
for (Long userId : userIds) {
User user = cacheUsers.get("user:" + userId);
if (user != null) {
users.add(user);
} else {
notInCacheIds.add(userId);
}
}

// 3. 批量查数据库
if (!notInCacheIds.isEmpty()) {
List<User> dbUsers = userMapper.selectBatchIds(notInCacheIds);
users.addAll(dbUsers);

// 批量写入缓存
Map<String, Object> cacheData = dbUsers.stream()
.collect(Collectors.toMap(
user -> "user:" + user.getId(),
user -> user
));
cacheService.multiSet(cacheData, 30, TimeUnit.MINUTES);
}

return users;
}
}

/**
* 用户注册事件监听器
* 异步处理用户注册后的非核心业务
*/
@Component
@RabbitListener(queues = "user.register.queue")
public class UserRegisterListener {

@Autowired
private EmailService emailService;

@Autowired
private SmsService smsService;

@Autowired
private UserStatisticsService userStatisticsService;

/**
* 处理用户注册事件
*/
@RabbitHandler
public void handleUserRegister(UserRegisterEvent event) {
try {
// 1. 发送欢迎邮件
emailService.sendWelcomeEmail(event.getEmail(), event.getUsername());

// 2. 发送欢迎短信
smsService.sendWelcomeSms(event.getUsername());

// 3. 更新用户统计
userStatisticsService.incrementRegisterCount();

// 4. 记录用户行为
log.info("用户注册成功: userId={}, username={}",
event.getUserId(), event.getUsername());

} catch (Exception e) {
log.error("处理用户注册事件失败: {}", e.getMessage(), e);
// 可以发送到死信队列或重试队列
}
}
}

6. 限流和熔断

6.1 限流配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* 限流配置类
* 实现基于Redis的分布式限流
*/
@Configuration
public class RateLimitConfig {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

/**
* 令牌桶限流器
*/
@Bean
public RateLimiter rateLimiter() {
return RateLimiter.create(100.0); // 每秒100个请求
}

/**
* Redis限流器
*/
@Bean
public RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(redisTemplate);
}
}

/**
* Redis限流器实现
*/
@Component
public class RedisRateLimiter {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

/**
* 滑动窗口限流
*/
public boolean isAllowed(String key, int limit, int windowSizeInSeconds) {
String script =
"local key = KEYS[1] " +
"local limit = tonumber(ARGV[1]) " +
"local window = tonumber(ARGV[2]) " +
"local current = redis.call('INCR', key) " +
"if current == 1 then " +
" redis.call('EXPIRE', key, window) " +
"end " +
"return current <= limit";

DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(script);
redisScript.setResultType(Long.class);

Long result = redisTemplate.execute(redisScript,
Collections.singletonList(key),
limit, windowSizeInSeconds);

return result != null && result <= limit;
}

/**
* 令牌桶限流
*/
public boolean isAllowedWithTokenBucket(String key, int capacity, int refillRate) {
String script =
"local key = KEYS[1] " +
"local capacity = tonumber(ARGV[1]) " +
"local refillRate = tonumber(ARGV[2]) " +
"local now = redis.call('TIME')[1] " +
"local bucket = redis.call('HMGET', key, 'tokens', 'lastRefill') " +
"local tokens = tonumber(bucket[1]) or capacity " +
"local lastRefill = tonumber(bucket[2]) or now " +
"local delta = math.max(0, now - lastRefill) " +
"tokens = math.min(capacity, tokens + delta * refillRate) " +
"if tokens >= 1 then " +
" tokens = tokens - 1 " +
" redis.call('HMSET', key, 'tokens', tokens, 'lastRefill', now) " +
" redis.call('EXPIRE', key, 3600) " +
" return 1 " +
"else " +
" redis.call('HMSET', key, 'tokens', tokens, 'lastRefill', now) " +
" redis.call('EXPIRE', key, 3600) " +
" return 0 " +
"end";

DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(script);
redisScript.setResultType(Long.class);

Long result = redisTemplate.execute(redisScript,
Collections.singletonList(key),
capacity, refillRate);

return result != null && result == 1;
}
}

/**
* 限流注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
String key() default "";
int limit() default 100;
int window() default 60;
}

/**
* 限流AOP
*/
@Aspect
@Component
public class RateLimitAspect {

@Autowired
private RedisRateLimiter redisRateLimiter;

@Pointcut("@annotation(com.example.annotation.RateLimit)")
public void rateLimitPointcut() {}

@Around("rateLimitPointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
RateLimit rateLimit = signature.getMethod().getAnnotation(RateLimit.class);

String key = rateLimit.key();
if (StringUtils.isEmpty(key)) {
key = signature.getMethod().getName();
}

boolean allowed = redisRateLimiter.isAllowed(key, rateLimit.limit(), rateLimit.window());
if (!allowed) {
throw new RateLimitException("请求过于频繁,请稍后再试");
}

return point.proceed();
}
}

6.2 熔断器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* 熔断器配置类
* 实现服务熔断和降级
*/
@Configuration
public class CircuitBreakerConfig {

/**
* 熔断器配置
*/
@Bean
public CircuitBreaker circuitBreaker() {
return CircuitBreaker.ofDefaults("default")
.withFailureThreshold(50) // 失败率阈值50%
.withWaitDurationInOpenState(Duration.ofSeconds(30)) // 熔断30秒
.withRingBufferSizeInHalfOpenState(10) // 半开状态下的请求数
.withRingBufferSizeInClosedState(100); // 关闭状态下的请求数
}

/**
* 重试配置
*/
@Bean
public Retry retry() {
return Retry.ofDefaults("default")
.withMaxAttempts(3) // 最大重试3次
.withWaitDuration(Duration.ofSeconds(1)); // 重试间隔1秒
}

/**
* 超时配置
*/
@Bean
public Timeout timeout() {
return Timeout.of(Duration.ofSeconds(5)); // 超时5秒
}
}

/**
* 熔断器服务
*/
@Service
public class CircuitBreakerService {

@Autowired
private CircuitBreaker circuitBreaker;

@Autowired
private Retry retry;

@Autowired
private Timeout timeout;

/**
* 执行带熔断保护的方法
*/
public <T> T executeWithCircuitBreaker(Supplier<T> supplier, Supplier<T> fallback) {
Supplier<T> decoratedSupplier = CircuitBreaker.decorateSupplier(circuitBreaker, supplier);
decoratedSupplier = Retry.decorateSupplier(retry, decoratedSupplier);
decoratedSupplier = Timeout.decorateSupplier(timeout, decoratedSupplier);

try {
return decoratedSupplier.get();
} catch (Exception e) {
log.error("执行失败,使用降级方案: {}", e.getMessage());
return fallback.get();
}
}

/**
* 执行带熔断保护的异步方法
*/
public <T> CompletableFuture<T> executeAsyncWithCircuitBreaker(
Supplier<T> supplier, Supplier<T> fallback) {
return CompletableFuture.supplyAsync(() ->
executeWithCircuitBreaker(supplier, fallback));
}
}

7. 性能监控

7.1 性能监控配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* 性能监控配置类
* 集成Micrometer进行性能监控
*/
@Configuration
@EnableMetrics
public class MetricsConfig {

/**
* 自定义指标
*/
@Bean
public MeterRegistry meterRegistry() {
return new SimpleMeterRegistry();
}

/**
* 请求计数器
*/
@Bean
public Counter requestCounter(MeterRegistry meterRegistry) {
return Counter.builder("http.requests.total")
.description("Total number of HTTP requests")
.register(meterRegistry);
}

/**
* 请求耗时计时器
*/
@Bean
public Timer requestTimer(MeterRegistry meterRegistry) {
return Timer.builder("http.request.duration")
.description("HTTP request duration")
.register(meterRegistry);
}

/**
* 活跃连接数
*/
@Bean
public Gauge activeConnections(MeterRegistry meterRegistry) {
return Gauge.builder("http.connections.active")
.description("Number of active HTTP connections")
.register(meterRegistry, this, MetricsConfig::getActiveConnections);
}

private double getActiveConnections() {
// 获取活跃连接数的逻辑
return 0.0;
}
}

/**
* 性能监控AOP
*/
@Aspect
@Component
public class MetricsAspect {

@Autowired
private Counter requestCounter;

@Autowired
private Timer requestTimer;

@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void requestMappingPointcut() {}

@Around("requestMappingPointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Timer.Sample sample = Timer.start(requestTimer);

try {
requestCounter.increment();
return point.proceed();
} finally {
sample.stop(requestTimer);
}
}
}

7.2 健康检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* 健康检查配置
*/
@Configuration
public class HealthCheckConfig {

/**
* 数据库健康检查
*/
@Bean
public HealthIndicator databaseHealthIndicator() {
return new AbstractHealthIndicator() {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
// 检查数据库连接
builder.up()
.withDetail("database", "MySQL")
.withDetail("status", "UP");
}
};
}

/**
* Redis健康检查
*/
@Bean
public HealthIndicator redisHealthIndicator() {
return new AbstractHealthIndicator() {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
// 检查Redis连接
builder.up()
.withDetail("redis", "Redis")
.withDetail("status", "UP");
}
};
}

/**
* 自定义健康检查
*/
@Component
public class CustomHealthIndicator implements HealthIndicator {

@Override
public Health health() {
// 检查系统状态
boolean isHealthy = checkSystemHealth();

if (isHealthy) {
return Health.up()
.withDetail("system", "OK")
.withDetail("timestamp", System.currentTimeMillis())
.build();
} else {
return Health.down()
.withDetail("system", "ERROR")
.withDetail("timestamp", System.currentTimeMillis())
.build();
}
}

private boolean checkSystemHealth() {
// 检查系统健康状态的逻辑
return true;
}
}
}

8. 系统优化策略

8.1 JVM优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# JVM参数优化
-Xms2g -Xmx2g # 堆内存大小
-XX:NewRatio=1 # 新生代与老年代比例
-XX:SurvivorRatio=8 # Eden与Survivor比例
-XX:+UseG1GC # 使用G1垃圾收集器
-XX:MaxGCPauseMillis=200 # 最大GC暂停时间
-XX:+UseStringDeduplication # 字符串去重
-XX:+OptimizeStringConcat # 字符串连接优化
-XX:+UseCompressedOops # 压缩指针
-XX:+UseCompressedClassPointers # 压缩类指针
-XX:+TieredCompilation # 分层编译
-XX:CompileThreshold=10000 # 编译阈值
-XX:+PrintGCDetails # 打印GC详情
-XX:+PrintGCTimeStamps # 打印GC时间戳
-Xloggc:gc.log # GC日志文件

8.2 应用优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* 应用优化配置
*/
@Configuration
public class ApplicationOptimizationConfig {

/**
* 线程池配置
*/
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20); // 核心线程数
executor.setMaxPoolSize(100); // 最大线程数
executor.setQueueCapacity(200); // 队列容量
executor.setKeepAliveSeconds(60); // 线程存活时间
executor.setThreadNamePrefix("async-"); // 线程名前缀
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}

/**
* HTTP客户端配置
*/
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(5000); // 连接超时
factory.setReadTimeout(10000); // 读取超时
factory.setConnectionRequestTimeout(3000); // 请求超时

RestTemplate restTemplate = new RestTemplate(factory);

// 添加拦截器
restTemplate.getInterceptors().add(new LoggingRequestInterceptor());

return restTemplate;
}

/**
* 对象池配置
*/
@Bean
public GenericObjectPool<HttpClient> httpClientPool() {
GenericObjectPoolConfig<HttpClient> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(100); // 最大连接数
config.setMaxIdle(20); // 最大空闲连接数
config.setMinIdle(5); // 最小空闲连接数
config.setMaxWaitMillis(3000); // 最大等待时间
config.setTestOnBorrow(true); // 借用时测试
config.setTestOnReturn(true); // 归还时测试
config.setTestWhileIdle(true); // 空闲时测试

return new GenericObjectPool<>(new HttpClientFactory(), config);
}
}

9. 总结

本文详细介绍了支撑百万级用户的Java高并发架构设计,包括:

9.1 核心技术点

  1. 多级缓存架构: 本地缓存 + Redis缓存,提升数据访问性能
  2. 数据库优化: 读写分离、连接池优化、批量操作
  3. 异步处理: 消息队列、异步任务、事件驱动
  4. 限流熔断: 分布式限流、服务熔断、降级策略
  5. 性能监控: 指标监控、健康检查、性能分析
  6. 系统优化: JVM优化、应用优化、资源管理

9.2 架构优势

  1. 高性能: 通过缓存、异步、优化等手段提升系统性能
  2. 高可用: 通过熔断、降级、监控等手段保证系统可用性
  3. 可扩展: 通过微服务、集群、分库分表等手段支持系统扩展
  4. 可维护: 通过监控、日志、健康检查等手段便于系统维护

9.3 最佳实践

  1. 缓存策略: 合理使用多级缓存,注意缓存一致性和过期策略
  2. 数据库优化: 合理设计索引,优化SQL语句,使用批量操作
  3. 异步处理: 核心业务同步处理,非核心业务异步处理
  4. 限流策略: 根据业务特点选择合适的限流算法和参数
  5. 监控告警: 建立完善的监控体系,及时发现和处理问题

通过以上架构设计和优化策略,可以构建支撑百万级用户的高并发系统,满足业务发展的需要。