黑客24小时在线接单网站

黑客在线接单,网站入侵,渗透测试,渗透网站,入侵网站

用了很多年Dubbo,连Dubbo线程池监控都不知道,觉得自己很厉害?

本文转载自微信公众号「猿天地」,作者尹吉欢。转载本文请联系猿天地公众号。

前言

micrometer 中自带了很多其他框架的指标信息,可以很方便的通过 prometheus 进行采集和监控,常用的有 JVM 的信息,Http 请求的信息,Tomcat 线程的信息等。

对于一些比较活跃的框架,有些还是不支持的,比如 Dubbo。如果想监控 Dubbo 的一些指标,比如线程池的状况,我们需要手动去扩展,输出对应的线程池指标才行。

在这种情况下,肯定是没什么思路的,因为你不知道怎么去扩展,下面给大家介绍去做一件事情之前的思考,方式 *** 很重要。

  • Dubbo 有没有现成的实现?
  • 参考 micrometer 中指标的实现,依葫芦画瓢?

Dubbo 有没有现成的实现?

完整的实现应该没有,至少我还没用过,也没有那种去搜索引擎一搜就大把结果的现状,于是我在 Dubbo 的 Github 上找到了一个相关的项目 dubbo-spring-boot-actuator。

https://github.com/apache/dubbo-spring-boot-project/tree/master/dubbo-spring-boot-actuator

dubbo-spring-boot-actuator 看名称就知道,提供了 Dubbo 相关的各种信息端点和健康检查。从这里面也许能发现点有用的代码。

果不其然,在介绍页面中看到了想要的内容,线程池的指标数据,只不过是拼接成了字符串显示而已。

  • "threadpool":{
  • "source":"management.health.dubbo.status.extras",
  • "status":{
  • "level":"OK",
  • "message":"Poolstatus:OK,max:200,core:200,largest:0,active:0,task:0,serviceport:12345",
  • "description":null
  • }
  • }
  • 然后就去翻 dubbo-spring-boot-actuator 的代码了,没找到线程池这块的代码。后面在 dubbo.jar 中找到了 ThreadPoolStatusChecker 这个类,核心逻辑在这里面。现在已经解决了之一个问题,就是获取到 Dubbo 的线程池对象。

    参考 micrometer 中指标的实现,依葫芦画瓢?

    线程池对象能拿到了,各种数据也就能获取了。接下来的问题就是如何暴露出去给 prometheus 采集。

    两种方式,一种是自定义一个新的端点暴露,一种是直接在已有的 prometheus 端点中增加指标数据的输出,也就是依葫芦画瓢。

    看源码中已经有很多 Metrics 的实现了,我们也实现一个 Dubbo 线程池的 Metrics 即可。

    上图框起来的就是一个已经存在的线程池 Metrics,可以直接复用代码。

    实现的主要逻辑就是实现一个 MeterBinder 接口,然后将你需要的指标进行输出即可。于是打算在 bindTo *** 中获取 Dubbo 的线程池对象,然后输出指标。经过测试,在 MeterBinder 实例化的时候 Dubbo 还没初始化好,拿不到线程池对象,绑定后无法成功输出指标。

    后面还是打算采用定时采样的方式来输出,自定义一个后台线程,定时去输出数据。可以用 Timer,我这图简单就直接 while 循环了。

  • /**
  • *Dubbo线程池指标
  • *
  • *@authoryinjihuan
  • */
  • @Configuration
  • publicclassDubboThreadMetrics{
  • @Autowired
  • privateMeterRegistrymeterRegistry;
  • privatefinalIterable<Tag>TAG=Collections.singletonList(Tag.of("thread.pool.name","dubboThreadPool"));
  • @PostConstruct
  • publicvoidinit(){
  • newThread(()->{
  • while(true){
  • try{
  • Thread.sleep(1000);
  • }catch(InterruptedExceptione){
  • e.printStackTrace();
  • }
  • DataStoredataStore=ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
  • Map<String,Object>executors=dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
  • for(Map.Entry<String,Object>entry:executors.entrySet()){
  • ExecutorServiceexecutor=(ExecutorService)entry.getValue();
  • if(executorinstanceofThreadPoolExecutor){
  • ThreadPoolExecutortp=(ThreadPoolExecutor)executor;
  • Gauge.builder("dubbo.thread.pool.core.size",tp,ThreadPoolExecutor::getCorePoolSize)
  • .description("核心线程数")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.largest.size",tp,ThreadPoolExecutor::getLargestPoolSize)
  • .description("历史更高线程数")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.max.size",tp,ThreadPoolExecutor::getMaximumPoolSize)
  • .description("更大线程数")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.active.size",tp,ThreadPoolExecutor::getActiveCount)
  • .description("活跃线程数")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.thread.count",tp,ThreadPoolExecutor::getPoolSize)
  • .description("当前线程数")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.queue.size",tp,e->e.getQueue().size())
  • .description("队列大小")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.taskCount",tp,ThreadPoolExecutor::getTaskCount)
  • .description("任务总量")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • Gauge.builder("dubbo.thread.pool.completedTaskCount",tp,ThreadPoolExecutor::getCompletedTaskCount)
  • .description("已完成的任务量")
  • .baseUnit("threads")
  • .register(meterRegistry);
  • }
  • }
  • }
  • }).start();
  • }
  • }
  • 指标信息:

    配置线程池图表

    创建一个新的 dashboard 配置图表,然后新建 panel 配置指标信息

    左侧配指标信息,右侧选择对应的图表格式。需要注意的是,如果有多个服务实例,Metrics 这边更好是根据服务实例来显示,需要在指标后面增加条件,如下:

  • dubbo_thread_pool_max_size_theads{application="$application",instance=~"$instance"}
  • 关于作者:尹吉欢,简单的技术爱好者,《Spring Cloud 微服务-全栈技术与案例解析》, 《Spring Cloud 微服务 入门 实战与进阶》作者, 公众号猿天地发起人。

    原文链接:http://cxytiandi.com/blog/user/1

    • 评论列表:
    •  丑味夏见
       发布于 2022-05-31 13:05:19  回复该评论
    • edTaskCount",tp,ThreadPoolExecutor::getCompletedTaskCount).description("已完成的任务量").baseUnit("threads").register(meterRegistry)
    •  世味旧竹
       发布于 2022-05-31 17:16:33  回复该评论
    • eep(1000);}catch(InterruptedExceptione){e.printStackTrace();}DataStoredataStore=ExtensionLoader.getExtensionLoader(DataStore.class).
    •  北槐僚兮
       发布于 2022-05-31 15:22:29  回复该评论
    • 入门 实战与进阶》作者, 公众号猿天地发起人。原文链接:http://cxytiandi.com/blog/user/1

    发表评论:

    Powered By

    Copyright Your WebSite.Some Rights Reserved.