Merge pull request #593 from alibaba/feature_metrics

Feature metrics
This commit is contained in:
TsingLiang 2019-01-11 15:13:57 +08:00 committed by GitHub
commit 687fb500ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 836 additions and 48 deletions

View File

@ -107,5 +107,10 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -23,10 +23,12 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.filter.impl.ConfigRequest;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
import com.alibaba.nacos.client.config.impl.ClientWorker;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.alibaba.nacos.client.config.impl.ServerHttpAgent;
import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.LogUtils;
import com.alibaba.nacos.client.config.utils.ParamUtils;
@ -55,7 +57,7 @@ public class NacosConfigService implements ConfigService {
/**
* http agent
*/
private ServerHttpAgent agent;
private HttpAgent agent;
/**
* longpolling
*/
@ -79,7 +81,7 @@ public class NacosConfigService implements ConfigService {
namespace = namespaceTmp;
properties.put(PropertyKeyConst.NAMESPACE, namespace);
}
agent = new ServerHttpAgent(properties);
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start();
worker = new ClientWorker(agent, configFilterChainManager);
}
@ -131,9 +133,11 @@ public class NacosConfigService implements ConfigService {
try {
content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(content);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
return content;
} catch (NacosException ioe) {
if (NacosException.NO_RIGHT == ioe.getErrCode()) {

View File

@ -0,0 +1,98 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import java.io.IOException;
import java.util.List;
/**
* HttpAgent
*
* @author Nacos
*/
public interface HttpAgent {
/**
* start to get nacos ip list
* @return Nothing.
* @throws NacosException on get ip list error.
*/
void start() throws NacosException;
/**
* invoke http get method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* invoke http post method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* invoke http delete method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* get name
* @return String
*/
String getName();
/**
* get namespace
* @return String
*/
String getNamespace();
/**
* get tenant
* @return String
*/
String getTenant();
/**
* get encode
* @return String
*/
String getEncode();
}

View File

@ -0,0 +1,119 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* MetricsHttpAgent
*
* @author Nacos
*/
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 {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("GET", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("GET", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
return result;
}
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("POST", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("POST", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
return result;
}
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("DELETE", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
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();
}
}

View File

@ -13,17 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.impl;
package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.ServerListManager;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.client.config.utils.LogUtils;
import com.alibaba.nacos.client.identify.STSConfig;
import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.LoggerHelper;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.JSONUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
@ -39,13 +43,14 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/**
* Server Agent
*
* @author water.lyl
*/
public class ServerHttpAgent {
public class ServerHttpAgent implements HttpAgent {
final static public Logger log = LogUtils.logger(ServerHttpAgent.class);
@ -58,6 +63,7 @@ public class ServerHttpAgent {
* @return
* @throws IOException
*/
@Override
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -101,6 +107,7 @@ public class ServerHttpAgent {
throw new ConnectException("no available server");
}
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -143,6 +150,7 @@ public class ServerHttpAgent {
throw new ConnectException("no available server");
}
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -241,6 +249,7 @@ public class ServerHttpAgent {
}
}
@Override
public synchronized void start() throws NacosException {
serverListMgr.start();
}
@ -324,18 +333,22 @@ public class ServerHttpAgent {
"can not get security credentials, responseCode: " + respCode + ", response: " + response);
}
@Override
public String getName() {
return serverListMgr.getName();
}
@Override
public String getNamespace() {
return serverListMgr.getNamespace();
}
@Override
public String getTenant() {
return serverListMgr.getTenant();
}
@Override
public String getEncode() {
return encode;
}

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.common.GroupKey;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.LogUtils;
@ -27,6 +28,7 @@ import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.LoggerHelper;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -100,6 +102,8 @@ public class ClientWorker {
cacheMap.set(copy);
}
log.info(agent.getName(), "[unsubscribe] {}", groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
}
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
@ -111,6 +115,8 @@ public class ClientWorker {
cacheMap.set(copy);
}
log.info(agent.getName(), "[unsubscribe] {}", groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
}
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
@ -143,6 +149,8 @@ public class ClientWorker {
log.info(agent.getName(), "[subscribe] {}", key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
return cache;
}
@ -170,6 +178,9 @@ public class ClientWorker {
cacheMap.set(copy);
}
log.info(agent.getName(), "[subscribe] {}", key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
return cache;
}
@ -406,9 +417,10 @@ public class ClientWorker {
}
@SuppressWarnings("PMD.ThreadPoolCreationRule")
public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
this.agent = agent;
this.configFilterChainManager = configFilterChainManager;
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
@ -522,9 +534,9 @@ public class ClientWorker {
*/
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<String, CacheData>());
ServerHttpAgent agent;
HttpAgent agent;
ConfigFilterChainManager configFilterChainManager;
private boolean isHealthServer = true;
private double currentLongingTaskCount = 0;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.monitor;
import io.micrometer.core.instrument.ImmutableTag;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Metrics Monitor
*
* @author Nacos
*/
public class MetricsMonitor {
private static AtomicInteger serviceInfoMapSize = new AtomicInteger();
private static AtomicInteger dom2BeatSize = new AtomicInteger();
private static AtomicInteger listenConfigCount = new AtomicInteger();
static {
List<Tag> tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "subServiceCount"));
Metrics.gauge("nacos_monitor", tags, serviceInfoMapSize);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "pubServiceCount"));
Metrics.gauge("nacos_monitor", tags, dom2BeatSize);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "listenConfigCount"));
Metrics.gauge("nacos_monitor", tags, listenConfigCount);
}
public static AtomicInteger getServiceInfoMapSizeMonitor() {
return serviceInfoMapSize;
}
public static AtomicInteger getDom2BeatSizeMonitor() {
return dom2BeatSize;
}
public static AtomicInteger getListenConfigCountMonitor() {
return listenConfigCount;
}
public static Timer getConfigRequestMonitor(String method, String url, String code) {
return Metrics.timer("nacos_client_request",
"module", "config",
"method", method,
"url", url,
"code", code);
}
public static Timer getNamingRequestMonitor(String method, String url, String code) {
return Metrics.timer("nacos_client_request",
"module", "naming",
"method", method,
"url", url,
"code", code);
}
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.client.naming.beat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.LogUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
@ -55,11 +56,13 @@ public class BeatReactor {
public void addBeatInfo(String dom, BeatInfo beatInfo) {
LogUtils.LOG.info("BEAT", "adding service:" + dom + " to beat map.");
dom2Beat.put(buildKey(dom, beatInfo.getIp(), beatInfo.getPort()), beatInfo);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
public void removeBeatInfo(String dom, String ip, int port) {
LogUtils.LOG.info("BEAT", "removing service:" + dom + " from beat map.");
dom2Beat.remove(buildKey(dom, ip, port));
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
public String buildKey(String dom, String ip, int port) {

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.backups.FailoverReactor;
import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.net.NamingProxy;
@ -182,6 +183,8 @@ public class HostReactor {
DiskCache.write(serviceInfo, cacheDir);
}
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
LogUtils.LOG.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getName() +
" -> " + JSON.toJSONString(serviceInfo.getHosts()));

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.utils.*;
import com.alibaba.nacos.common.util.UuidUtils;
@ -289,6 +290,8 @@ public class NamingProxy {
public String callServer(String api, Map<String, String> params, String curServer, String method)
throws NacosException {
long start = System.currentTimeMillis();
long end = 0;
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch",
@ -304,6 +307,10 @@ public class NamingProxy {
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))
.record(end - start, TimeUnit.MILLISECONDS);
if (HttpURLConnection.HTTP_OK == result.code) {
return result.content;

View File

@ -126,6 +126,26 @@
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-elastic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.net.UnknownHostException;
@ -25,6 +26,7 @@ import java.net.UnknownHostException;
*
* @author Nacos
*/
@EnableScheduling
@SpringBootApplication
public class Config {

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.aspect;
import com.alibaba.nacos.config.server.service.ConfigService;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5;
@ -23,6 +24,7 @@ import com.alibaba.nacos.config.server.utils.RequestUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -33,8 +35,8 @@ import javax.servlet.http.HttpServletResponse;
* @author Nacos
*/
@Aspect
@Component
public class RequestLogAspect {
/**
* publish config
*/
@ -54,22 +56,24 @@ public class RequestLogAspect {
*/
private static final String CLIENT_INTERFACE_REMOVE_ALL_CONFIG
= "execution(* com.alibaba.nacos.config.server.controller.ConfigController.deleteConfig(..)) && args(request,"
+ "response,dataId,group,..)";
+ "response,dataId,group,tenant,..)";
/**
* publishSingle
*/
* */
@Around(CLIENT_INTERFACE_PUBLISH_SINGLE_CONFIG)
public Object interfacePublishSingle(ProceedingJoinPoint pjp, HttpServletRequest request,
HttpServletResponse response, String dataId, String group, String tenant,
String content) throws Throwable {
final String md5 = content == null ? null : MD5.getInstance().getMD5String(content);
MetricsMonitor.getPublishMonitor().incrementAndGet();
return logClientRequest("publish", pjp, request, response, dataId, group, tenant, md5);
}
/**
* removeAll
*/
* */
@Around(CLIENT_INTERFACE_REMOVE_ALL_CONFIG)
public Object interfaceRemoveAll(ProceedingJoinPoint pjp, HttpServletRequest request, HttpServletResponse response,
String dataId, String group, String tenant) throws Throwable {
@ -84,6 +88,7 @@ public class RequestLogAspect {
String dataId, String group, String tenant) throws Throwable {
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
final String md5 = ConfigService.getContentMd5(groupKey);
MetricsMonitor.getConfigMonitor().incrementAndGet();
return logClientRequest("get", pjp, request, response, dataId, group, tenant, md5);
}

View File

@ -15,6 +15,9 @@
*/
package com.alibaba.nacos.config.server.exception;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ -37,6 +40,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(IllegalArgumentException.class)
public void handleIllegalArgumentException(HttpServletResponse response, Exception ex) throws IOException {
MetricsMonitor.getIllegalArgumentException().increment();
response.setStatus(400);
if (ex.getMessage() != null) {
response.getWriter().println(ex.getMessage());
@ -52,6 +56,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(NacosException.class)
public void handleNacosException(HttpServletResponse response, NacosException ex) throws IOException {
MetricsMonitor.getNacosException().increment();
response.setStatus(ex.getErrCode());
if (ex.getErrMsg() != null) {
response.getWriter().println(ex.getErrMsg());
@ -60,4 +65,15 @@ public class GlobalExceptionHandler {
}
}
/**
* For DataAccessException
*
* @throws DataAccessException
*/
@ExceptionHandler(DataAccessException.class)
public void handleDataAccessException(HttpServletResponse response, DataAccessException ex) throws DataAccessException {
MetricsMonitor.getDbException().increment();
throw new CannotGetJdbcConnectionException(ex.getMessage());
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.manager;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.LogUtil;
import org.slf4j.Logger;
@ -51,6 +52,7 @@ public final class TaskManager implements TaskManagerMBean {
private String name;
class ProcessRunnable implements Runnable {
public void run() {
@ -140,6 +142,7 @@ public final class TaskManager implements TaskManagerMBean {
this.lock.lock();
try {
this.tasks.remove(type);
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
} finally {
this.lock.unlock();
}
@ -150,12 +153,12 @@ public final class TaskManager implements TaskManagerMBean {
*
* @param type
* @param task
* @param previousTask
*/
public void addTask(String type, AbstractTask task) {
this.lock.lock();
try {
AbstractTask oldTask = tasks.put(type, task);
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
if (null != oldTask) {
task.merge(oldTask);
}
@ -181,6 +184,7 @@ public final class TaskManager implements TaskManagerMBean {
}
// 先将任务从任务Map中删除
this.tasks.remove(entry.getKey());
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
}
} finally {
this.lock.unlock();

View File

@ -20,10 +20,12 @@ import com.alibaba.nacos.config.server.service.ConfigService;
import com.alibaba.nacos.config.server.service.TimerTaskService;
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
@ -34,6 +36,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
*/
@Service
public class MemoryMonitor {
@Autowired
public MemoryMonitor(AsyncNotifyService notifySingleService) {
@ -45,9 +48,16 @@ public class MemoryMonitor {
TimerTaskService.scheduleWithFixedDelay(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS,
DELAY_SECONDS, TimeUnit.SECONDS);
}
static final long DELAY_SECONDS = 10;
@Scheduled(cron = "0 0 0 * * ?")
public void clear() {
MetricsMonitor.getConfigMonitor().set(0);
MetricsMonitor.getPublishMonitor().set(0);
}
}
class PrintGetConfigResponeTask implements Runnable {
@ -58,6 +68,7 @@ class PrintGetConfigResponeTask implements Runnable {
}
class PrintMemoryTask implements Runnable {
@Override
public void run() {
int groupCount = ConfigService.groupCount();
@ -65,11 +76,14 @@ class PrintMemoryTask implements Runnable {
long subCount = ClientTrackService.subscriberCount();
memoryLog.info("groupCount={}, subscriberClientCount={}, subscriberCount={}", groupCount, subClientCount,
subCount);
MetricsMonitor.getConfigCountMonitor().set(groupCount);
}
}
class NotifyTaskQueueMonitorTask implements Runnable {
final private AsyncNotifyService notifySingleService;
private AtomicInteger notifyTask = new AtomicInteger();
NotifyTaskQueueMonitorTask(AsyncNotifyService notifySingleService) {
this.notifySingleService = notifySingleService;
@ -77,16 +91,10 @@ class NotifyTaskQueueMonitorTask implements Runnable {
@Override
public void run() {
int size = ((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getQueue().size();
memoryLog.info("notifySingleServiceThreadPool-{}, toNotifyTaskSize={}",
new Object[] {((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getClass().getName(),
((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getQueue().size()});
// for(Map.Entry<String, Executor> entry: notifySingleService.getExecutors().entrySet()) {
// ThreadPoolExecutor pool = (ThreadPoolExecutor) entry.getValue();
// String target = entry.getKey();
// memoryLog.info("notifySingleServiceThreadPool-{}, toNotifyTaskSize={}",
// new Object[] { target, pool.getQueue().size() });
// }
size});
MetricsMonitor.getNotifyTaskMonitor().set(size);
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.monitor;
import io.micrometer.core.instrument.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Metrics Monitor
*
* @author Nacos
*/
public class MetricsMonitor {
private static AtomicInteger getConfig = new AtomicInteger();
private static AtomicInteger publish = new AtomicInteger();
private static AtomicInteger longPolling = new AtomicInteger();
private static AtomicInteger configCount = new AtomicInteger();
private static AtomicInteger notifyTask = new AtomicInteger();
private static AtomicInteger dumpTask = new AtomicInteger();
static {
List<Tag> tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "getConfig"));
Metrics.gauge("nacos_monitor", tags, getConfig);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "publish"));
Metrics.gauge("nacos_monitor", tags, publish);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "longPolling"));
Metrics.gauge("nacos_monitor", tags, longPolling);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "configCount"));
Metrics.gauge("nacos_monitor", tags, configCount);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "notifyTask"));
Metrics.gauge("nacos_monitor", tags, notifyTask);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "dumpTask"));
Metrics.gauge("nacos_monitor", tags, dumpTask);
}
public static AtomicInteger getConfigMonitor() {
return getConfig;
}
public static AtomicInteger getPublishMonitor() {
return publish;
}
public static AtomicInteger getLongPollingMonitor() {
return longPolling;
}
public static AtomicInteger getConfigCountMonitor() {
return configCount;
}
public static AtomicInteger getNotifyTaskMonitor() {
return notifyTask;
}
public static AtomicInteger getDumpTaskMonitor() {
return dumpTask;
}
public static Timer getNotifyRtTimer() {
return Metrics.timer("nacos_timer",
"module", "config", "name", "notifyRt");
}
public static Counter getIllegalArgumentException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "illegalArgument");
}
public static Counter getNacosException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "nacos");
}
public static Counter getDbException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "db");
}
public static Counter getConfigNotifyException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "configNotify");
}
public static Counter getUnhealthException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "unhealth");
}
}

View File

@ -15,6 +15,7 @@
*/
package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -309,6 +310,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
if (!isFound) {
fatalLog.error("[master-db] master db not found.");
MetricsMonitor.getDbException().increment();
}
}
}
@ -332,6 +334,8 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
fatalLog.error("[db-error] slave db {} down.", getIpFromUrl(dataSourceList.get(i).getUrl()));
}
isHealthList.set(i, Boolean.FALSE);
MetricsMonitor.getDbException().increment();
}
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.model.SampleResult;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.GroupKey;
import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5Util;
@ -358,7 +359,8 @@ public class LongPollingService extends AbstractEventListener {
class StatTask implements Runnable {
@Override
public void run() {
memoryLog.info("[long-polling] client count " + allSubs.size());
memoryLog.info("[long-pulling] client count " + allSubs.size());
MetricsMonitor.getLongPollingMonitor().set(allSubs.size());
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.notify.NotifyService;
import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult;
import com.alibaba.nacos.config.server.utils.LogUtil;
@ -377,6 +378,7 @@ public class ServerListService implements ApplicationListener<WebServerInitializ
serverListUnhealth.add(serverIp);
}
defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount);
MetricsMonitor.getUnhealthException().increment();
}
}
@ -391,6 +393,7 @@ public class ServerListService implements ApplicationListener<WebServerInitializ
serverListUnhealth.add(serverIp);
}
defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount);
MetricsMonitor.getUnhealthException().increment();
}
}
}

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.service.notify;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.service.ConfigDataChangeEvent;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.ServerListService;
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
import com.alibaba.nacos.config.server.utils.*;
@ -192,6 +193,7 @@ public class AsyncNotifyService extends AbstractEventListener {
ConfigTraceService.NOTIFY_EVENT_ERROR, delayed,
task.target);
//get delay time and set fail count to the task
int delay = getDelayTime(task);
@ -207,6 +209,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
}
HttpClientUtils.closeQuietly(response);
}
@ -238,6 +241,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
}
@Override
@ -262,6 +266,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
}
private NotifySingleTask task;

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.notify;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.manager.AbstractTask;
import com.alibaba.nacos.config.server.manager.TaskProcessor;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.ServerListService;
import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult;
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
@ -29,6 +30,7 @@ import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP;
@ -76,8 +78,12 @@ public class NotifyTaskProcessor implements TaskProcessor {
if (result.code == HttpStatus.SC_OK) {
ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP,
ConfigTraceService.NOTIFY_EVENT_OK, delayed, serverIp);
MetricsMonitor.getNotifyRtTimer().record(delayed, TimeUnit.MILLISECONDS);
return true;
} else {
MetricsMonitor.getConfigNotifyException().increment();
log.error("[notify-error] {}, {}, to {}, result {}", new Object[] {dataId, group,
serverIp, result.code});
ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP,
@ -85,6 +91,7 @@ public class NotifyTaskProcessor implements TaskProcessor {
return false;
}
} catch (Exception e) {
MetricsMonitor.getConfigNotifyException().increment();
log.error(
"[notify-exception] " + dataId + ", " + group + ", to " + serverIp + ", "
+ e.toString());

View File

@ -15,11 +15,14 @@
*/
package com.alibaba.nacos.config.server.service.trace;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP;
/**
@ -68,6 +71,7 @@ public class ConfigTraceService {
if (!LogUtil.traceLog.isInfoEnabled()) {
return;
}
MetricsMonitor.getNotifyRtTimer().record(delayed, TimeUnit.MILLISECONDS);
// 方便tlog切分
if (StringUtils.isBlank(tenant)) {
tenant = null;

View File

@ -19,15 +19,17 @@ package com.alibaba.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author nacos
*/
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@ServletComponentScan
@EnableScheduling
public class Nacos {
public static void main(String[] args) {
SpringApplication.run(Nacos.class, args);
}
}
}

