美文网首页
dubbo线程池监控

dubbo线程池监控

作者: GoddyWu | 来源:发表于2023-09-12 20:33 被阅读0次

之前有遇到dubbo线程池枯竭的问题,但作为服务端不太好监控到自己的线程池已满。基于之前已经打通micrometer+prometheus+grafana来做java服务的实时监控,直接使用metrics实时上报到prometheus,贼方便

1. 获取到dubbo的线程池

因为dubbo线程数是一个波动的值,所以采用仪表盘(gauge)来存储数据

dubbo 2.6.8

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.store.DataStore;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
public class DubboThreadPoolUtil {

    private static final String DEFAULT_PORT = "20880";

    /**
     * 获取dubbo的线程池
     */
    public static Optional<ThreadPoolExecutor> getThreadPool() {
        return getThreadPool(DEFAULT_PORT);
    }

    public static Optional<ThreadPoolExecutor> getThreadPool(String port) {
        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
        Map<String, Object> executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
        return Optional.ofNullable(executors.get(port)).map(executor -> {
            if (executor instanceof ThreadPoolExecutor) {
                return (ThreadPoolExecutor) executor;
            } else {
                return null;
            }
        });
    }

}

2. 搭配micrometer+prometheus使用

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.store.DataStore;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class DubboThreadPoolUtil {

    private static final String DEFAULT_PORT = "20880";

    private static ScheduledThreadPoolExecutor scheduledExecutor;
    private static ThreadPoolExecutor dubboExecutor;

    /**
     * 获取dubbo的线程池
     */
    public static Optional<ThreadPoolExecutor> getThreadPool() {
        return getThreadPool(DEFAULT_PORT);
    }

    public static Optional<ThreadPoolExecutor> getThreadPool(String port) {
        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
        Map<String, Object> executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
        return Optional.ofNullable(executors.get(port)).map(executor -> {
            if (executor instanceof ThreadPoolExecutor) {
                return (ThreadPoolExecutor) executor;
            } else {
                return null;
            }
        });
    }

    public static void addMetricsWatcher() {
        addMetricsWatcher(DEFAULT_PORT);
    }

    public static void addMetricsWatcher(String port) {
        if (scheduledExecutor == null) {
            ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("dubbo-threadPool-watcher-%d").build();
            scheduledExecutor = new ScheduledThreadPoolExecutor(1, threadFactory);
        }
        scheduledExecutor.scheduleWithFixedDelay(() -> {
            if (dubboExecutor == null) {
                Optional<ThreadPoolExecutor> threadPoolOptional = getThreadPool(port);
                if (!threadPoolOptional.isPresent()) {
                    log.info("添加dubbo线程池监控【未成功,等1s重试】");
                    return;
                }
                dubboExecutor = threadPoolOptional.get();
                log.info("添加dubbo线程池监控【完毕】");
            }

            Metrics.gauge("dubbo_threadPool", Collections.singletonList(Tag.of("indicator", "活跃线程数")), dubboExecutor, ThreadPoolExecutor::getActiveCount);
            Metrics.gauge("dubbo_threadPool", Collections.singletonList(Tag.of("indicator", "最大线程数")), dubboExecutor, ThreadPoolExecutor::getMaximumPoolSize);

        },  0,1, TimeUnit.SECONDS);
    }
}

3. 配置grafana图

max(dubbo_threadPool{indicator="活跃线程数"})

max(dubbo_threadPool{indicator="最大线程数"})

效果如下


值得注意的是,dubbo线程池默认采用的SynchronousQueue

相关文章

  • 3. Dubbo线程池模型

    dubbo有两种线程池,io线程池、业务线程池以netty作为io框架为例:boss线程池: 主要处理新的连接请求...

  • 信号量用法:锁

    用于dubbo线程池满的拒绝策略

  • dubbo线程池

    类型 dubbo的线程池类型通过SPI定义在org.apache.dubbo.common.threadpool....

  • Java线程池监控预警实现

    前言 在Java线程池的使用中,如何动态可视化监控线程池各项运行指标是一个比较重要的需求。 线程池监控必要性 如果...

  • Dubbo线程池

    Dubbo的线程模型与线程池策略 Dubbo默认的底层网络通讯使用的是Netty,服务提供方NettyServer...

  • Dubbo-线程池

    一、Dubbo中的线程池 提供了三种线程池的实现: fixed:固定大小的线程池,启动时建立,并且不会关闭,这也是...

  • 重写线程池

    什么是线程池 线程池 我们都知道 是一种池化技术,主要解决了线程创建都额外资源消耗,线程监控 等问题 当然 线程...

  • 我们自搭监控系统的grafana的视图设计

    一、监控体系 业务指标监控 应用监控(jvm、接口访问量及耗时、线程池、数据库连接池、hystrix) 中间件--...

  • [Dubbo]基础组件之ThreadPool

    介绍 ThreadPool 我们在开发过程中经常使用,java线程池的相关知识见线程池相关文章dubbo也不例外会...

  • Dubbo-Client线程池机制

    DUbbo-Client默认的线程池是CachedThreadPool 实际过程中可能会导致client线程堆积 ...

网友评论

      本文标题:dubbo线程池监控

      本文链接:https://www.haomeiwen.com/subject/zytyvdtx.html