pinpoint agent线程模型

pinpoint agent线程模型

以下分析基于pinpoint1.7.1版本

pinpoint agent主要使用到的异步线程有4个

DeadlockMonitorThread : 死锁监测线程,执行一次休眠60s

public DeadlockMonitorThread(DeadlockThreadRegistry deadlockThreadRegistry, long intervalMillis) {
    this.deadlockMonitorTask = new DeadlockMonitorTask(deadlockThreadRegistry, intervalMillis);
    this.deadlockMonitorThread = new Thread(deadlockMonitorTask, "Pinpoint-deadlock-monitor");
    this.deadlockMonitorThread.setDaemon(true);
    // for preload
    deadlockMonitorTask.doTask();
}

AgentInfoSender: agent信息上报定时任务,是个timer,3秒上报一次

DefaultAgentStatMonitor: agent状态信息上报(jvm状态等),线程数为1的定时线程池(ScheduledExecutorService),延迟5秒执行,每5秒上报一次

private final ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1, new PinpointThreadFactory("Pinpoint-stat-monitor", true));

TcpDataSender: 调用链数据上报通道,单线程,数据队列(LinkedBlockingQueue)大小5120,重试队列(LinkedBlockingQueue)大小1024,底层通迅使用的Netty

以上除了数据上报较为复杂外,其它几个都是定时执行的单线程程序

调用链数据上报分为两种

  1. API、sql、String常量,这类数据上报如果失败会先放到重试队列,后续进行重试,默认重试3次
  2. 调用链详情数据上报失败不会重试

数据上报流程

  1. 数据先被添加到上报队列中,返回添加成功or失败
public boolean execute(T data) {
    if (data == null) {
        if (isWarn) {
            logger.warn("execute(). data is null");
        }
        return false;
    }
    if (!isRun.get()) {
        if (isWarn) {
            logger.warn("{} is shutdown. discard data:{}", executorName, data);
        }
        return false;
    }
    boolean offer = queue.offer(data);
    if (!offer) {
        if (isWarn) {
            logger.warn("{} Drop data. queue is full. size:{}", executorName, queue.size());
        }
    }
    return offer;
}
  1. 数据上报线程循环从队列中获取数据发送到收集器
private void doExecute() {
    drainStartEntry:
    while (isRun()) {
        try {
            Collection<T> dtoList = getDrainQueue();
            int drainSize = takeN(dtoList, this.maxDrainSize);
            if (drainSize > 0) {
                doExecute(dtoList);
                continue;
            }

            while (isRun()) {
                T dto = takeOne();
                if (dto != null) {
                    doExecute(dto);
                    continue drainStartEntry;
                }
            }
        } catch (Throwable th) {
            logger.warn("{} doExecute(). Unexpected Error. Cause:{}", executorName, th.getMessage(), th);
        }
    }
    flushQueue();
}

还有一个UDP的数据上报通道,除了底层协议不同外,其它和TCP上报一样

数据上报流程

总结

agent使用的异步线程都是单线程

数据上报都是先把数据放入队列中,立即返回,队列大小可配置,默认5120

底层数据上报通迅是基于Netty的NIO

由于调用链监控的粒度非常细,所以过多的日志打印会对应用造成影响,要避免不必要的日志,合理设置日志级别,线上使用的日志级别要配置高一些

posted @ 2018-11-16 19:53  胡大叔  阅读(1470)  评论(0编辑  收藏  举报