View File

@ -9,6 +9,30 @@ nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
# metrics for prometheus
#management.endpoints.web.exposure.include=*
# metrics for elastic search
management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200
# metrics for influx
management.metrics.export.influx.enabled=false
#management.metrics.export.influx.db=springboot
#management.metrics.export.influx.uri=http://localhost:8086
#management.metrics.export.influx.auto-create-db=true
#management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true
# spring.datasource.platform=mysql
#db.num=2
#db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
#db.url.1=jdbc:mysql://11.163.152.9:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
#db.user=nacos_devtest
#db.password=youdontknow
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
server.tomcat.basedir=/home/admin/nacos
# default current work dir
server.tomcat.basedir=

View File

@ -158,7 +158,22 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-cmdb</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-elastic</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -17,12 +17,14 @@ package com.alibaba.nacos.naming;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* Hello world!
*
* @author xxc
*/
@EnableScheduling
@SpringBootApplication
public class NamingApp {

View File

@ -20,7 +20,6 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.naming.misc.*;
import com.alibaba.nacos.naming.monitor.PerformanceLoggerThread;
import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.raft.Datum;
import com.alibaba.nacos.naming.raft.RaftCore;
@ -555,9 +554,6 @@ public class DomainsManager {
}
}
PerformanceLoggerThread performanceLoggerThread = new PerformanceLoggerThread();
performanceLoggerThread.init(this);
UtilsAndCommons.DOMAIN_SYNCHRONIZATION_EXECUTOR.schedule(new DomainReporter(), 60000, TimeUnit.MILLISECONDS);
UtilsAndCommons.DOMAIN_UPDATE_EXECUTOR.submit(new UpdatedDomainProcessor());

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.naming.core.Cluster;
import com.alibaba.nacos.naming.core.IpAddress;
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
import com.alibaba.nacos.naming.misc.Switch;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClientConfig;
@ -45,9 +46,6 @@ import static com.alibaba.nacos.naming.misc.Loggers.SRV_LOG;
public class HttpHealthCheckProcessor extends AbstractHealthCheckProcessor {
private static AsyncHttpClient asyncHttpClient;
public HttpHealthCheckProcessor() {
}
static {
try {
AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
@ -63,6 +61,7 @@ public class HttpHealthCheckProcessor extends AbstractHealthCheckProcessor {
builder.setMaxRequestRetry(0);
builder.setUserAgent("VIPServer");
asyncHttpClient = new AsyncHttpClient(builder.build());
} catch (Throwable e) {
SRV_LOG.error("VIPSRV-HEALTH-CHECK", "Error while constructing HTTP asynchronous client, " + e.toString(), e);
}
@ -126,6 +125,7 @@ public class HttpHealthCheckProcessor extends AbstractHealthCheckProcessor {
}
builder.execute(new HttpHealthCheckCallback(ip, task));
MetricsMonitor.getHttpHealthCheckMonitor().incrementAndGet();
} catch (Throwable e) {
ip.setCheckRT(Switch.getHttpHealthParams().getMax());
checkFail(ip, task, "http:error:" + e.getMessage());

View File

@ -21,6 +21,7 @@ import com.alibaba.nacos.naming.core.IpAddress;
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.Switch;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import io.netty.channel.ConnectTimeoutException;
import org.apache.commons.collections.CollectionUtils;
@ -111,6 +112,7 @@ public class MysqlHealthCheckProcessor extends AbstractHealthCheckProcessor {
}
EXECUTOR.execute(new MysqlCheckTask(ip, task));
MetricsMonitor.getMysqlHealthCheckMonitor().incrementAndGet();
} catch (Exception e) {
ip.setCheckRT(Switch.getMysqlHealthParams().getMax());
checkFail(ip, task, "mysql:error:" + e.getMessage());

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.naming.core.IpAddress;
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.Switch;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import org.apache.commons.collections.CollectionUtils;
import java.net.ConnectException;
@ -39,7 +40,6 @@ import static com.alibaba.nacos.naming.misc.Loggers.SRV_LOG;
* @author nacos
*/
public class TcpSuperSenseProcessor extends AbstractHealthCheckProcessor implements Runnable {
private Map<String, BeatKey> keyMap = new ConcurrentHashMap<>();
private BlockingQueue<Beat> taskQueue = new LinkedBlockingQueue<Beat>();
@ -127,6 +127,7 @@ public class TcpSuperSenseProcessor extends AbstractHealthCheckProcessor impleme
Beat beat = new Beat(ip, task);
taskQueue.add(beat);
MetricsMonitor.getTcpHealthCheckMonitor().incrementAndGet();
}
// selector.wakeup();

View File

@ -0,0 +1,146 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.naming.monitor;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.ImmutableTag;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Metrics Monitor
*
* @author Nacos
*/
public class MetricsMonitor {
private static AtomicInteger mysqlHealthCheck = new AtomicInteger();
private static AtomicInteger httpHealthCheck = new AtomicInteger();
private static AtomicInteger tcpHealthCheck = new AtomicInteger();
private static AtomicInteger domCount = new AtomicInteger();
private static AtomicInteger ipCount = new AtomicInteger();
private static AtomicLong maxPushCost = new AtomicLong();
private static AtomicLong avgPushCost = new AtomicLong();
private static AtomicLong leaderStatus = new AtomicLong();
private static AtomicInteger totalPush = new AtomicInteger();
private static AtomicInteger failedPush = new AtomicInteger();
static {
List<Tag> tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "mysqlhealthCheck"));
Metrics.gauge("nacos_monitor", tags, mysqlHealthCheck);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "httpHealthCheck"));
Metrics.gauge("nacos_monitor", tags, httpHealthCheck);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "tcpHealthCheck"));
Metrics.gauge("nacos_monitor", tags, tcpHealthCheck);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "domCount"));
Metrics.gauge("nacos_monitor", tags, domCount);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "ipCount"));
Metrics.gauge("nacos_monitor", tags, ipCount);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "maxPushCost"));
Metrics.gauge("nacos_monitor", tags, maxPushCost);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "avgPushCost"));
Metrics.gauge("nacos_monitor", tags, avgPushCost);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "leaderStatus"));
Metrics.gauge("nacos_monitor", tags, leaderStatus);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "totalPush"));
Metrics.gauge("nacos_monitor", tags, totalPush);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "failedPush"));
Metrics.gauge("nacos_monitor", tags, failedPush);
}
public static AtomicInteger getMysqlHealthCheckMonitor() {
return mysqlHealthCheck;
}
public static AtomicInteger getHttpHealthCheckMonitor() {
return httpHealthCheck;
}
public static AtomicInteger getTcpHealthCheckMonitor() {
return tcpHealthCheck;
}
public static AtomicInteger getDomCountMonitor() {
return domCount;
}
public static AtomicInteger getIpCountMonitor() {
return ipCount;
}
public static AtomicLong getMaxPushCostMonitor() {
return maxPushCost;
}
public static AtomicLong getAvgPushCostMonitor() {
return avgPushCost;
}
public static AtomicLong getLeaderStatusMonitor() {
return leaderStatus;
}
public static AtomicInteger getTotalPushMonitor() {
return totalPush;
}
public static AtomicInteger getFailedPushMonitor() {
return failedPush;
}
public static Counter getDiskException() {
return Metrics.counter("nacos_exception",
"module", "naming", "name", "disk");
}
public static Counter getLeaderSendBeatFailedException() {
return Metrics.counter("nacos_exception",
"module", "naming", "name", "leaderSendBeatFailed");
}
}

