一. 概述
1. 版本:2.7.8
2. 说明
Monitor 监控层
用来统计RPC 调用次数和调用耗时时间,扩展接口为MonitorFactory,对应的实现类为DubboMonitorFactroy。
用户可以实现该层的MonitorFactory扩展接口,实现自定义监控统计策略。
二. MonitorFactory工厂实现
1. 结构图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210220165916582.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hpSmFtZXNDaGVu,size_16,color_FFFFFF,t_70)
2. MonitorFactory接口
- Monitor工厂接口
- 默认实现为DubboMonitorFactory
@SPI("dubbo")
public interface MonitorFactory {
@Adaptive("protocol")
Monitor getMonitor(URL url);
}
3. AbstractMonitorFactory抽象类
- 通过加锁的方式创建监控对象(DubboMonitor)
- 每个URL作为一个监控单元
- getMonitor()方法获取Monitor对象:如存在,则直接返回
- getMonitor()方法获取Monitor对象:如不存在,则加锁初始化并缓存在静态变量中
public abstract class AbstractMonitorFactory implements MonitorFactory {
private static final Logger logger = LoggerFactory.getLogger(AbstractMonitorFactory.class);
private static final ReentrantLock LOCK = new ReentrantLock();
private static final Map<String, Monitor> MONITORS = new ConcurrentHashMap<>();
private static final Map<String, CompletableFuture<Monitor>> FUTURES = new ConcurrentHashMap<>();
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 {
LOCK.unlock();
}
}
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实现类
- 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)