Compare commits
2 Commits
718bbf9ddd
...
96625fc77a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96625fc77a | ||
|
|
17b8f69c19 |
@ -132,6 +132,32 @@ public class ThreadPoolConfig {
|
|||||||
executor.initialize();
|
executor.initialize();
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审计事件处理线程池 - 使用虚拟线程(Java 21+)
|
||||||
|
*
|
||||||
|
* ⚠️ 为什么使用虚拟线程?
|
||||||
|
* 1. 审计事件处理是**I/O密集型**任务(写日志、写数据库)
|
||||||
|
* 2. 虚拟线程在I/O阻塞时不占用OS线程,资源消耗极低
|
||||||
|
* 3. 审计事件量可能很大,虚拟线程支持高并发处理
|
||||||
|
* 4. 独立线程池避免与业务线程池竞争资源
|
||||||
|
*
|
||||||
|
* 💡 场景:
|
||||||
|
* - 异步记录用户操作审计日志
|
||||||
|
* - 写入审计数据库
|
||||||
|
* - 发送审计事件到消息队列
|
||||||
|
*
|
||||||
|
* 🎯 解决问题:
|
||||||
|
* - 修复 "More than one TaskExecutor bean found" 警告
|
||||||
|
* - 确保审计事件处理不受其他业务线程池影响
|
||||||
|
*/
|
||||||
|
@Bean("auditTaskExecutor")
|
||||||
|
public SimpleAsyncTaskExecutor auditTaskExecutor() {
|
||||||
|
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor("audit-virtual-");
|
||||||
|
executor.setVirtualThreads(true);
|
||||||
|
executor.setConcurrencyLimit(-1); // 无限制,支持大量并发审计事件
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 注意 ==========
|
// ========== 注意 ==========
|
||||||
// sshOutputExecutor 已迁移到 Framework 层
|
// sshOutputExecutor 已迁移到 Framework 层
|
||||||
|
|||||||
@ -42,7 +42,11 @@ public class AuditAspect {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 记录异常信息
|
// 记录异常信息
|
||||||
metadata.setDetail(metadata.getDetail() + " [Error: " + e.getMessage() + "]");
|
metadata.setDetail(metadata.getDetail() + " [Error: " + e.getMessage() + "]");
|
||||||
|
|
||||||
|
// 发布审计事件
|
||||||
eventPublisher.publishEvent(new AuditEvent(this, metadata));
|
eventPublisher.publishEvent(new AuditEvent(this, metadata));
|
||||||
|
|
||||||
|
// 重新抛出异常
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class AuditEventListener {
|
public class AuditEventListener {
|
||||||
|
|
||||||
@Async
|
@Async("auditTaskExecutor")
|
||||||
@EventListener
|
@EventListener
|
||||||
public void handleAuditEvent(AuditEvent event) {
|
public void handleAuditEvent(AuditEvent event) {
|
||||||
// 这里可以将审计信息保存到数据库或发送到日志系统
|
// 这里可以将审计信息保存到数据库或发送到日志系统
|
||||||
|
|||||||
@ -317,7 +317,7 @@ export const LogViewerWindow: React.FC<LogViewerWindowProps> = ({
|
|||||||
<SelectTrigger className="h-7 w-40 text-xs">
|
<SelectTrigger className="h-7 w-40 text-xs">
|
||||||
<SelectValue placeholder="选择Pod" />
|
<SelectValue placeholder="选择Pod" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent className="z-[9999]">
|
||||||
{podNames.map((name) => (
|
{podNames.map((name) => (
|
||||||
<SelectItem key={name} value={name}>
|
<SelectItem key={name} value={name}>
|
||||||
{name}
|
{name}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user