use of com.alibaba.nacos.api.remote.request.RequestMeta in project nacos by alibaba.
the class ServerLoaderController method smartReload.
/**
* Get server state of current server.
*
* @return state json.
*/
@Secured(resource = Commons.NACOS_CORE_CONTEXT_V2 + "/loader", action = ActionTypes.WRITE)
@GetMapping("/smartReloadCluster")
public ResponseEntity<String> smartReload(HttpServletRequest request, @RequestParam(value = "loaderFactor", required = false) String loaderFactorStr, @RequestParam(value = "force", required = false) String force) {
LOGGER.info("Smart reload request receive,requestIp={}", getRemoteIp(request));
Map<String, Object> serverLoadMetrics = getServerLoadMetrics();
Object avgString = serverLoadMetrics.get("avg");
List<ServerLoaderMetrics> details = (List<ServerLoaderMetrics>) serverLoadMetrics.get("detail");
int avg = Integer.parseInt(avgString.toString());
float loaderFactor = StringUtils.isBlank(loaderFactorStr) ? RemoteUtils.LOADER_FACTOR : Float.parseFloat(loaderFactorStr);
int overLimitCount = (int) (avg * (1 + loaderFactor));
int lowLimitCount = (int) (avg * (1 - loaderFactor));
List<ServerLoaderMetrics> overLimitServer = new ArrayList<>();
List<ServerLoaderMetrics> lowLimitServer = new ArrayList<>();
for (ServerLoaderMetrics metrics : details) {
int sdkCount = Integer.parseInt(metrics.getMetric().get(SDK_CONNECTION_COUNT_METRIC));
if (sdkCount > overLimitCount) {
overLimitServer.add(metrics);
}
if (sdkCount < lowLimitCount) {
lowLimitServer.add(metrics);
}
}
// desc by sdkConCount
overLimitServer.sort((o1, o2) -> {
Integer sdkCount1 = Integer.valueOf(o1.getMetric().get(SDK_CONNECTION_COUNT_METRIC));
Integer sdkCount2 = Integer.valueOf(o2.getMetric().get(SDK_CONNECTION_COUNT_METRIC));
return sdkCount1.compareTo(sdkCount2) * -1;
});
LOGGER.info("Over load limit server list ={}", overLimitServer);
// asc by sdkConCount
lowLimitServer.sort((o1, o2) -> {
Integer sdkCount1 = Integer.valueOf(o1.getMetric().get(SDK_CONNECTION_COUNT_METRIC));
Integer sdkCount2 = Integer.valueOf(o2.getMetric().get(SDK_CONNECTION_COUNT_METRIC));
return sdkCount1.compareTo(sdkCount2);
});
LOGGER.info("Low load limit server list ={}", lowLimitServer);
AtomicBoolean result = new AtomicBoolean(true);
for (int i = 0; i < overLimitServer.size() & i < lowLimitServer.size(); i++) {
ServerReloadRequest serverLoaderInfoRequest = new ServerReloadRequest();
serverLoaderInfoRequest.setReloadCount(overLimitCount);
serverLoaderInfoRequest.setReloadServer(lowLimitServer.get(i).address);
Member member = serverMemberManager.find(overLimitServer.get(i).address);
LOGGER.info("Reload task submit ,fromServer ={},toServer={}, ", overLimitServer.get(i).address, lowLimitServer.get(i).address);
if (serverMemberManager.getSelf().equals(member)) {
try {
serverReloaderRequestHandler.handle(serverLoaderInfoRequest, new RequestMeta());
} catch (NacosException e) {
LOGGER.error("Fail to loader self server", e);
result.set(false);
}
} else {
try {
clusterRpcClientProxy.asyncRequest(member, serverLoaderInfoRequest, new RequestCallBack() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public long getTimeout() {
return 100L;
}
@Override
public void onResponse(Response response) {
if (response == null || !response.isSuccess()) {
LOGGER.error("Fail to loader member={},response={}", member.getAddress(), response);
result.set(false);
}
}
@Override
public void onException(Throwable e) {
LOGGER.error("Fail to loader member={}", member.getAddress(), e);
result.set(false);
}
});
} catch (NacosException e) {
LOGGER.error("Fail to loader member={}", member.getAddress(), e);
result.set(false);
}
}
}
return ResponseEntity.ok().body(result.get() ? SUCCESS_RESULT : FAIL_RESULT);
}
use of com.alibaba.nacos.api.remote.request.RequestMeta in project nacos by alibaba.
the class ServerLoaderController method getServerLoadMetrics.
private Map<String, Object> getServerLoadMetrics() {
List<ServerLoaderMetrics> responseList = new LinkedList<>();
// default include self.
int memberSize = serverMemberManager.allMembersWithoutSelf().size();
CountDownLatch countDownLatch = new CountDownLatch(memberSize);
for (Member member : serverMemberManager.allMembersWithoutSelf()) {
if (MemberUtil.isSupportedLongCon(member)) {
ServerLoaderInfoRequest serverLoaderInfoRequest = new ServerLoaderInfoRequest();
try {
clusterRpcClientProxy.asyncRequest(member, serverLoaderInfoRequest, new RequestCallBack() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public long getTimeout() {
return 200L;
}
@Override
public void onResponse(Response response) {
if (response instanceof ServerLoaderInfoResponse) {
ServerLoaderMetrics metrics = new ServerLoaderMetrics();
metrics.setAddress(member.getAddress());
metrics.setMetric(((ServerLoaderInfoResponse) response).getLoaderMetrics());
responseList.add(metrics);
}
countDownLatch.countDown();
}
@Override
public void onException(Throwable e) {
LOGGER.error("Get metrics fail,member={}", member.getAddress(), e);
countDownLatch.countDown();
}
});
} catch (NacosException e) {
LOGGER.error("Get metrics fail,member={}", member.getAddress(), e);
countDownLatch.countDown();
}
} else {
countDownLatch.countDown();
}
}
try {
ServerLoaderInfoResponse handle = serverLoaderInfoRequestHandler.handle(new ServerLoaderInfoRequest(), new RequestMeta());
ServerLoaderMetrics metrics = new ServerLoaderMetrics();
metrics.setAddress(serverMemberManager.getSelf().getAddress());
metrics.setMetric(handle.getLoaderMetrics());
responseList.add(metrics);
} catch (NacosException e) {
LOGGER.error("Get self metrics fail", e);
}
try {
countDownLatch.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
LOGGER.warn("Get metrics timeout,metrics info may not complete.");
}
int max = 0;
int min = -1;
int total = 0;
for (ServerLoaderMetrics serverLoaderMetrics : responseList) {
String sdkConCountStr = serverLoaderMetrics.getMetric().get("sdkConCount");
if (StringUtils.isNotBlank(sdkConCountStr)) {
int sdkConCount = Integer.parseInt(sdkConCountStr);
if (max == 0 || max < sdkConCount) {
max = sdkConCount;
}
if (min == -1 || sdkConCount < min) {
min = sdkConCount;
}
total += sdkConCount;
}
}
Map<String, Object> responseMap = new HashMap<>(9);
responseList.sort(Comparator.comparing(ServerLoaderMetrics::getAddress));
responseMap.put("detail", responseList);
responseMap.put("memberCount", serverMemberManager.allMembers().size());
responseMap.put("metricsCount", responseList.size());
responseMap.put("completed", responseList.size() == serverMemberManager.allMembers().size());
responseMap.put("max", max);
responseMap.put("min", min);
responseMap.put("avg", total / responseList.size());
responseMap.put("threshold", total / responseList.size() * 1.1);
responseMap.put("total", total);
return responseMap;
}
use of com.alibaba.nacos.api.remote.request.RequestMeta in project nacos by alibaba.
the class GrpcRequestAcceptor method request.
@Override
public void request(Payload grpcRequest, StreamObserver<Payload> responseObserver) {
traceIfNecessary(grpcRequest, true);
String type = grpcRequest.getMetadata().getType();
// server is on starting.
if (!ApplicationUtils.isStarted()) {
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.INVALID_SERVER_STATUS, "Server is starting,please try later."));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
// server check.
if (ServerCheckRequest.class.getSimpleName().equals(type)) {
Payload serverCheckResponseP = GrpcUtils.convert(new ServerCheckResponse(CONTEXT_KEY_CONN_ID.get()));
traceIfNecessary(serverCheckResponseP, false);
responseObserver.onNext(serverCheckResponseP);
responseObserver.onCompleted();
return;
}
RequestHandler requestHandler = requestHandlerRegistry.getByRequestType(type);
// no handler found.
if (requestHandler == null) {
Loggers.REMOTE_DIGEST.warn(String.format("[%s] No handler for request type : %s :", "grpc", type));
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.NO_HANDLER, "RequestHandler Not Found"));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
// check connection status.
String connectionId = CONTEXT_KEY_CONN_ID.get();
boolean requestValid = connectionManager.checkValid(connectionId);
if (!requestValid) {
Loggers.REMOTE_DIGEST.warn("[{}] Invalid connection Id ,connection [{}] is un registered ,", "grpc", connectionId);
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.UN_REGISTER, "Connection is unregistered."));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
Object parseObj = null;
try {
parseObj = GrpcUtils.parse(grpcRequest);
} catch (Exception e) {
Loggers.REMOTE_DIGEST.warn("[{}] Invalid request receive from connection [{}] ,error={}", "grpc", connectionId, e);
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.BAD_GATEWAY, e.getMessage()));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
if (parseObj == null) {
Loggers.REMOTE_DIGEST.warn("[{}] Invalid request receive ,parse request is null", connectionId);
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.BAD_GATEWAY, "Invalid request"));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
if (!(parseObj instanceof Request)) {
Loggers.REMOTE_DIGEST.warn("[{}] Invalid request receive ,parsed payload is not a request,parseObj={}", connectionId, parseObj);
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build(NacosException.BAD_GATEWAY, "Invalid request"));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
return;
}
Request request = (Request) parseObj;
try {
Connection connection = connectionManager.getConnection(CONTEXT_KEY_CONN_ID.get());
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp(connection.getMetaInfo().getClientIp());
requestMeta.setConnectionId(CONTEXT_KEY_CONN_ID.get());
requestMeta.setClientVersion(connection.getMetaInfo().getVersion());
requestMeta.setLabels(connection.getMetaInfo().getLabels());
connectionManager.refreshActiveTime(requestMeta.getConnectionId());
Response response = requestHandler.handleRequest(request, requestMeta);
Payload payloadResponse = GrpcUtils.convert(response);
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
} catch (Throwable e) {
Loggers.REMOTE_DIGEST.error("[{}] Fail to handle request from connection [{}] ,error message :{}", "grpc", connectionId, e);
Payload payloadResponse = GrpcUtils.convert(ErrorResponse.build((e instanceof NacosException) ? ((NacosException) e).getErrCode() : ResponseCode.FAIL.getCode(), e.getMessage()));
traceIfNecessary(payloadResponse, false);
responseObserver.onNext(payloadResponse);
responseObserver.onCompleted();
}
}
use of com.alibaba.nacos.api.remote.request.RequestMeta in project nacos by alibaba.
the class ServerLoaderInfoRequestHandlerTest method testHandle.
@Test
public void testHandle() {
Mockito.when(connectionManager.currentClientsCount()).thenReturn(1);
Mockito.when(connectionManager.currentClientsCount(Mockito.any())).thenReturn(1);
Mockito.when(connectionManager.getConnectionLimitRule()).thenReturn(null);
ServerLoaderInfoRequest request = new ServerLoaderInfoRequest();
RequestMeta meta = new RequestMeta();
try {
ServerLoaderInfoResponse response = handler.handle(request, meta);
String sdkConCount = response.getMetricsValue("sdkConCount");
Assert.assertEquals(sdkConCount, "1");
} catch (NacosException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
use of com.alibaba.nacos.api.remote.request.RequestMeta in project nacos by alibaba.
the class ServerReloaderRequestHandlerTest method testHandle.
@Test
public void testHandle() {
Mockito.when(connectionManager.currentClientsCount(Mockito.any())).thenReturn(2);
ServerReloadRequest reloadRequest = new ServerReloadRequest();
reloadRequest.setReloadCount(2);
reloadRequest.setReloadServer("test");
RequestMeta meta = new RequestMeta();
meta.setClientIp("1.1.1.1");
try {
ServerReloadResponse reloadResponse = handler.handle(reloadRequest, meta);
Assert.assertEquals("ignore", reloadResponse.getMessage());
} catch (NacosException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
reloadRequest.setReloadCount(1);
try {
ServerReloadResponse reloadResponse = handler.handle(reloadRequest, meta);
Assert.assertEquals("ok", reloadResponse.getMessage());
} catch (NacosException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
Aggregations