【Dubbo】Monitor层实现简述

一. 概述

1. 版本:2.7.8

2. 说明

Monitor 监控层
    
    用来统计RPC 调用次数和调用耗时时间,扩展接口为MonitorFactory,对应的实现类为DubboMonitorFactroy。
    
    用户可以实现该层的MonitorFactory扩展接口,实现自定义监控统计策略。

二. MonitorFactory工厂实现

1. 结构图

在这里插入图片描述


2. MonitorFactory接口

  1. Monitor工厂接口
  2. 默认实现为DubboMonitorFactory
@SPI("dubbo")
public interface MonitorFactory {
   

    /**
     * Create monitor.
     *
     * @param url
     * @return monitor
     */
    @Adaptive("protocol")
    Monitor getMonitor(URL url);

}

3. AbstractMonitorFactory抽象类

  1. 通过加锁的方式创建监控对象(DubboMonitor)
  2. 每个URL作为一个监控单元
  3. getMonitor()方法获取Monitor对象:如存在,则直接返回
  4. getMonitor()方法获取Monitor对象:如不存在,则加锁初始化并缓存在静态变量中
public abstract class AbstractMonitorFactory implements MonitorFactory {
   

    private static final Logger logger = LoggerFactory.getLogger(AbstractMonitorFactory.class);

    /**
     * The lock for getting monitor center
     */
    private static final ReentrantLock LOCK = new ReentrantLock();

    /**
     * The monitor centers Map<RegistryAddress, Registry>
     */
    private static final Map<String, Monitor> MONITORS = new ConcurrentHashMap<>();

    private static final Map<String, CompletableFuture<Monitor>> FUTURES = new ConcurrentHashMap<>();

    /**
     * The monitor create executor
     */
    private static final ExecutorService EXECUTOR = 
    new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), 
        new NamedThreadFactory("DubboMonitorCreator", true));

    public static Collection<Monitor> getMonitors() {
   
        return Collections.unmodifiableCollection(MONITORS.values());
    }

    @Override
    public Monitor getMonitor(URL url) {
   

        url = url.setPath(MonitorService.class.getName()).addParameter(INTERFACE_KEY, MonitorService.class.getName());
        String key = url.toServiceStringWithoutResolving();
        Monitor monitor = MONITORS.get(key);
        Future<Monitor> future = FUTURES.get(key);
        if (monitor != null || future != null) {
   
            return monitor;
        }

        LOCK.lock();

        try {
   

            monitor = MONITORS.get(key);
            future = FUTURES.get(key);
            if (monitor != null || future != null) {
   
                return monitor;
            }

            final URL monitorUrl = url;
            final CompletableFuture<Monitor> completableFuture 
            = CompletableFuture.supplyAsync(
            () -> AbstractMonitorFactory.this.createMonitor(monitorUrl));
            FUTURES.put(key, completableFuture);
            completableFuture.thenRunAsync(new MonitorListener(key), EXECUTOR);

            return null;
        } finally {
   
            // unlock
            LOCK.unlock();
        }
    }

    // 抽象方法,由DubboMonitorFactory子类实现。主要是创建DubboMonitor对象
    protected abstract Monitor createMonitor(URL url);


    class MonitorListener implements Runnable {
   

        private String key;

        public MonitorListener(String key) {
   
            this.key = key;
        }

        @Override
        public void run() {
   
        
            try {
   
            
                CompletableFuture<Monitor> completableFuture = AbstractMonitorFactory.FUTURES.get(key);
                AbstractMonitorFactory.MONITORS.put(key, completableFuture.get());
                AbstractMonitorFactory.FUTURES.remove(key);
                
            } catch (InterruptedException e) {
   
            
                logger.warn("Thread was interrupted unexpectedly, monitor will never be got.");
                AbstractMonitorFactory.FUTURES.remove(key);
                
            } catch (ExecutionException e) {
   
            
                logger.warn("Create monitor failed, monitor data will not be collected until you fix this problem. ", e);
            }
        }
    }

}


4. DubboMonitorFactory实现类

  1. createMonitor方法创建DubboMonitor对象,该对象构造时创建定时器周期统计数据
public class DubboMonitorFactory extends AbstractMonitorFactory {
   

    private Protocol protocol;

    private ProxyFactory proxyFactory;

    public void setProtocol(Protocol protocol) {
   
        this.protocol = protocol;
    }

    public void setProxyFactory(ProxyFactory proxyFactory) {
   
        this.proxyFactory = proxyFactory;
    }

    @Override
    protected Monitor createMonitor(URL url) {
   

        URLBuilder urlBuilder = URLBuilder.from(url);
        urlBuilder.setProtocol(url.getParameter(PROTOCOL_KEY, DUBBO_PROTOCOL)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值