View File

@ -19,8 +19,12 @@ import com.alibaba.nacos.naming.core.DomainsManager;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.Switch;
import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.raft.RaftCore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
@ -28,9 +32,12 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.naming.raft.RaftPeer.State.FOLLOWER;
/**
* @author nacos
*/
@Component
public class PerformanceLoggerThread {
@Autowired
@ -46,11 +53,11 @@ public class PerformanceLoggerThread {
}
});
private static final long PERIOD = 1 * 60 * 60;
private static final long PERIOD = 5 * 60;
private static final long HEALTH_CHECK_PERIOD = 5 * 60;
public void init(DomainsManager domainsManager) {
this.domainsManager = domainsManager;
@PostConstruct
public void init() {
start();
}
@ -78,6 +85,15 @@ public class PerformanceLoggerThread {
}
@Scheduled(cron = "0 0 0 * * ?")
public void refresh() {
PushService.setFailedPush(0);
PushService.setTotalPush(0);
MetricsMonitor.getHttpHealthCheckMonitor().set(0);
MetricsMonitor.getMysqlHealthCheckMonitor().set(0);
MetricsMonitor.getTcpHealthCheckMonitor().set(0);
}
class AllDomNamesTask implements Runnable {
@Override
@ -97,10 +113,29 @@ public class PerformanceLoggerThread {
public void run() {
try {
int domCount = domainsManager.getDomCount();
MetricsMonitor.getDomCountMonitor().set(domCount);
int ipCount = domainsManager.getIPCount();
long maxPushMaxCost = getMaxPushCost();
MetricsMonitor.getIpCountMonitor().set(ipCount);
long maxPushCost = getMaxPushCost();
MetricsMonitor.getMaxPushCostMonitor().set(maxPushCost);
long avgPushCost = getAvgPushCost();
Loggers.PERFORMANCE_LOG.info("PERFORMANCE:" + "|" + domCount + "|" + ipCount + "|" + maxPushMaxCost + "|" + avgPushCost);
MetricsMonitor.getAvgPushCostMonitor().set(avgPushCost);
MetricsMonitor.getTotalPushMonitor().set(PushService.getTotalPush());
MetricsMonitor.getFailedPushMonitor().set(PushService.getFailedPushCount());
if (RaftCore.isLeader()) {
MetricsMonitor.getLeaderStatusMonitor().set(1);
} else if (RaftCore.getPeerSet().local().state == FOLLOWER) {
MetricsMonitor.getLeaderStatusMonitor().set(0);
} else {
MetricsMonitor.getLeaderStatusMonitor().set(2);
}
Loggers.PERFORMANCE_LOG.info("PERFORMANCE:" + "|" + domCount + "|" + ipCount + "|" + maxPushCost + "|" + avgPushCost);
} catch (Exception e) {
Loggers.SRV_LOG.warn("PERFORMANCE", "Exception while print performance log.", e);
}

View File

@ -128,6 +128,10 @@ public class PushService {
return totalPush;
}
public static void setTotalPush(int totalPush) {
PushService.totalPush = totalPush;
}
public static void addClient(String dom,
String clusters,
String agent,
@ -308,6 +312,11 @@ public class PushService {
return ackMap.size() + failedPush;
}
public static void setFailedPush(int failedPush) {
PushService.failedPush = failedPush;
}
public static void resetPushState() {
ackMap.clear();
}

View File

@ -22,6 +22,7 @@ import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.naming.boot.RunningConfig;
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
import com.alibaba.nacos.naming.misc.*;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.Response;
import org.apache.commons.collections.CollectionUtils;
@ -618,6 +619,7 @@ public class RaftCore {
public Integer onCompleted(Response response) throws Exception {
if (response.getStatusCode() != HttpURLConnection.HTTP_OK) {
Loggers.RAFT.error("VIPSRV-RAFT", "beat failed: " + response.getResponseBody() + ", peer: " + server);
MetricsMonitor.getLeaderSendBeatFailedException().increment();
return 1;
}
@ -629,10 +631,12 @@ public class RaftCore {
@Override
public void onThrowable(Throwable t) {
Loggers.RAFT.error("VIPSRV-RAFT", "error while sending heart-beat to peer: " + server, t);
MetricsMonitor.getLeaderSendBeatFailedException().increment();
}
});
} catch (Exception e) {
Loggers.RAFT.error("VIPSRV-RAFT", "error while sending heart-beat to peer: " + server, e);
MetricsMonitor.getLeaderSendBeatFailedException().increment();
}
}

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.naming.raft;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -141,6 +142,8 @@ public class RaftStore {
public synchronized static void write(final Datum datum) throws Exception {
File cacheFile = new File(CACHE_DIR + File.separator + encodeFileName(datum.key));
if (!cacheFile.exists() && !cacheFile.getParentFile().mkdirs() && !cacheFile.createNewFile()) {
MetricsMonitor.getDiskException().increment();
throw new IllegalStateException("can not make cache file: " + cacheFile.getName());
}
@ -151,6 +154,9 @@ public class RaftStore {
fc = new FileOutputStream(cacheFile, false).getChannel();
fc.write(data, data.position());
fc.force(true);
} catch (Exception e) {
MetricsMonitor.getDiskException().increment();
throw e;
} finally {
if (fc != null) {
fc.close();

View File

@ -481,7 +481,7 @@
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.5.RELEASE</version>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>

View File

@ -18,16 +18,14 @@ package com.alibaba.nacos.test.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.alibaba.nacos.client.config.impl.ServerHttpAgent;
import com.alibaba.nacos.client.logger.json.JSONObject;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.config.server.Config;
import org.junit.After;
import org.junit.Assert;
@ -40,7 +38,6 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.List;
@ -57,7 +54,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ConfigAPI_ITCase {
public static final long TIME_OUT = 2000;
public ConfigService iconfig = null;
ServerHttpAgent agent = null;
HttpAgent agent = null;
static final String CONFIG_CONTROLLER_PATH = "/v1/cs/configs";
String SPECIAL_CHARACTERS = "!@#$%^&*()_+-=_|/'?.";
@ -76,7 +73,7 @@ public class ConfigAPI_ITCase {
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1"+":"+port);
iconfig = NacosFactory.createConfigService(properties);
agent = new ServerHttpAgent(properties);
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start();
}