You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 边车模式Sidecar Pattern实现
* 为应用提供额外的辅助功能,如日志、监控、安全等
*/
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Sidecar {
private final String name; // 边车名称
private final String appId; // 关联的应用ID
private final ExecutorService executor; // 执行线程池
private final List<SidecarFeature> features; // 边车功能列表
private volatile boolean running; // 运行状态
private final AtomicInteger requestCount = new AtomicInteger(0); // 请求计数
private final AtomicInteger errorCount = new AtomicInteger(0); // 错误计数
// 边车功能接口
public interface SidecarFeature {
String getName();
void start();
void stop();
void handleRequest(RequestContext context);
}
// 请求上下文
public static class RequestContext {
private final String requestId;
private final String path;
private final long startTime;
private long endTime;
private boolean success;
private String errorMessage;
public RequestContext(String requestId, String path) {
this.requestId = requestId;
this.path = path;
this.startTime = System.currentTimeMillis();
this.success = true;
}
public void complete() {
this.endTime = System.currentTimeMillis();
}
public void markError(String errorMessage) {
this.success = false;
this.errorMessage = errorMessage;
this.endTime = System.currentTimeMillis();
}
public long getDuration() {
return endTime - startTime;
}
public String getRequestId() { return requestId; }
public String getPath() { return path; }
public boolean isSuccess() { return success; }
public String getErrorMessage() { return errorMessage; }
public long getStartTime() { return startTime; }
public long getEndTime() { return endTime; }
}
// 创建边车实例
public Sidecar(String appId) {
this.name = "sidecar-" + appId;
this.appId = appId;
this.executor = Executors.newFixedThreadPool(5);
this.features = new ArrayList<>();
this.running = false;
System.out.println("边车初始化: " + name + " 关联应用: " + appId);
}
// 添加边车功能
public void addFeature(SidecarFeature feature) {
if (feature != null) {
features.add(feature);
System.out.println("添加边车功能: " + feature.getName());
// 如果边车已运行,立即启动新功能
if (running) {
feature.start();
}
}
}
// 启动边车
public synchronized void start() {
if (!running) {
running = true;
System.out.println("边车启动: " + name);
// 启动所有功能
for (SidecarFeature feature : features) {
try {
feature.start();
} catch (Exception e) {
System.err.println("启动边车功能失败: " + feature.getName() + ", 错误: " + e.getMessage());
}
}
}
}
// 停止边车
public synchronized void stop() {
if (running) {
running = false;
System.out.println("边车停止: " + name);
// 停止所有功能
for (SidecarFeature feature : features) {
try {
feature.stop();
} catch (Exception e) {
System.err.println("停止边车功能失败: " + feature.getName() + ", 错误: " + e.getMessage());
}
}
// 关闭线程池
executor.shutdown();
}
}
// 处理请求(异步)
public void handleRequestAsync(String requestId, String path) {
if (!running) {
System.err.println("边车未运行,无法处理请求: " + requestId);
return;
}
RequestContext context = new RequestContext(requestId, path);
requestCount.incrementAndGet();
executor.submit(() -> {
try {
for (SidecarFeature feature : features) {
feature.handleRequest(context);
}
} catch (Exception e) {
errorCount.incrementAndGet();
context.markError(e.getMessage());
System.err.println("处理请求出错: " + requestId + ", 错误: " + e.getMessage());
} finally {
if (context.isSuccess() && context.getEndTime() == 0) {
context.complete();
}
}
});
}
// 处理请求(同步)
public void handleRequestSync(String requestId, String path) {
if (!running) {
System.err.println("边车未运行,无法处理请求: " + requestId);
return;
}
RequestContext context = new RequestContext(requestId, path);
requestCount.incrementAndGet();
try {
for (SidecarFeature feature : features) {
feature.handleRequest(context);
}
} catch (Exception e) {
errorCount.incrementAndGet();
context.markError(e.getMessage());
System.err.println("处理请求出错: " + requestId + ", 错误: " + e.getMessage());
} finally {
if (context.isSuccess() && context.getEndTime() == 0) {
context.complete();
}
}
}
// 获取统计信息
public String getStats() {
return String.format("边车统计 - 应用: %s, 请求数: %d, 错误数: %d, 运行状态: %s",
appId, requestCount.get(), errorCount.get(), running ? "运行中" : "已停止");
}
// 获取运行状态
public boolean isRunning() {
return running;
}
// 获取边车名称
public String getName() {
return name;
}
// 内置日志功能实现
public static class LoggingFeature implements SidecarFeature {
@Override
public String getName() {
return "日志功能";}
@Override
public void start() {
System.out.println("日志功能已启动");
}
@Override
public void stop() {
System.out.println("日志功能已停止");
}
@Override
public void handleRequest(RequestContext context) {
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
String status = context.isSuccess() ? "SUCCESS" : "ERROR";
System.out.println(String.format("[%s] [%s] 请求: %s, 路径: %s, 状态: %s, 耗时: %dms",
timestamp, Thread.currentThread().getName(),
context.getRequestId(), context.getPath(), status, context.getDuration()));
}
}
// 内置监控功能实现
public static class MonitoringFeature implements SidecarFeature {
private final AtomicInteger requestCounter = new AtomicInteger(0);
@Override
public String getName() {
return "监控功能";}
@Override
public void start() {
System.out.println("监控功能已启动");
}
@Override
public void stop() {
System.out.println("监控功能已停止");
}
@Override
public void handleRequest(RequestContext context) {
int count = requestCounter.incrementAndGet();
if (count % 5 == 0) {
System.out.println("监控统计: 已处理 " + count + " 个请求");
}
}
}
}