zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    人工智能系统
    Maven tomcat插件配置和使用
    青春谁不糊涂3
    假设但是学习java入门,请离开SSH稍远
    Linux下top订购具体解释
    Unity3d + NGUI 多分辨率适应
    Delphi 注册文件类型 设置文件图标
    如何创建自定义的文件类型关联
    delphi 中字符串与16进制、10进制转换函数
    十六进制字符串转化成字符串输出HexToStr(Delphi版、C#版)
  • 原文地址:https://www.cnblogs.com/yissheng/p/9971224.html
Copyright © 2011-2022 走看看