欢迎光临
我们一直在努力

SkyWalking 源码分析 —— Collector Server Component 服务器组件

1. 引言

1.1 SkyWalking 概述

SkyWalking 是一个开源的 APM(应用性能监控)系统,专门为微服务、云原生和容器化架构设计。它提供了分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。Collector 作为 SkyWalking 的核心服务器组件,承担着数据处理、聚合和存储的重要职责。

1.2 Collector 组件的重要性

Collector 是 SkyWalking 架构中的中枢神经系统,负责接收来自各种探针(Agent)的数据,进行实时处理和分析,并将结果存储到后端存储中。其设计直接影响整个系统的性能、可靠性和扩展性。

2. Collector 整体架构设计

2.1 模块化架构

Collector 采用高度模块化的设计,每个模块都有明确的职责边界:

java

// 模块定义接口
public interface Module {
String name();
Class<? extends ModuleProvider> provider();
}

// 模块提供者接口
public interface ModuleProvider {
String name();
ModuleConfig createConfigBeanIfAbsent();
void prepare() throws ServiceNotProvidedException;
void start() throws ServiceNotProvidedException;
void notifyAfterCompleted() throws ServiceNotProvidedException;
String[] requiredModules();
}

2.2 核心模块组成

Collector 由以下几个核心模块构成:

  • Agent Receiver Module – 负责接收 Agent 上报的数据

  • Cluster Module – 提供集群管理能力

  • Storage Module – 数据存储抽象层

  • Analysis Module – 数据分析处理模块

  • Query Module – 数据查询模块

  • Configuration Module – 配置管理模块

  • 2.3 数据流架构

    Collector 的数据处理遵循清晰的流水线模式:

    text

    Agent数据 → 接收模块 → 数据解析 → 数据聚合 → 存储 → 查询服务

    3. 启动流程深度分析

    3.1 入口类分析

    Collector 的启动入口位于 ApplicationStartUp 类:

    java

    public class ApplicationStartUp {
    public static void main(String[] args) {
    // 1. 初始化配置管理器
    ConfigInitializer.initialize();

    // 2. 创建并配置模块管理器
    ModuleManager moduleManager = new ModuleManager();

    // 3. 初始化核心模块
    BootstrapFlow bootstrapFlow = new BootstrapFlow(moduleManager);
    bootstrapFlow.start();

    // 4. 启动完成后的回调
    bootstrapFlow.notifyAfterCompleted();
    }
    }

    3.2 模块初始化过程

    模块初始化采用分层启动策略:

    java

    public class BootstrapFlow {
    private void start() {
    // 第一阶段:准备阶段
    for (ModuleProvider provider : providers) {
    provider.prepare();
    }

    // 第二阶段:启动阶段
    for (ModuleProvider provider : providers) {
    provider.start();
    }

    // 第三阶段:完成阶段
    for (ModuleProvider provider : providers) {
    provider.notifyAfterCompleted();
    }
    }
    }

    3.3 依赖注入机制

    SkyWalking 使用自定义的轻量级依赖注入机制:

    java

    public class ModuleManager {
    private Map<String, ModuleProvider> loadedProviders = new HashMap<>();

    public void init(ApplicationConfiguration applicationConfiguration) {
    // 解析模块依赖关系
    List<String> startupModuleList = applicationConfiguration.moduleList();

    // 拓扑排序确保依赖顺序
    List<String> sortedModules = sortModules(startupModuleList);

    // 按顺序初始化模块
    for (String moduleName : sortedModules) {
    ModuleProvider provider = createProvider(moduleName);
    loadedProviders.put(moduleName, provider);
    provider.prepare();
    }
    }
    }

    4. 网络通信层详解

    4.1 gRPC 服务器实现

    Collector 使用 gRPC 作为主要的通信协议:

    java

    public class GRPCServer {
    private Server server;
    private final int port;

    public void start() throws IOException {
    server = ServerBuilder.forPort(port)
    .addService(new TraceSegmentService())
    .addService(new JVMMetricService())
    .addService(new ManagementService())
    .build()
    .start();

    // 注册关闭钩子
    Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
    }

    // 跟踪段服务实现
    private class TraceSegmentService extends TraceSegmentReportServiceGrpc.TraceSegmentReportServiceImplBase {
    @Override
    public void collect(UpstreamSegment request,
    StreamObserver<Commands> responseObserver) {
    // 处理跟踪数据
    segmentProcessor.process(request);
    responseObserver.onNext(Commands.newBuilder().build());
    responseObserver.onCompleted();
    }
    }
    }

    4.2 HTTP 服务器设计

    HTTP 服务器主要用于管理接口和查询接口:

    java

    public class JettyServer {
    private Server server;

    public void start() {
    server = new Server(port);

    ServletContextHandler context = new ServletContextHandler();
    context.setContextPath("/");

    // 注册 GraphQL 查询服务
    context.addServlet(new ServletHolder(new GraphQLQueryHandler()), "/graphql");

    // 注册健康检查端点
    context.addServlet(new ServletHolder(new HealthCheckHandler()), "/health");

    server.setHandler(context);
    server.start();
    }
    }

    4.3 连接管理和负载均衡

    java

    public class ConnectionManager {
    private final Map<String, List<Connection>> connections = new ConcurrentHashMap<>();

    public void register(String serviceName, Connection connection) {
    connections.computeIfAbsent(serviceName, k -> new CopyOnWriteArrayList<>())
    .add(connection);
    }

    public Connection select(String serviceName) {
    List<Connection> connList = connections.get(serviceName);
    if (connList == null || connList.isEmpty()) {
    return null;
    }
    // 使用轮询负载均衡策略
    return roundRobinSelect(connList);
    }
    }

    5. 数据处理引擎

    5.1 数据接收器(Receiver)

    Receiver 负责接收不同类型的数据:

    java

    public abstract class Receiver {
    private final DataProcessor processor;

    public void receive(RemoteData data) {
    // 数据验证
    if (!validate(data)) {
    return;
    }

    // 数据预处理
    PreprocessedData preprocessed = preprocess(data);

    // 提交到处理队列
    processor.process(preprocessed);
    }

    protected abstract boolean validate(RemoteData data);
    protected abstract PreprocessedData preprocess(RemoteData data);
    }

    5.2 数据处理器(Processor)

    Processor 实现具体的数据处理逻辑:

    java

    public class SegmentProcessor implements DataProcessor<SegmentObject> {
    private final Buffer buffer;
    private final AnalysisWorker analysisWorker;

    @Override
    public void process(SegmentObject segment) {
    // 1. 数据缓冲
    buffer.write(segment);

    // 2. 触发分析
    if (buffer.isReadyForAnalysis()) {
    analysisWorker.analyze(buffer.drain());
    }
    }
    }

    5.3 数据聚合器(Aggregator)

    Aggregator 负责数据的聚合计算:

    java

    public class MetricsAggregator {
    private final TimeWindow window;
    private final ConcurrentHashMap<MetricKey, MetricValue> metrics = new ConcurrentHashMap<>();

    public void aggregate(MetricData data) {
    MetricKey key = buildKey(data);
    metrics.compute(key, (k, existing) -> {
    if (existing == null) {
    return createNewValue(data);
    }
    return mergeValue(existing, data);
    });

    // 检查时间窗口
    if (window.shouldFlush()) {
    flushMetrics();
    }
    }

    private void flushMetrics() {
    Map<MetricKey, MetricValue> snapshot = new HashMap<>(metrics);
    metrics.clear();

    // 异步存储
    storageService.save(snapshot);
    }
    }

    6. 存储抽象层

    6.1 存储接口设计

    java

    public interface StorageDAO {
    // 度量数据存储
    void saveMetrics(List<Metric> metrics);

    // 跟踪数据存储
    void saveTraces(List<Trace> traces);

    // 查询接口
    List<Trace> queryTraces(TraceQuery query);
    List<Metric> queryMetrics(MetricQuery query);
    }

    6.2 Elasticsearch 实现

    java

    public class ElasticSearchDAO implements StorageDAO {
    private final RestHighLevelClient client;
    private final IndexManager indexManager;

    @Override
    public void saveMetrics(List<Metric> metrics) {
    BulkRequest bulkRequest = new BulkRequest();

    for (Metric metric : metrics) {
    IndexRequest request = new IndexRequest(indexManager.getMetricIndex(metric))
    .source(convertToMap(metric));
    bulkRequest.add(request);
    }

    // 批量写入
    client.bulk(bulkRequest, RequestOptions.DEFAULT);
    }

    @Override
    public List<Trace> queryTraces(TraceQuery query) {
    SearchRequest searchRequest = new SearchRequest(indexManager.getTraceIndex());

    // 构建查询条件
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    boolQuery.must(QueryBuilders.termQuery("serviceId", query.getServiceId()));

    if (query.getStartTime() != null && query.getEndTime() != null) {
    boolQuery.must(QueryBuilders.rangeQuery("startTime")
    .gte(query.getStartTime())
    .lte(query.getEndTime()));
    }

    searchRequest.source(new SearchSourceBuilder().query(boolQuery));

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
    return convertToTraces(response);
    }
    }

    6.3 存储优化策略

    java

    public class StorageOptimizer {
    // 批量写入优化
    public void optimizedBulkWrite(List<DataPoint> dataPoints) {
    if (dataPoints.size() < BATCH_SIZE) {
    // 等待更多数据
    buffer.addAll(dataPoints);
    return;
    }

    // 分批写入
    List<List<DataPoint>> batches = partition(dataPoints, BATCH_SIZE);
    for (List<DataPoint> batch : batches) {
    asyncWrite(batch);
    }
    }

    // 索引管理优化
    public void manageIndices() {
    // 自动创建新索引
    createNewIndexIfNeeded();

    // 清理过期索引
    deleteExpiredIndices();

    // 索引优化
    optimizeIndices();
    }
    }

    7. 集群管理机制

    7.1 集群协调器

    java

    public class ClusterCoordinator {
    private final ServiceDiscovery discovery;
    private final ServiceRegistry registry;
    private final LoadBalancer loadBalancer;

    public void init() {
    // 注册当前节点
    registry.register(buildNodeInfo());

    // 发现其他节点
    discovery.watchNodes(this::onNodesChanged);
    }

    private void onNodesChanged(List<Node> nodes) {
    // 更新负载均衡器
    loadBalancer.updateNodes(nodes);

    // 重新分配任务
    taskScheduler.redistributeTasks();
    }
    }

    7.2 分布式锁实现

    java

    public class DistributedLock {
    private final String lockKey;
    private final String lockValue;
    private final long ttl;

    public boolean tryLock() {
    // 使用 Redis 或 ZooKeeper 实现分布式锁
    return redisTemplate.opsForValue()
    .setIfAbsent(lockKey, lockValue, Duration.ofSeconds(ttl));
    }

    public void unlock() {
    // 只能解锁自己持有的锁
    if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {
    redisTemplate.delete(lockKey);
    }
    }
    }

    7.3 数据分片策略

    java

    public class ShardingStrategy {
    private final int totalShards;

    public int calculateShard(String entityId) {
    // 基于一致性哈希的分片策略
    int hashCode = Objects.hashCode(entityId);
    return Math.abs(hashCode) % totalShards;
    }

    public boolean isResponsible(String entityId) {
    int shard = calculateShard(entityId);
    return shard == currentShard;
    }
    }

    8. 配置管理系统

    8.1 配置加载机制

    java

    public class ConfigurationManager {
    private final Map<String, Object> configurations = new ConcurrentHashMap<>();

    public void loadConfigurations() {
    // 1. 加载默认配置
    loadFromClasspath("application.yml");

    // 2. 加载外部配置
    loadFromFileSystem("config/application.yml");

    // 3. 加载环境变量
    loadFromEnvironment();

    // 4. 加载运行时配置
    loadFromRuntime();
    }

    public <T> T getConfig(String key, Class<T> type) {
    Object value = configurations.get(key);
    return type.cast(value);
    }
    }

    8.2 热更新配置

    java

    public class HotUpdateConfiguration {
    private final WatchService watchService;

    public void watchConfigChanges() {
    Path configPath = Paths.get("config");
    configPath.register(watchService, ENTRY_MODIFY);

    while (true) {
    WatchKey key = watchService.take();
    for (WatchEvent<?> event : key.pollEvents()) {
    if (event.context().toString().endsWith(".yml")) {
    // 重新加载配置
    reloadConfiguration();
    // 通知配置变更
    notifyConfigurationChange();
    }
    }
    key.reset();
    }
    }
    }

    9. 监控和度量

    9.1 性能度量收集

    java

    public class PerformanceMetrics {
    private final Meter requestMeter;
    private final Timer responseTimer;
    private final Counter errorCounter;

    public void recordRequest() {
    requestMeter.mark();
    }

    public void recordResponseTime(long duration) {
    responseTimer.record(duration, TimeUnit.MILLISECONDS);
    }

    public void recordError() {
    errorCounter.increment();
    }

    public PerformanceSnapshot getSnapshot() {
    return new PerformanceSnapshot(
    requestMeter.getCount(),
    responseTimer.getMeanRate(),
    errorCounter.getCount()
    );
    }
    }

    9.2 健康检查机制

    java

    public class HealthCheckManager {
    private final List<HealthCheck> healthChecks = new CopyOnWriteArrayList<>();

    public HealthStatus checkHealth() {
    List<HealthIssue> issues = new ArrayList<>();

    for (HealthCheck check : healthChecks) {
    HealthResult result = check.check();
    if (!result.isHealthy()) {
    issues.add(result.getIssue());
    }
    }

    return new HealthStatus(issues.isEmpty(), issues);
    }

    // 存储健康检查
    public class StorageHealthCheck implements HealthCheck {
    @Override
    public HealthResult check() {
    try {
    storageDAO.healthCheck();
    return HealthResult.healthy();
    } catch (Exception e) {
    return HealthResult.unhealthy("Storage unavailable: " + e.getMessage());
    }
    }
    }
    }

    10. 容错和高可用

    10.1 故障转移机制

    java

    public class FailoverManager {
    private final List<ServiceEndpoint> endpoints;
    private int currentEndpointIndex = 0;

    public <T> T executeWithFailover(Callable<T> operation) {
    int retries = 0;
    while (retries < maxRetries) {
    try {
    ServiceEndpoint endpoint = getNextEndpoint();
    return operation.call(endpoint);
    } catch (Exception e) {
    retries++;
    markEndpointAsDown(currentEndpointIndex);
    if (retries == maxRetries) {
    throw new RuntimeException("All endpoints failed", e);
    }
    }
    }
    return null;
    }

    private synchronized ServiceEndpoint getNextEndpoint() {
    currentEndpointIndex = (currentEndpointIndex + 1) % endpoints.size();
    return endpoints.get(currentEndpointIndex);
    }
    }

    10.2 数据备份和恢复

    java

    public class DataBackupManager {
    private final StorageDAO primaryStorage;
    private final StorageDAO backupStorage;

    public void backupData(BackupData data) {
    // 异步备份到次要存储
    CompletableFuture.runAsync(() -> {
    try {
    backupStorage.save(data);
    } catch (Exception e) {
    logger.error("Backup failed", e);
    }
    });
    }

    public void restoreFromBackup() {
    // 从备份恢复数据
    List<BackupData> backupData = backupStorage.getAll();
    primaryStorage.batchSave(backupData);
    }
    }

    11. 性能优化策略

    11.1 内存管理优化

    java

    public class MemoryPool {
    private final Queue<byte[]> bufferPool = new ConcurrentLinkedQueue<>();
    private final int bufferSize;

    public byte[] borrowBuffer() {
    byte[] buffer = bufferPool.poll();
    if (buffer == null) {
    buffer = new byte[bufferSize];
    }
    return buffer;
    }

    public void returnBuffer(byte[] buffer) {
    if (buffer != null && buffer.length == bufferSize) {
    // 清空缓冲区以便重用
    Arrays.fill(buffer, (byte) 0);
    bufferPool.offer(buffer);
    }
    }
    }

    11.2 缓存策略

    java

    public class QueryCache {
    private final Cache<CacheKey, CacheValue> cache;
    private final LoadingCache<CacheKey, CacheValue> loadingCache;

    public QueryCache() {
    this.cache = Caffeine.newBuilder()
    .maximumSize(10000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build();

    this.loadingCache = Caffeine.newBuilder()
    .maximumSize(1000)
    .build(this::loadFromStorage);
    }

    public CacheValue get(CacheKey key) {
    return loadingCache.get(key);
    }
    }

    12. 扩展性设计

    12.1 插件机制

    java

    public class PluginManager {
    private final Map<String, Plugin> plugins = new ConcurrentHashMap<>();

    public void loadPlugins() {
    ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class);
    for (Plugin plugin : loader) {
    plugins.put(plugin.name(), plugin);
    plugin.initialize();
    }
    }

    public void installPlugin(Plugin plugin) {
    plugins.put(plugin.name(), plugin);
    plugin.install();
    }
    }

    12.2 自定义处理器

    java

    public class ProcessorChain {
    private final List<DataProcessor> processors = new CopyOnWriteArrayList<>();

    public void process(DataContext context) {
    for (DataProcessor processor : processors) {
    if (!processor.process(context)) {
    // 处理器返回 false 时中断链
    break;
    }
    }
    }

    public void addProcessor(DataProcessor processor) {
    processors.add(processor);
    // 按优先级排序
    processors.sort(Comparator.comparingInt(DataProcessor::getPriority));
    }
    }

    13. 测试策略

    13.1 单元测试

    java

    public class SegmentProcessorTest {
    @Test
    public void testSegmentProcessing() {
    // 给定
    SegmentProcessor processor = new SegmentProcessor();
    SegmentObject segment = createTestSegment();

    // 当
    processor.process(segment);

    // 则
    verify(storageDAO).save(any(Segment.class));
    }
    }

    13.2 集成测试

    java

    public class CollectorIntegrationTest {
    @Test
    public void testEndToEndProcessing() {
    // 启动嵌入式 Collector
    CollectorServer server = new CollectorServer();
    server.start();

    // 发送测试数据
    sendTestData();

    // 验证结果
    assertQueryResults();

    server.stop();
    }
    }

    14. 部署和运维

    14.1 容器化部署

    dockerfile

    FROM openjdk:11-jre-slim
    COPY skywalking-collector.tar.gz /app/
    WORKDIR /app
    RUN tar -xzf skywalking-collector.tar.gz
    EXPOSE 11800 12800
    CMD ["bin/collector-startup.sh"]

    14.2 配置管理

    yaml

    cluster:
    standalone:
    selector: ${SW_CLUSTER:standalone}

    storage:
    elasticsearch:
    nameSpace: ${SW_NAMESPACE:""}
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}

    receiver-sharing-server:
    default:

    receiver-trace:
    default:
    bufferPath: ${SW_RECEIVER_BUFFER_PATH:../trace-buffer/}
    bufferOffsetMaxFileSize: ${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100}

    15. 总结

    15.1 设计亮点

  • 模块化设计:高度解耦的模块架构,便于扩展和维护

  • 异步处理:基于 Disruptor 的高性能异步处理流水线

  • 存储抽象:支持多种存储后端,具有良好的扩展性

  • 集群支持:完善的集群管理和数据分片机制

  • 监控完善:内置完善的监控和度量系统

  • 15.2 性能考量

  • 内存管理:对象池化和缓冲区重用减少 GC 压力

  • 批量操作:数据批量处理和存储优化

  • 缓存策略:多级缓存提升查询性能

  • 连接复用:减少网络开销

  • 15.3 可扩展性

  • 插件架构:支持自定义插件扩展功能

  • 配置驱动:灵活的配置管理系统

  • API 设计:清晰的接口定义,便于二次开发

  • 赞(0)
    未经允许不得转载:171主机测评 » SkyWalking 源码分析 —— Collector Server Component 服务器组件
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址