DubboRCP调用次数和调用时间的监控,以 Statistics 为中心,扩展接口为 MonitorFactory、Monitor、MonitorService.
MonitorService 主要提供两个接口,收集和查找监控数据.
/**
* Collect monitor data
* 1. support invocation count: count://host/interface?application=foo&method=foo&provider=10.20.153.11:20880&success=12&failure=2&elapsed=135423423
* 1.1 host,application,interface,group,version,method: record source host/application/interface/method
* 1.2 add provider address parameter if it's data sent from consumer, otherwise, add source consumer's address in parameters
* 1.3 success,failure,elapsed: record success count, failure count, and total cost for success invocations, average cost (total cost/success calls)
*
* @param statistics
*/
void collect(URL statistics);
/**
* Lookup monitor data
* 1. support lookup by day: count://host/interface?application=foo&method=foo&side=provider&view=chart&date=2012-07-03
* 1.1 host,application,interface,group,version,method: query criteria for looking up by host, application, interface, method. When one criterion is not present, it means ALL will be accepted, but 0.0.0.0 is ALL for host
* 1.2 side=consumer,provider: decide the data from which side, both provider and consumer are returned by default
* 1.3 default value is view=summary, to return the summarized data for the whole day. view=chart will return the URL address showing the whole day trend which is convenient for embedding in other web page
* 1.4 date=2012-07-03: specify the date to collect the data, today is the default value
*
* @param query
* @return statistics
*/
List<URL> lookup(URL query);
Monitor 接口继承 Node 和 MonitorService. 也就是说是以 Monitor 提供对外服务.
MonitorFactory 创建 Monitor 的工厂.
BuiltinServiceDetector 加载内置服务,例如 EchoService、GenericService、MetricsService、MonitorService
AbstractMonitorFactory 创建 Monitor 的工厂. 抽象了 createMonitor 方法.
protected abstract Monitor createMonitor(URL url);
MonitorFilter 会按照 MonitorSerivce 中方法定义的格式,将调用情况封装成 url. 它作用于服务端和客户端.
1.在 invoke 方法中 concurrent + 1
2.在 onResponse 中 concurrent - 1,上报成功
3.在 onError 中 concurrent - 1,上报失败
4.url:count://host:port/serviceName/methodName?application=xxx&interface=xxx&method=xxx&provider=xxx:yyy&failure=xxx&success=xxx&elapsed=xxx&concurrent=xxx&input=xxx&output=xxx&group=xxx&version=xxx
new URL(COUNT_PROTOCOL, NetUtils.getLocalHost(), localPort, service + PATH_SEPARATOR + method, MonitorService.APPLICATION, application, MonitorService.INTERFACE, service, MonitorService.METHOD, method, remoteKey, remoteValue, error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1", MonitorService.ELAPSED, String.valueOf(elapsed), MonitorService.CONCURRENT, String.valueOf(concurrent), INPUT_KEY, input, OUTPUT_KEY, output, GROUP_KEY, group, VERSION_KEY, version);
DubboMonitor 会将 URL 封装成 Statistics 对象.
看了上面的 url,是否可以做一些删减了?比如前面部分的 serviceName/methodName 是否必须?
Statistics(url、application、service、method、group、version、server、client) 为统计信息. 那么它专注那些信息了?
1.url
2.application
3.service
4.method
5.group
6.version
7.server
8.client
public class Statistics implements Serializable {
private static final long serialVersionUID = -6921183057683641441L;
private URL url;
private String application;
private String service;
private String method;
private String group;
private String version;
private String client;
private String server;
public Statistics(URL url) {
this.url = url;
this.application = url.getParameter(MonitorService.APPLICATION);
this.service = url.getParameter(MonitorService.INTERFACE);
this.method = url.getParameter(MonitorService.METHOD);
this.group = url.getParameter(MonitorService.GROUP);
this.version = url.getParameter(MonitorService.VERSION);
this.client = url.getParameter(MonitorService.CONSUMER, url.getAddress());
this.server = url.getParameter(MonitorService.PROVIDER, url.getAddress());
}
}
DubboMonitor 实现 Monitor 接口,每隔 60s 上报一次. 主要是收集和查找监控数据.
update[0] :调用成功的次数
update[1] :调用失败的次数
update[2] :总调用流量(请求包的总大小)。
update[3] :总响应流量(响应包的总大小)。
update[4] :总响应时长(总服务调用开销)。
update[5] :一次收集周期的平均TPS。
update[6] :最大请求包大小。
update[7] :最大响应包大小。
update[8] :最大响应时间。
update[9] :最大TPS。
DubboMonitorFactory(protocol、proxyFactory) 继承 AbstractMonitorFactory 接口,创建 DubboMonitor 的工厂.
private Protocol protocol;
private ProxyFactory proxyFactory;
MetricsFilter 实现 Filter 接口,待定。
Dubbo monitor 监控信息上报到那了?
流程是咋样的?
从网上 copy 了下:
dubbo-monitor-simple
基本用法
-
启动com.alibaba.dubbo.monitor.simple.MonitorStarter#main
-
需要进行监控的服务,在xml中配置<dubbo:monitor protocol="registry"/>
-
打开监控页面http://localhost:8080可以看到服务调用相关的统计
实现原理
dubbo-monitor-simple
-
dubbo-monitor-simple启动的时候,发布服务:com.alibaba.dubbo.monitor.MonitorService(实现类:com.alibaba.dubbo.monitor.simple.SimpleMonitorService),只实现了collect方法,将RPC调用过来的URL存到queue里面
-
com.alibaba.dubbo.monitor.simple.SimpleMonitorService启动了两个线程,分别执行write和draw方法,write从queue里面取出URL进行统计分析,结果写文件,draw方法把这些结果画成折线图,存本地图片文件
-
com.alibaba.dubbo.monitor.simple.pages.ChartsPageHandler和com.alibaba.dubbo.monitor.simple.pages.StatisticsPageHandler负责在页面上渲染展示这些数据
Dubbo应用
-
Dubbo服务在配置了<dubbo:monitor protocol="registry"/>标签后,调用经过com.alibaba.dubbo.monitor.support.MonitorFilter时,会进行结果收集操作。
-
最终在调用到com.alibaba.dubbo.monitor.dubbo.DubboMonitor#collect,该方法将调用过程中的统计信息存放在statisticsMap中。并且,有另一个线程定期(默认为60秒)调用dubbo-monitor-simple暴露的com.alibaba.dubbo.monitor.MonitorService服务,将这些信息发送给monitor。
Dubbo-montitor-simple实现的过程借助了dubbo服务调用:Monitor端暴露服务,Dubbo应用通过配置去消费这些服务,消费的过程就是自身服务数据上报的过程。
Dubbo-monitor-simple的代码在本项目的master分支
通过摘抄自 wiki 的描述,我们能很清晰看到 dubbo 的服务监控是如何做的.
1.服务在被调用之前,进过 MonitorFilter,在 MonitorFilter 中获取 DubboMonitor 完成监控数据的收集.
2.在 DubboMonitorFactory 中完成 MonitorService 服务的引用. Protocol 得到 Invoker,proxyFactory 完成透明化调用.
Invoker<MonitorService> monitorInvoker = protocol.refer(MonitorService.class, urlBuilder.build());
MonitorService monitorService = proxyFactory.getProxy(monitorInvoker);
3.在 DubboMonitor 中的 send 方法中,完成每个 60s 上报一次监控数据.
4.也就是说 dubbo 的服务监控,也是通过 dubbo 服务,将服务端和消费端的调用数据自动上报到 dubbo-monitor-simple 应用服务.
dubbo 接入 trace 原理:https://segmentfault.com/a/1190000018515411
参考:
① https://blog.youkuaiyun.com/prestigeding/article/details/82254649
② https://blog.youkuaiyun.com/weixin_38308374/article/details/106157243
http://dubbo.apache.org/zh/docs/v2.7/user/simple-monitor/
https://github.com/apache/dubbo-admin/wiki/dubbo-monitor-simple