序
本文主要研究一下nacos client的MetricsMonitor
MetricsMonitor
nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/monitor/MetricsMonitor.java
public class MetricsMonitor {
private static Gauge nacosMonitor = Gauge.build()
.name("nacos_monitor").labelNames("module", "name")
.help("nacos_monitor").register();
private static Histogram nacosClientRequestHistogram = Histogram.build().labelNames("module", "method", "url", "code")
.name("nacos_client_request").help("nacos_client_request")
.register();
public static Gauge.Child getServiceInfoMapSizeMonitor() {
return nacosMonitor.labels("naming", "serviceInfoMapSize");
}
public static Gauge.Child getDom2BeatSizeMonitor() {
return nacosMonitor.labels("naming", "dom2BeatSize");
}
public static Gauge.Child getListenConfigCountMonitor() {
return nacosMonitor.labels("naming", "listenConfigCount");
}
public static Histogram.Timer getConfigRequestMonitor(String method, String url, String code) {
return nacosClientRequestHistogram.labels("config", method, url, code).startTimer();
}
public static Histogram.Child getNamingRequestMonitor(String method, String url, String code) {
return nacosClientRequestHistogram.labels("naming", method, url, code);
}
}
- MetricsMonitor内置了nacosMonitor、nacosClientRequestHistogram;并提供了getServiceInfoMapSizeMonitor、getDom2BeatSizeMonitor、getListenConfigCountMonitor、getConfigRequestMonitor、getNamingRequestMonitor静态方法
MetricsHttpAgent
nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java
public class MetricsHttpAgent implements HttpAgent {
private HttpAgent httpAgent;
public MetricsHttpAgent(HttpAgent httpAgent) {
this.httpAgent = httpAgent;
}
@Override
public void start() throws NacosException {
httpAgent.start();
}
@Override
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
HttpResult result = null;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
throw e;
} finally {
timer.observeDuration();
timer.close();
}
return result;
}
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA");
HttpResult result = null;
try {
result = httpAgent.httpPost(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
throw e;
} finally {
timer.observeDuration();
timer.close();
}
return result;
}
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA");
HttpResult result = null;
try {
result = httpAgent.httpDelete(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
throw e;
} finally {
timer.observeDuration();
timer.close();
}
return result;
}
@Override
public String getName() {
return httpAgent.getName();
}
@Override
public String getNamespace() {
return httpAgent.getNamespace();
}
@Override
public String getTenant() {
return httpAgent.getTenant();
}
@Override
public String getEncode() {
return httpAgent.getEncode();
}
}
- MetricsHttpAgent代理了httpAgent,它在httpGet、httpPost、httpDelete方法执行前后通过MetricsMonitor.getConfigRequestMonitor获取Histogram.Timer,记录了响应耗时
NamingProxy
nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java
public class NamingProxy {
private static final int DEFAULT_SERVER_PORT = 8848;
private int serverPort = DEFAULT_SERVER_PORT;
private String namespaceId;
private String endpoint;
private String nacosDomain;
private List<String> serverList;
private List<String> serversFromEndpoint = new ArrayList<String>();
private long lastSrvRefTime = 0L;
private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);
private Properties properties;
public NamingProxy(String namespaceId, String endpoint, String serverList) {
this.namespaceId = namespaceId;
this.endpoint = endpoint;
if (StringUtils.isNotEmpty(serverList)) {
this.serverList = Arrays.asList(serverList.split(","));
if (this.serverList.size() == 1) {
this.nacosDomain = serverList;
}
}
initRefreshSrvIfNeed();
}
//......
public String callServer(String api, Map<String, String> params, String curServer, String method)
throws NacosException {
long start = System.currentTimeMillis();
long end = 0;
checkSignature(params);
List<String> headers = builderHeaders();
String url;
if (curServer.startsWith(UtilAndComs.HTTPS) || curServer.startsWith(UtilAndComs.HTTP)) {
url = curServer + api;
} else {
if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) {
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort;
}
url = HttpClient.getPrefix() + curServer + api;
}
HttpClient.HttpResult result = HttpClient.request(url, headers, params, UtilAndComs.ENCODING, method);
end = System.currentTimeMillis();
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(result.code))
.observe(end - start);
if (HttpURLConnection.HTTP_OK == result.code) {
return result.content;
}
if (HttpURLConnection.HTTP_NOT_MODIFIED == result.code) {
return StringUtils.EMPTY;
}
throw new NacosException(NacosException.SERVER_ERROR, "failed to req API:"
+ curServer + api + ". code:"
+ result.code + " msg: " + result.content);
}
//......
}
- NamingProxy的callServer方法会在执行完http请求之后通过MetricsMonitor.getNamingRequestMonitor来记录请求耗时
小结
MetricsMonitor内置了nacosMonitor、nacosClientRequestHistogram;并提供了getServiceInfoMapSizeMonitor、getDom2BeatSizeMonitor、getListenConfigCountMonitor、getConfigRequestMonitor、getNamingRequestMonitor静态方法