Resolve the issues of codestyle of nacos-config module for phase5. (#3272)
* [#3249]Fix chinese unit method name in config test module. * [#3249]resolve the code style issue in service package. * [ISSUE#3249]fix typo.
This commit is contained in:
parent
144c1819b0
commit
0086dfe787
@ -16,21 +16,16 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.monitor;
|
package com.alibaba.nacos.config.server.monitor;
|
||||||
|
|
||||||
import com.alibaba.nacos.config.server.service.ClientTrackService;
|
|
||||||
import com.alibaba.nacos.config.server.service.ConfigCacheService;
|
|
||||||
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
|
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
|
||||||
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory monitor
|
* Memory monitor.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -58,40 +53,3 @@ public class MemoryMonitor {
|
|||||||
MetricsMonitor.getPublishMonitor().set(0);
|
MetricsMonitor.getPublishMonitor().set(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrintGetConfigResponeTask implements Runnable {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
memoryLog.info(ResponseMonitor.getStringForPrint());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrintMemoryTask implements Runnable {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int groupCount = ConfigCacheService.groupCount();
|
|
||||||
int subClientCount = ClientTrackService.subscribeClientCount();
|
|
||||||
long subCount = ClientTrackService.subscriberCount();
|
|
||||||
memoryLog.info("groupCount={}, subscriberClientCount={}, subscriberCount={}", groupCount, subClientCount,
|
|
||||||
subCount);
|
|
||||||
MetricsMonitor.getConfigCountMonitor().set(groupCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NotifyTaskQueueMonitorTask implements Runnable {
|
|
||||||
|
|
||||||
final private AsyncNotifyService notifySingleService;
|
|
||||||
|
|
||||||
NotifyTaskQueueMonitorTask(AsyncNotifyService notifySingleService) {
|
|
||||||
this.notifySingleService = notifySingleService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int size = ((ScheduledThreadPoolExecutor) notifySingleService.getExecutor()).getQueue().size();
|
|
||||||
memoryLog.info("toNotifyTaskSize={}", size);
|
|
||||||
MetricsMonitor.getNotifyTaskMonitor().set(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -16,14 +16,18 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.monitor;
|
package com.alibaba.nacos.config.server.monitor;
|
||||||
|
|
||||||
import io.micrometer.core.instrument.*;
|
import io.micrometer.core.instrument.Tag;
|
||||||
|
import io.micrometer.core.instrument.ImmutableTag;
|
||||||
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
import io.micrometer.core.instrument.Timer;
|
||||||
|
import io.micrometer.core.instrument.Counter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metrics Monitor
|
* Metrics Monitor.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NotifyTaskQueueMonitorTask.
|
||||||
|
*
|
||||||
|
* @author zongtanghu
|
||||||
|
*/
|
||||||
|
public class NotifyTaskQueueMonitorTask implements Runnable {
|
||||||
|
|
||||||
|
private final AsyncNotifyService notifySingleService;
|
||||||
|
|
||||||
|
NotifyTaskQueueMonitorTask(AsyncNotifyService notifySingleService) {
|
||||||
|
this.notifySingleService = notifySingleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int size = ((ScheduledThreadPoolExecutor) notifySingleService.getExecutor()).getQueue().size();
|
||||||
|
memoryLog.info("toNotifyTaskSize = {}", size);
|
||||||
|
MetricsMonitor.getNotifyTaskMonitor().set(size);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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 static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PrintGetConfigResponeTask.
|
||||||
|
*
|
||||||
|
* @author zongtanghu
|
||||||
|
*/
|
||||||
|
public class PrintGetConfigResponeTask implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
memoryLog.info(ResponseMonitor.getStringForPrint());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.alibaba.nacos.config.server.service.ClientTrackService;
|
||||||
|
import com.alibaba.nacos.config.server.service.ConfigCacheService;
|
||||||
|
|
||||||
|
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zongtanghu
|
||||||
|
*/
|
||||||
|
public class PrintMemoryTask implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int groupCount = ConfigCacheService.groupCount();
|
||||||
|
int subClientCount = ClientTrackService.subscribeClientCount();
|
||||||
|
long subCount = ClientTrackService.subscriberCount();
|
||||||
|
memoryLog.info("groupCount = {}, subscriberClientCount = {}, subscriberCount = {}", groupCount, subClientCount,
|
||||||
|
subCount);
|
||||||
|
MetricsMonitor.getConfigCountMonitor().set(groupCount);
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ import java.text.DecimalFormat;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response Monitory
|
* Response Monitory.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -48,12 +48,20 @@ public class ResponseMonitor {
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh for getting configCountDetail.
|
||||||
|
*/
|
||||||
public static void refresh() {
|
public static void refresh() {
|
||||||
for (int i = 0; i < getConfigCountDetail.length; i++) {
|
for (int i = 0; i < getConfigCountDetail.length; i++) {
|
||||||
getConfigCountDetail[i] = new AtomicLong();
|
getConfigCountDetail[i] = new AtomicLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddConfigTime.
|
||||||
|
*
|
||||||
|
* @param time config time which is added.
|
||||||
|
*/
|
||||||
public static void addConfigTime(long time) {
|
public static void addConfigTime(long time) {
|
||||||
getConfigCount.incrementAndGet();
|
getConfigCount.incrementAndGet();
|
||||||
if (time < MS_50) {
|
if (time < MS_50) {
|
||||||
|
@ -22,6 +22,8 @@ import com.alibaba.nacos.config.server.result.core.IResultCode;
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ResultBuilder.
|
||||||
|
*
|
||||||
* @author klw
|
* @author klw
|
||||||
* @ClassName: ResultBuilder
|
* @ClassName: ResultBuilder
|
||||||
* @Description: util for generating {@link RestResult}
|
* @Description: util for generating {@link RestResult}
|
||||||
@ -29,6 +31,14 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public class ResultBuilder {
|
public class ResultBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildResult.
|
||||||
|
*
|
||||||
|
* @param resultCode resultCode.
|
||||||
|
* @param resultData resultData.
|
||||||
|
* @param <T> T.
|
||||||
|
* @return RestResult.
|
||||||
|
*/
|
||||||
public static <T extends Object> RestResult<T> buildResult(IResultCode resultCode, T resultData) {
|
public static <T extends Object> RestResult<T> buildResult(IResultCode resultCode, T resultData) {
|
||||||
Assert.notNull(resultCode, "the resultCode can not be null");
|
Assert.notNull(resultCode, "the resultCode can not be null");
|
||||||
RestResult<T> rr = new RestResult<>(resultCode.getCode(), resultCode.getCodeMsg(), resultData);
|
RestResult<T> rr = new RestResult<>(resultCode.getCode(), resultCode.getCodeMsg(), resultData);
|
||||||
@ -39,6 +49,14 @@ public class ResultBuilder {
|
|||||||
return buildResult(ResultCodeEnum.SUCCESS, resultData);
|
return buildResult(ResultCodeEnum.SUCCESS, resultData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildSuccessResult.
|
||||||
|
*
|
||||||
|
* @param successMsg successMsg string value.
|
||||||
|
* @param resultData resultData.
|
||||||
|
* @param <T> T.
|
||||||
|
* @return RestResult.
|
||||||
|
*/
|
||||||
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg, T resultData) {
|
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg, T resultData) {
|
||||||
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, resultData);
|
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, resultData);
|
||||||
rr.setMessage(successMsg);
|
rr.setMessage(successMsg);
|
||||||
@ -49,6 +67,13 @@ public class ResultBuilder {
|
|||||||
return buildResult(ResultCodeEnum.SUCCESS, null);
|
return buildResult(ResultCodeEnum.SUCCESS, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildSuccessResult.
|
||||||
|
*
|
||||||
|
* @param successMsg successMsg string value.
|
||||||
|
* @param <T> T.
|
||||||
|
* @return RestResult.
|
||||||
|
*/
|
||||||
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg) {
|
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg) {
|
||||||
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, null);
|
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, null);
|
||||||
rr.setMessage(successMsg);
|
rr.setMessage(successMsg);
|
||||||
|
@ -19,6 +19,8 @@ package com.alibaba.nacos.config.server.result.code;
|
|||||||
import com.alibaba.nacos.config.server.result.core.IResultCode;
|
import com.alibaba.nacos.config.server.result.core.IResultCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ResultCodeEnum.
|
||||||
|
*
|
||||||
* @author klw
|
* @author klw
|
||||||
* @ClassName: ResultCodeEnum
|
* @ClassName: ResultCodeEnum
|
||||||
* @Description: result code enum
|
* @Description: result code enum
|
||||||
@ -27,13 +29,13 @@ import com.alibaba.nacos.config.server.result.core.IResultCode;
|
|||||||
public enum ResultCodeEnum implements IResultCode {
|
public enum ResultCodeEnum implements IResultCode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* common code
|
* Common code.
|
||||||
**/
|
**/
|
||||||
SUCCESS(200, "处理成功"),
|
SUCCESS(200, "处理成功"),
|
||||||
ERROR(500, "服务器内部错误"),
|
ERROR(500, "服务器内部错误"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* config use 100001 ~ 100999
|
* Config use 100001 ~ 100999.
|
||||||
**/
|
**/
|
||||||
NAMESPACE_NOT_EXIST(100001, "目标 namespace 不存在"),
|
NAMESPACE_NOT_EXIST(100001, "目标 namespace 不存在"),
|
||||||
|
|
||||||
@ -45,9 +47,7 @@ public enum ResultCodeEnum implements IResultCode {
|
|||||||
|
|
||||||
DATA_EMPTY(100005, "导入的文件数据为空"),
|
DATA_EMPTY(100005, "导入的文件数据为空"),
|
||||||
|
|
||||||
NO_SELECTED_CONFIG(100006, "没有选择任何配制"),
|
NO_SELECTED_CONFIG(100006, "没有选择任何配制");
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
package com.alibaba.nacos.config.server.result.core;
|
package com.alibaba.nacos.config.server.result.core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* IResultCode.
|
||||||
|
*
|
||||||
* @author klw
|
* @author klw
|
||||||
* @ClassName: IResultCode
|
* @ClassName: IResultCode
|
||||||
* @Description: result code enum needs to be implemented this interface
|
* @Description: result code enum needs to be implemented this interface
|
||||||
@ -25,22 +27,16 @@ package com.alibaba.nacos.config.server.result.core;
|
|||||||
public interface IResultCode {
|
public interface IResultCode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the result code
|
* Get the result code.
|
||||||
*
|
*
|
||||||
* @return java.lang.String
|
* @return code value.
|
||||||
* @author klw
|
|
||||||
* @Date 2019/6/28 14:56
|
|
||||||
* @Param []
|
|
||||||
*/
|
*/
|
||||||
int getCode();
|
int getCode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the result code's message
|
* Get the result code's message.
|
||||||
*
|
*
|
||||||
* @return java.lang.String
|
* @return code's message.
|
||||||
* @author klw
|
|
||||||
* @Date 2019/6/28 14:56
|
|
||||||
* @Param []
|
|
||||||
*/
|
*/
|
||||||
String getCodeMsg();
|
String getCodeMsg();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
|
|||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合数据白名单。
|
* AggrWhitelist.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -42,7 +42,10 @@ public class AggrWhitelist {
|
|||||||
public static final String AGGRIDS_METADATA = "com.alibaba.nacos.metadata.aggrIDs";
|
public static final String AGGRIDS_METADATA = "com.alibaba.nacos.metadata.aggrIDs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定的dataId是否在聚合dataId白名单。
|
* Judge whether specified dataId includes aggregation white list.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @return Whether to match aggregation rules.
|
||||||
*/
|
*/
|
||||||
public static boolean isAggrDataId(String dataId) {
|
public static boolean isAggrDataId(String dataId) {
|
||||||
if (null == dataId) {
|
if (null == dataId) {
|
||||||
@ -58,7 +61,9 @@ public class AggrWhitelist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传入内容,重新加载聚合白名单
|
* Load aggregation white lists based content parameter value.
|
||||||
|
*
|
||||||
|
* @param content content string value.
|
||||||
*/
|
*/
|
||||||
public static void load(String content) {
|
public static void load(String content) {
|
||||||
if (StringUtils.isBlank(content)) {
|
if (StringUtils.isBlank(content)) {
|
||||||
@ -91,8 +96,6 @@ public class AggrWhitelist {
|
|||||||
return AGGR_DATAID_WHITELIST.get();
|
return AGGR_DATAID_WHITELIST.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================
|
|
||||||
|
|
||||||
static final AtomicReference<List<Pattern>> AGGR_DATAID_WHITELIST = new AtomicReference<List<Pattern>>(
|
static final AtomicReference<List<Pattern>> AGGR_DATAID_WHITELIST = new AtomicReference<List<Pattern>>(
|
||||||
new ArrayList<Pattern>());
|
new ArrayList<Pattern>());
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client ip whitelist
|
* Client ip whitelist.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -36,13 +36,17 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
|
|||||||
public class ClientIpWhiteList {
|
public class ClientIpWhiteList {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定的ip在白名单中
|
* Judge whether specified client ip includes in the whitelist.
|
||||||
|
*
|
||||||
|
* @param clientIp clientIp string value.
|
||||||
|
* @return Judge result.
|
||||||
*/
|
*/
|
||||||
static public boolean isLegalClient(String clientIp) {
|
public static boolean isLegalClient(String clientIp) {
|
||||||
if (StringUtils.isBlank(clientIp)) {
|
if (StringUtils.isBlank(clientIp)) {
|
||||||
throw new IllegalArgumentException("clientIp is empty");
|
throw new IllegalArgumentException("clientIp is empty");
|
||||||
}
|
}
|
||||||
clientIp = clientIp.trim();
|
clientIp = clientIp.trim();
|
||||||
|
|
||||||
if (CLIENT_IP_WHITELIST.get().contains(clientIp)) {
|
if (CLIENT_IP_WHITELIST.get().contains(clientIp)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -50,18 +54,20 @@ public class ClientIpWhiteList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether start client ip whitelist
|
* Whether start client ip whitelist.
|
||||||
*
|
*
|
||||||
* @return true: enable ; false disable
|
* @return true: enable ; false disable
|
||||||
*/
|
*/
|
||||||
static public boolean isEnableWhitelist() {
|
public static boolean isEnableWhitelist() {
|
||||||
return isOpen;
|
return isOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传入内容,重新加载客户端ip白名单
|
* Load white lists based content parameter value.
|
||||||
|
*
|
||||||
|
* @param content content string value.
|
||||||
*/
|
*/
|
||||||
static public void load(String content) {
|
public static void load(String content) {
|
||||||
if (StringUtils.isBlank(content)) {
|
if (StringUtils.isBlank(content)) {
|
||||||
defaultLog.warn("clientIpWhiteList is blank.close whitelist.");
|
defaultLog.warn("clientIpWhiteList is blank.close whitelist.");
|
||||||
isOpen = false;
|
isOpen = false;
|
||||||
@ -78,12 +84,10 @@ public class ClientIpWhiteList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================
|
public static final String CLIENT_IP_WHITELIST_METADATA = "com.alibaba.nacos.metadata.clientIpWhitelist";
|
||||||
|
|
||||||
static public final String CLIENT_IP_WHITELIST_METADATA = "com.alibaba.nacos.metadata.clientIpWhitelist";
|
private static final AtomicReference<List<String>> CLIENT_IP_WHITELIST = new AtomicReference<List<String>>(
|
||||||
|
|
||||||
static final AtomicReference<List<String>> CLIENT_IP_WHITELIST = new AtomicReference<List<String>>(
|
|
||||||
new ArrayList<String>());
|
new ArrayList<String>());
|
||||||
|
|
||||||
static Boolean isOpen = false;
|
private static Boolean isOpen = false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.service;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientRecord saves records which fetch from client-side.
|
||||||
|
*
|
||||||
|
* @author zongtanghu
|
||||||
|
*/
|
||||||
|
public class ClientRecord {
|
||||||
|
|
||||||
|
private final String ip;
|
||||||
|
|
||||||
|
private volatile long lastTime;
|
||||||
|
|
||||||
|
private final ConcurrentMap<String, String> groupKey2md5Map;
|
||||||
|
|
||||||
|
private final ConcurrentMap<String, Long> groupKey2pollingTsMap;
|
||||||
|
|
||||||
|
public ClientRecord(final String clientIp) {
|
||||||
|
this.ip = clientIp;
|
||||||
|
this.groupKey2md5Map = new ConcurrentHashMap<String, String>(20, 0.75f, 1);
|
||||||
|
this.groupKey2pollingTsMap = new ConcurrentHashMap<String, Long>(20, 0.75f, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastTime() {
|
||||||
|
return lastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastTime(long lastTime) {
|
||||||
|
this.lastTime = lastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentMap<String, String> getGroupKey2md5Map() {
|
||||||
|
return groupKey2md5Map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentMap<String, Long> getGroupKey2pollingTsMap() {
|
||||||
|
return groupKey2pollingTsMap;
|
||||||
|
}
|
||||||
|
}
|
@ -24,58 +24,77 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跟踪客户端md5的服务。 一段时间没有比较md5后,就删除IP对应的记录。
|
* ClientTrackService which tracks client's md5 service and delete expired ip's records.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
public class ClientTrackService {
|
public class ClientTrackService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跟踪客户端md5.
|
* Track client's md5 value.
|
||||||
*/
|
*/
|
||||||
static public void trackClientMd5(String ip, Map<String, String> clientMd5Map) {
|
public static void trackClientMd5(String ip, Map<String, String> clientMd5Map) {
|
||||||
ClientRecord record = getClientRecord(ip);
|
ClientRecord record = getClientRecord(ip);
|
||||||
record.lastTime = System.currentTimeMillis();
|
record.setLastTime(System.currentTimeMillis());
|
||||||
record.groupKey2md5Map.putAll(clientMd5Map);
|
record.getGroupKey2md5Map().putAll(clientMd5Map);
|
||||||
}
|
|
||||||
|
|
||||||
static public void trackClientMd5(String ip, Map<String, String> clientMd5Map,
|
|
||||||
Map<String, Long> clientlastPollingTSMap) {
|
|
||||||
ClientRecord record = getClientRecord(ip);
|
|
||||||
record.lastTime = System.currentTimeMillis();
|
|
||||||
record.groupKey2md5Map.putAll(clientMd5Map);
|
|
||||||
record.groupKey2pollingTsMap.putAll(clientlastPollingTSMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static public void trackClientMd5(String ip, String groupKey, String clientMd5) {
|
|
||||||
ClientRecord record = getClientRecord(ip);
|
|
||||||
record.lastTime = System.currentTimeMillis();
|
|
||||||
record.groupKey2md5Map.put(groupKey, clientMd5);
|
|
||||||
record.groupKey2pollingTsMap.put(groupKey, record.lastTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回订阅者客户端个数
|
* TrackClientMd5.
|
||||||
|
*
|
||||||
|
* @param ip ip string value.
|
||||||
|
* @param clientMd5Map clientMd5Map.
|
||||||
|
* @param clientLastPollingTsMap clientLastPollingTsMap.
|
||||||
*/
|
*/
|
||||||
static public int subscribeClientCount() {
|
public static void trackClientMd5(String ip, Map<String, String> clientMd5Map,
|
||||||
|
Map<String, Long> clientLastPollingTsMap) {
|
||||||
|
ClientRecord record = getClientRecord(ip);
|
||||||
|
record.setLastTime(System.currentTimeMillis());
|
||||||
|
record.getGroupKey2md5Map().putAll(clientMd5Map);
|
||||||
|
record.getGroupKey2pollingTsMap().putAll(clientLastPollingTsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the specified value(ip/groupKey/clientMd5) into clientRecords Map.
|
||||||
|
*
|
||||||
|
* @param ip ip string value.
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @param clientMd5 clientMd5 string value.
|
||||||
|
*/
|
||||||
|
public static void trackClientMd5(String ip, String groupKey, String clientMd5) {
|
||||||
|
ClientRecord record = getClientRecord(ip);
|
||||||
|
record.setLastTime(System.currentTimeMillis());
|
||||||
|
record.getGroupKey2md5Map().put(groupKey, clientMd5);
|
||||||
|
record.getGroupKey2pollingTsMap().put(groupKey, record.getLastTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get subscribe client count.
|
||||||
|
*
|
||||||
|
* @return subscribe client count.
|
||||||
|
*/
|
||||||
|
public static int subscribeClientCount() {
|
||||||
return clientRecords.size();
|
return clientRecords.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回所有订阅者个数
|
* Get all of subsciber count.
|
||||||
|
*
|
||||||
|
* @return all of subsciber count.
|
||||||
*/
|
*/
|
||||||
static public long subscriberCount() {
|
public static long subscriberCount() {
|
||||||
long count = 0;
|
long count = 0;
|
||||||
for (ClientRecord record : clientRecords.values()) {
|
for (ClientRecord record : clientRecords.values()) {
|
||||||
count += record.groupKey2md5Map.size();
|
count += record.getGroupKey2md5Map().size();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* groupkey -> SubscriberStatus
|
* Groupkey -> SubscriberStatus.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static public Map<String, SubscriberStatus> listSubStatus(String ip) {
|
public static Map<String, SubscriberStatus> listSubStatus(String ip) {
|
||||||
Map<String, SubscriberStatus> status = new HashMap<String, SubscriberStatus>(100);
|
Map<String, SubscriberStatus> status = new HashMap<String, SubscriberStatus>(100);
|
||||||
|
|
||||||
ClientRecord record = getClientRecord(ip);
|
ClientRecord record = getClientRecord(ip);
|
||||||
@ -83,10 +102,10 @@ public class ClientTrackService {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : record.groupKey2md5Map.entrySet()) {
|
for (Map.Entry<String, String> entry : record.getGroupKey2md5Map().entrySet()) {
|
||||||
String groupKey = entry.getKey();
|
String groupKey = entry.getKey();
|
||||||
String clientMd5 = entry.getValue();
|
String clientMd5 = entry.getValue();
|
||||||
long lastPollingTs = record.groupKey2pollingTsMap.get(groupKey);
|
long lastPollingTs = record.getGroupKey2pollingTsMap().get(groupKey);
|
||||||
boolean isUpdate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
boolean isUpdate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
||||||
|
|
||||||
status.put(groupKey, new SubscriberStatus(groupKey, isUpdate, clientMd5, lastPollingTs));
|
status.put(groupKey, new SubscriberStatus(groupKey, isUpdate, clientMd5, lastPollingTs));
|
||||||
@ -96,18 +115,18 @@ public class ClientTrackService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ip -> SubscriberStatus
|
* Ip -> SubscriberStatus.
|
||||||
*/
|
*/
|
||||||
static public Map<String, SubscriberStatus> listSubsByGroup(String groupKey) {
|
public static Map<String, SubscriberStatus> listSubsByGroup(String groupKey) {
|
||||||
Map<String, SubscriberStatus> subs = new HashMap<String, SubscriberStatus>(100);
|
Map<String, SubscriberStatus> subs = new HashMap<String, SubscriberStatus>(100);
|
||||||
|
|
||||||
for (ClientRecord clientRec : clientRecords.values()) {
|
for (ClientRecord clientRec : clientRecords.values()) {
|
||||||
String clientMd5 = clientRec.groupKey2md5Map.get(groupKey);
|
String clientMd5 = clientRec.getGroupKey2md5Map().get(groupKey);
|
||||||
Long lastPollingTs = clientRec.groupKey2pollingTsMap.get(groupKey);
|
Long lastPollingTs = clientRec.getGroupKey2pollingTsMap().get(groupKey);
|
||||||
|
|
||||||
if (null != clientMd5 && lastPollingTs != null) {
|
if (null != clientMd5 && null != lastPollingTs) {
|
||||||
Boolean isUpdate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
Boolean isUpdate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
||||||
subs.put(clientRec.ip, new SubscriberStatus(groupKey, isUpdate, clientMd5, lastPollingTs));
|
subs.put(clientRec.getIp(), new SubscriberStatus(groupKey, isUpdate, clientMd5, lastPollingTs));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -115,11 +134,13 @@ public class ClientTrackService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定订阅者IP,查找数据是否最新。 groupKey -> isUptodate
|
* Specify subscriber's ip and look up whether data is lastest.
|
||||||
|
* groupKey -> isUptodate.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static public Map<String, Boolean> isClientUptodate(String ip) {
|
public static Map<String, Boolean> isClientUptodate(String ip) {
|
||||||
Map<String, Boolean> result = new HashMap<String, Boolean>(100);
|
Map<String, Boolean> result = new HashMap<String, Boolean>(100);
|
||||||
for (Map.Entry<String, String> entry : getClientRecord(ip).groupKey2md5Map.entrySet()) {
|
for (Map.Entry<String, String> entry : getClientRecord(ip).getGroupKey2md5Map().entrySet()) {
|
||||||
String groupKey = entry.getKey();
|
String groupKey = entry.getKey();
|
||||||
String clientMd5 = entry.getValue();
|
String clientMd5 = entry.getValue();
|
||||||
Boolean isuptodate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
Boolean isuptodate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
||||||
@ -129,61 +150,46 @@ public class ClientTrackService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定groupKey,查找所有订阅者以及数据是否最新。 IP -> isUptodate
|
* Specify groupKey and look up whether subsciber and data is lastest.
|
||||||
|
* IP -> isUptodate.
|
||||||
*/
|
*/
|
||||||
static public Map<String, Boolean> listSubscriberByGroup(String groupKey) {
|
public static Map<String, Boolean> listSubscriberByGroup(String groupKey) {
|
||||||
Map<String, Boolean> subs = new HashMap<String, Boolean>(100);
|
Map<String, Boolean> subs = new HashMap<String, Boolean>(100);
|
||||||
|
|
||||||
for (ClientRecord clientRec : clientRecords.values()) {
|
for (ClientRecord clientRec : clientRecords.values()) {
|
||||||
String clientMd5 = clientRec.groupKey2md5Map.get(groupKey);
|
String clientMd5 = clientRec.getGroupKey2md5Map().get(groupKey);
|
||||||
if (null != clientMd5) {
|
if (null != clientMd5) {
|
||||||
Boolean isuptodate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
Boolean isuptodate = ConfigCacheService.isUptodate(groupKey, clientMd5);
|
||||||
subs.put(clientRec.ip, isuptodate);
|
subs.put(clientRec.getIp(), isuptodate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return subs;
|
return subs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 找到指定clientIp对应的记录。
|
* Get and return the record of specified client ip.
|
||||||
|
*
|
||||||
|
* @param clientIp clientIp string value.
|
||||||
|
* @return the record of specified client ip.
|
||||||
*/
|
*/
|
||||||
static private ClientRecord getClientRecord(String clientIp) {
|
private static ClientRecord getClientRecord(String clientIp) {
|
||||||
ClientRecord record = clientRecords.get(clientIp);
|
ClientRecord record = clientRecords.get(clientIp);
|
||||||
if (null != record) {
|
if (null != record) {
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
clientRecords.putIfAbsent(clientIp, new ClientRecord(clientIp));
|
ClientRecord clientRecord = new ClientRecord(clientIp);
|
||||||
return clientRecords.get(clientIp);
|
clientRecords.putIfAbsent(clientIp, clientRecord);
|
||||||
|
return clientRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void refreshClientRecord() {
|
public static void refreshClientRecord() {
|
||||||
clientRecords = new ConcurrentHashMap<String, ClientRecord>(50);
|
clientRecords = new ConcurrentHashMap<String, ClientRecord>(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所有客户端记录。遍历 >> 新增/删除
|
* All of client records, adding or deleting.
|
||||||
*/
|
*/
|
||||||
static volatile ConcurrentMap<String, ClientRecord> clientRecords = new ConcurrentHashMap<String, ClientRecord>();
|
static volatile ConcurrentMap<String, ClientRecord> clientRecords = new ConcurrentHashMap<String, ClientRecord>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存客户端拉数据的记录。
|
|
||||||
*/
|
|
||||||
class ClientRecord {
|
|
||||||
|
|
||||||
final String ip;
|
|
||||||
|
|
||||||
volatile long lastTime;
|
|
||||||
|
|
||||||
final ConcurrentMap<String, String> groupKey2md5Map;
|
|
||||||
|
|
||||||
final ConcurrentMap<String, Long> groupKey2pollingTsMap;
|
|
||||||
|
|
||||||
ClientRecord(String clientIp) {
|
|
||||||
ip = clientIp;
|
|
||||||
groupKey2md5Map = new ConcurrentHashMap<String, String>(20, 0.75f, 1);
|
|
||||||
groupKey2pollingTsMap = new ConcurrentHashMap<String, Long>(20, 0.75f, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,14 +33,21 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.*;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.dumpLog;
|
||||||
|
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
||||||
|
import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* config service
|
* Config service.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -49,18 +56,26 @@ public class ConfigCacheService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private static PersistService persistService;
|
private static PersistService persistService;
|
||||||
|
|
||||||
static public int groupCount() {
|
public static int groupCount() {
|
||||||
return CACHE.size();
|
return CACHE.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean hasGroupKey(String groupKey) {
|
public static boolean hasGroupKey(String groupKey) {
|
||||||
return CACHE.containsKey(groupKey);
|
return CACHE.containsKey(groupKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存配置文件,并缓存md5.
|
* Save config file and update md5 value in cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @param content content string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
|
* @param type file type.
|
||||||
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
public static boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
||||||
String type) {
|
String type) {
|
||||||
String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
CacheItem ci = makeSure(groupKey);
|
CacheItem ci = makeSure(groupKey);
|
||||||
@ -91,7 +106,7 @@ public class ConfigCacheService {
|
|||||||
String errMsg = ioe.getMessage();
|
String errMsg = ioe.getMessage();
|
||||||
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUATA_CN) || errMsg
|
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUATA_CN) || errMsg
|
||||||
.contains(DISK_QUATA_EN)) {
|
.contains(DISK_QUATA_EN)) {
|
||||||
// 磁盘写满保护代码
|
// Protect from disk full.
|
||||||
fatalLog.error("磁盘满自杀退出", ioe);
|
fatalLog.error("磁盘满自杀退出", ioe);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
@ -103,9 +118,17 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存配置文件,并缓存md5.
|
* Save config file and update md5 value in cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @param content content string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
|
* @param betaIps betaIps string value.
|
||||||
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
public static boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
||||||
String betaIps) {
|
String betaIps) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
|
|
||||||
@ -140,9 +163,17 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存配置文件,并缓存md5.
|
* Save config file and update md5 value in cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @param content content string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
|
* @param tag tag string value.
|
||||||
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean dumpTag(String dataId, String group, String tenant, String tag, String content,
|
public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content,
|
||||||
long lastModifiedTs) {
|
long lastModifiedTs) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
|
|
||||||
@ -176,9 +207,16 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存配置文件,并缓存md5.
|
* Save config file and update md5 value in cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @param content content string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean dumpChange(String dataId, String group, String tenant, String content, long lastModifiedTs) {
|
public static boolean dumpChange(String dataId, String group, String tenant, String content, long lastModifiedTs) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
|
|
||||||
makeSure(groupKey);
|
makeSure(groupKey);
|
||||||
@ -212,7 +250,10 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void reloadConfig() {
|
/**
|
||||||
|
* Reload config.
|
||||||
|
*/
|
||||||
|
public static void reloadConfig() {
|
||||||
String aggreds = null;
|
String aggreds = null;
|
||||||
try {
|
try {
|
||||||
if (PropertyUtil.isEmbeddedStorage()) {
|
if (PropertyUtil.isEmbeddedStorage()) {
|
||||||
@ -268,10 +309,13 @@ public class ConfigCacheService {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
dumpLog.error("reload fail:" + SwitchService.SWITCH_META_DATAID, e);
|
dumpLog.error("reload fail:" + SwitchService.SWITCH_META_DATAID, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public List<String> checkMd5() {
|
/**
|
||||||
|
* Check md5.
|
||||||
|
* @return return diff result list.
|
||||||
|
*/
|
||||||
|
public static List<String> checkMd5() {
|
||||||
List<String> diffList = new ArrayList<String>();
|
List<String> diffList = new ArrayList<String>();
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
for (Entry<String/* groupKey */, CacheItem> entry : CACHE.entrySet()) {
|
for (Entry<String/* groupKey */, CacheItem> entry : CACHE.entrySet()) {
|
||||||
@ -296,21 +340,24 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除配置文件,删除缓存。
|
* Delete config file, and delete cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean remove(String dataId, String group, String tenant) {
|
public static boolean remove(String dataId, String group, String tenant) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
final int lockResult = tryWriteLock(groupKey);
|
final int lockResult = tryWriteLock(groupKey);
|
||||||
/**
|
|
||||||
* 数据不存在
|
// If data is non-existent.
|
||||||
*/
|
|
||||||
if (0 == lockResult) {
|
if (0 == lockResult) {
|
||||||
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 加锁失败
|
// try to lock failed
|
||||||
*/
|
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
return false;
|
return false;
|
||||||
@ -330,21 +377,24 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除配置文件,删除缓存。
|
* Delete beta config file, and delete cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean removeBeta(String dataId, String group, String tenant) {
|
public static boolean removeBeta(String dataId, String group, String tenant) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
final int lockResult = tryWriteLock(groupKey);
|
final int lockResult = tryWriteLock(groupKey);
|
||||||
/**
|
|
||||||
* 数据不存在
|
// If data is non-existent.
|
||||||
*/
|
|
||||||
if (0 == lockResult) {
|
if (0 == lockResult) {
|
||||||
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 加锁失败
|
// try to lock failed
|
||||||
*/
|
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
return false;
|
return false;
|
||||||
@ -365,21 +415,25 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除配置文件,删除缓存。
|
* Delete tag config file, and delete cache.
|
||||||
|
*
|
||||||
|
* @param dataId dataId string value.
|
||||||
|
* @param group group string value.
|
||||||
|
* @param tenant tenant string value.
|
||||||
|
* @param tag tag string value.
|
||||||
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
static public boolean removeTag(String dataId, String group, String tenant, String tag) {
|
public static boolean removeTag(String dataId, String group, String tenant, String tag) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
final int lockResult = tryWriteLock(groupKey);
|
final int lockResult = tryWriteLock(groupKey);
|
||||||
/**
|
|
||||||
* 数据不存在
|
// If data is non-existent.
|
||||||
*/
|
|
||||||
if (0 == lockResult) {
|
if (0 == lockResult) {
|
||||||
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
dumpLog.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 加锁失败
|
// try to lock failed
|
||||||
*/
|
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
dumpLog.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
return false;
|
return false;
|
||||||
@ -400,6 +454,13 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update md5 value.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @param md5 md5 string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
|
*/
|
||||||
public static void updateMd5(String groupKey, String md5, long lastModifiedTs) {
|
public static void updateMd5(String groupKey, String md5, long lastModifiedTs) {
|
||||||
CacheItem cache = makeSure(groupKey);
|
CacheItem cache = makeSure(groupKey);
|
||||||
if (cache.md5 == null || !cache.md5.equals(md5)) {
|
if (cache.md5 == null || !cache.md5.equals(md5)) {
|
||||||
@ -409,6 +470,14 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Beta md5 value.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @param md5 md5 string value.
|
||||||
|
* @param ips4Beta ips4Beta List.
|
||||||
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
|
*/
|
||||||
public static void updateBetaMd5(String groupKey, String md5, List<String> ips4Beta, long lastModifiedTs) {
|
public static void updateBetaMd5(String groupKey, String md5, List<String> ips4Beta, long lastModifiedTs) {
|
||||||
CacheItem cache = makeSure(groupKey);
|
CacheItem cache = makeSure(groupKey);
|
||||||
if (cache.md54Beta == null || !cache.md54Beta.equals(md5)) {
|
if (cache.md54Beta == null || !cache.md54Beta.equals(md5)) {
|
||||||
@ -420,6 +489,14 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update tag md5 value.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @param tag tag string value.
|
||||||
|
* @param md5 md5 string value.
|
||||||
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
|
*/
|
||||||
public static void updateTagMd5(String groupKey, String tag, String md5, long lastModifiedTs) {
|
public static void updateTagMd5(String groupKey, String tag, String md5, long lastModifiedTs) {
|
||||||
CacheItem cache = makeSure(groupKey);
|
CacheItem cache = makeSure(groupKey);
|
||||||
if (cache.tagMd5 == null) {
|
if (cache.tagMd5 == null) {
|
||||||
@ -444,51 +521,14 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回cache的md5。零长度字符串表示没有该数据。
|
* Get and return content md5 value from cache. Empty string represents no data.
|
||||||
*/
|
*/
|
||||||
static public String getContentMd5(String groupKey) {
|
public static String getContentMd5(String groupKey) {
|
||||||
CacheItem item = CACHE.get(groupKey);
|
CacheItem item = CACHE.get(groupKey);
|
||||||
return (null != item) ? item.md5 : Constants.NULL;
|
return (null != item) ? item.md5 : Constants.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String getContentMd5(String groupKey, String ip, String tag) {
|
||||||
* 返回cache的md5。零长度字符串表示没有该数据。
|
|
||||||
*/
|
|
||||||
static public String getContentBetaMd5(String groupKey) {
|
|
||||||
CacheItem item = CACHE.get(groupKey);
|
|
||||||
return (null != item) ? item.md54Beta : Constants.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回cache的md5。零长度字符串表示没有该数据。
|
|
||||||
*/
|
|
||||||
static public String getContentTagMd5(String groupKey, String tag) {
|
|
||||||
CacheItem item = CACHE.get(groupKey);
|
|
||||||
if (item == null) {
|
|
||||||
return Constants.NULL;
|
|
||||||
}
|
|
||||||
if (item.tagMd5 == null) {
|
|
||||||
return Constants.NULL;
|
|
||||||
}
|
|
||||||
return item.tagMd5.get(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回beta Ip列表
|
|
||||||
*/
|
|
||||||
static public List<String> getBetaIps(String groupKey) {
|
|
||||||
CacheItem item = CACHE.get(groupKey);
|
|
||||||
return (null != item) ? item.getIps4Beta() : Collections.<String>emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回cache。
|
|
||||||
*/
|
|
||||||
static public CacheItem getContentCache(String groupKey) {
|
|
||||||
return CACHE.get(groupKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static public String getContentMd5(String groupKey, String ip, String tag) {
|
|
||||||
CacheItem item = CACHE.get(groupKey);
|
CacheItem item = CACHE.get(groupKey);
|
||||||
if (item != null && item.isBeta) {
|
if (item != null && item.isBeta) {
|
||||||
if (item.ips4Beta.contains(ip)) {
|
if (item.ips4Beta.contains(ip)) {
|
||||||
@ -503,28 +543,76 @@ public class ConfigCacheService {
|
|||||||
return (null != item) ? item.md5 : Constants.NULL;
|
return (null != item) ? item.md5 : Constants.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public long getLastModifiedTs(String groupKey) {
|
/**
|
||||||
|
* Get and return beta md5 value from cache. Empty string represents no data.
|
||||||
|
*/
|
||||||
|
public static String getContentBetaMd5(String groupKey) {
|
||||||
|
CacheItem item = CACHE.get(groupKey);
|
||||||
|
return (null != item) ? item.md54Beta : Constants.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and return tag md5 value from cache. Empty string represents no data.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @param tag tag string value.
|
||||||
|
* @return Content Tag Md5 value.
|
||||||
|
*/
|
||||||
|
public static String getContentTagMd5(String groupKey, String tag) {
|
||||||
|
CacheItem item = CACHE.get(groupKey);
|
||||||
|
if (item == null) {
|
||||||
|
return Constants.NULL;
|
||||||
|
}
|
||||||
|
if (item.tagMd5 == null) {
|
||||||
|
return Constants.NULL;
|
||||||
|
}
|
||||||
|
return item.tagMd5.get(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and return beta ip list.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @return list beta ips.
|
||||||
|
*/
|
||||||
|
public static List<String> getBetaIps(String groupKey) {
|
||||||
|
CacheItem item = CACHE.get(groupKey);
|
||||||
|
return (null != item) ? item.getIps4Beta() : Collections.<String>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and return content cache.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
* @return CacheItem.
|
||||||
|
*/
|
||||||
|
public static CacheItem getContentCache(String groupKey) {
|
||||||
|
return CACHE.get(groupKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getLastModifiedTs(String groupKey) {
|
||||||
CacheItem item = CACHE.get(groupKey);
|
CacheItem item = CACHE.get(groupKey);
|
||||||
return (null != item) ? item.lastModifiedTs : 0L;
|
return (null != item) ? item.lastModifiedTs : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isUptodate(String groupKey, String md5) {
|
public static boolean isUptodate(String groupKey, String md5) {
|
||||||
String serverMd5 = ConfigCacheService.getContentMd5(groupKey);
|
String serverMd5 = ConfigCacheService.getContentMd5(groupKey);
|
||||||
return StringUtils.equals(md5, serverMd5);
|
return StringUtils.equals(md5, serverMd5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isUptodate(String groupKey, String md5, String ip, String tag) {
|
public static boolean isUptodate(String groupKey, String md5, String ip, String tag) {
|
||||||
String serverMd5 = ConfigCacheService.getContentMd5(groupKey, ip, tag);
|
String serverMd5 = ConfigCacheService.getContentMd5(groupKey, ip, tag);
|
||||||
return StringUtils.equals(md5, serverMd5);
|
return StringUtils.equals(md5, serverMd5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给数据加读锁。如果成功,后面必须调用{@link #releaseReadLock(String)},失败则不需要。
|
* Try to add read lock. If it successed, then it can call {@link #releaseWriteLock(String)}.And it won't call if
|
||||||
|
* failed.
|
||||||
*
|
*
|
||||||
* @param groupKey
|
* @param groupKey groupKey string value.
|
||||||
* @return 零表示没有数据,失败。正数表示成功,负数表示有写锁导致加锁失败。
|
* @return 0 - No data and failed. Positive number 0 - Success. Negative number - lock failed。
|
||||||
*/
|
*/
|
||||||
static public int tryReadLock(String groupKey) {
|
public static int tryReadLock(String groupKey) {
|
||||||
CacheItem groupItem = CACHE.get(groupKey);
|
CacheItem groupItem = CACHE.get(groupKey);
|
||||||
int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryReadLock() ? 1 : -1);
|
int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryReadLock() ? 1 : -1);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
@ -533,7 +621,12 @@ public class ConfigCacheService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void releaseReadLock(String groupKey) {
|
/**
|
||||||
|
* Release readLock.
|
||||||
|
*
|
||||||
|
* @param groupKey groupKey string value.
|
||||||
|
*/
|
||||||
|
public static void releaseReadLock(String groupKey) {
|
||||||
CacheItem item = CACHE.get(groupKey);
|
CacheItem item = CACHE.get(groupKey);
|
||||||
if (null != item) {
|
if (null != item) {
|
||||||
item.rwLock.releaseReadLock();
|
item.rwLock.releaseReadLock();
|
||||||
@ -541,10 +634,11 @@ public class ConfigCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给数据加写锁。如果成功,后面必须调用{@link #releaseWriteLock(String)},失败则不需要。
|
* Try to add write lock. If it successed, then it can call {@link #releaseWriteLock(String)}.And it won't call if
|
||||||
|
* failed.
|
||||||
*
|
*
|
||||||
* @param groupKey
|
* @param groupKey groupKey string value.
|
||||||
* @return 零表示没有数据,失败。正数表示成功,负数表示加锁失败。
|
* @return 0 - No data and failed. Positive number 0 - Success. Negative number - lock failed。
|
||||||
*/
|
*/
|
||||||
static int tryWriteLock(String groupKey) {
|
static int tryWriteLock(String groupKey) {
|
||||||
CacheItem groupItem = CACHE.get(groupKey);
|
CacheItem groupItem = CACHE.get(groupKey);
|
||||||
@ -572,19 +666,19 @@ public class ConfigCacheService {
|
|||||||
return (null == item) ? tmp : item;
|
return (null == item) ? tmp : item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String NO_SPACE_CN = "设备上没有空间";
|
private static final String NO_SPACE_CN = "设备上没有空间";
|
||||||
|
|
||||||
private final static String NO_SPACE_EN = "No space left on device";
|
private static final String NO_SPACE_EN = "No space left on device";
|
||||||
|
|
||||||
private final static String DISK_QUATA_CN = "超出磁盘限额";
|
private static final String DISK_QUATA_CN = "超出磁盘限额";
|
||||||
|
|
||||||
private final static String DISK_QUATA_EN = "Disk quota exceeded";
|
private static final String DISK_QUATA_EN = "Disk quota exceeded";
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(ConfigCacheService.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(ConfigCacheService.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* groupKey -> cacheItem
|
* groupKey -> cacheItem.
|
||||||
*/
|
*/
|
||||||
static private final ConcurrentHashMap<String, CacheItem> CACHE = new ConcurrentHashMap<String, CacheItem>();
|
private static final ConcurrentHashMap<String, CacheItem> CACHE = new ConcurrentHashMap<String, CacheItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,16 @@ import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
|||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ConfigChangePublisher.
|
||||||
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class ConfigChangePublisher {
|
public class ConfigChangePublisher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify ConfigChange.
|
||||||
|
* @param event ConfigDataChangeEvent instance.
|
||||||
|
*/
|
||||||
public static void notifyConfigChange(ConfigDataChangeEvent event) {
|
public static void notifyConfigChange(ConfigDataChangeEvent event) {
|
||||||
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
||||||
return;
|
return;
|
||||||
|
@ -37,10 +37,21 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.CompletionService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* config sub service
|
* Config sub service.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -72,11 +83,11 @@ public class ConfigSubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得调用的URL
|
* Get and return called url string value.
|
||||||
*
|
*
|
||||||
* @param ip ip
|
* @param ip ip.
|
||||||
* @param relativePath path
|
* @param relativePath path.
|
||||||
* @return all path
|
* @return all path.
|
||||||
*/
|
*/
|
||||||
private String getUrl(String ip, String relativePath) {
|
private String getUrl(String ip, String relativePath) {
|
||||||
return "http://" + ip + ApplicationUtils.getContextPath() + relativePath;
|
return "http://" + ip + ApplicationUtils.getContextPath() + relativePath;
|
||||||
@ -87,16 +98,16 @@ public class ConfigSubService {
|
|||||||
|
|
||||||
Collection<Member> ipList = memberManager.allMembers();
|
Collection<Member> ipList = memberManager.allMembers();
|
||||||
List<SampleResult> collectionResult = new ArrayList<SampleResult>(ipList.size());
|
List<SampleResult> collectionResult = new ArrayList<SampleResult>(ipList.size());
|
||||||
// 提交查询任务
|
// Submit query task.
|
||||||
for (Member ip : ipList) {
|
for (Member ip : ipList) {
|
||||||
try {
|
try {
|
||||||
completionService.submit(new Job(ip.getAddress(), url, params));
|
completionService.submit(new Job(ip.getAddress(), url, params));
|
||||||
} catch (Exception e) { // 发送请求失败
|
} catch (Exception e) { // Send request failed.
|
||||||
LogUtil.defaultLog
|
LogUtil.defaultLog
|
||||||
.warn("Get client info from {} with exception: {} during submit job", ip, e.getMessage());
|
.warn("Get client info from {} with exception: {} during submit job", ip, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 获取结果并合并
|
// Get and merge result.
|
||||||
SampleResult sampleResults = null;
|
SampleResult sampleResults = null;
|
||||||
for (Member member : ipList) {
|
for (Member member : ipList) {
|
||||||
try {
|
try {
|
||||||
@ -125,6 +136,13 @@ public class ConfigSubService {
|
|||||||
return collectionResult;
|
return collectionResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge SampleResult.
|
||||||
|
*
|
||||||
|
* @param sampleCollectResult sampleCollectResult.
|
||||||
|
* @param sampleResults sampleResults.
|
||||||
|
* @return SampleResult.
|
||||||
|
*/
|
||||||
public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List<SampleResult> sampleResults) {
|
public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List<SampleResult> sampleResults) {
|
||||||
SampleResult mergeResult = new SampleResult();
|
SampleResult mergeResult = new SampleResult();
|
||||||
Map<String, String> lisentersGroupkeyStatus = null;
|
Map<String, String> lisentersGroupkeyStatus = null;
|
||||||
@ -146,7 +164,7 @@ public class ConfigSubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 去每个Nacos Server节点查询订阅者的任务
|
* Query subsrciber's task from every nacos server nodes.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -177,9 +195,8 @@ public class ConfigSubService {
|
|||||||
String urlAll = getUrl(ip, url) + "?" + paramUrl;
|
String urlAll = getUrl(ip, url) + "?" + paramUrl;
|
||||||
com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult result = NotifyService
|
com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult result = NotifyService
|
||||||
.invokeURL(urlAll, null, Constants.ENCODE);
|
.invokeURL(urlAll, null, Constants.ENCODE);
|
||||||
/**
|
|
||||||
* http code 200
|
// Http code 200
|
||||||
*/
|
|
||||||
if (result.code == HttpURLConnection.HTTP_OK) {
|
if (result.code == HttpURLConnection.HTTP_OK) {
|
||||||
String json = result.content;
|
String json = result.content;
|
||||||
SampleResult resultObj = JSONUtils.deserializeObject(json, new TypeReference<SampleResult>() {
|
SampleResult resultObj = JSONUtils.deserializeObject(json, new TypeReference<SampleResult>() {
|
||||||
|
@ -33,14 +33,30 @@ import org.springframework.stereotype.Service;
|
|||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.pullLog;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.pullLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 长轮询服务。负责处理
|
* LongPollingService.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -99,7 +115,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
|
|
||||||
for (ClientLongPolling clientLongPolling : allSubs) {
|
for (ClientLongPolling clientLongPolling : allSubs) {
|
||||||
if (clientLongPolling.ip.equals(clientIp)) {
|
if (clientLongPolling.ip.equals(clientIp)) {
|
||||||
// 一个ip可能有多个监听
|
// One ip can have multiple listener.
|
||||||
if (!lisentersGroupkeyStatus.equals(clientLongPolling.clientMd5Map)) {
|
if (!lisentersGroupkeyStatus.equals(clientLongPolling.clientMd5Map)) {
|
||||||
lisentersGroupkeyStatus.putAll(clientLongPolling.clientMd5Map);
|
lisentersGroupkeyStatus.putAll(clientLongPolling.clientMd5Map);
|
||||||
}
|
}
|
||||||
@ -110,10 +126,11 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合采样结果中的采样ip和监听配置的信息;合并策略用后面的覆盖前面的是没有问题的
|
* Aggregate the sampling IP and monitoring configuration information in the sampling results.
|
||||||
|
* There is no problem for the merging strategy to cover the previous one with the latter.
|
||||||
*
|
*
|
||||||
* @param sampleResults sample Results
|
* @param sampleResults sample Results.
|
||||||
* @return Results
|
* @return Results.
|
||||||
*/
|
*/
|
||||||
public SampleResult mergeSampleResult(List<SampleResult> sampleResults) {
|
public SampleResult mergeSampleResult(List<SampleResult> sampleResults) {
|
||||||
SampleResult mergeResult = new SampleResult();
|
SampleResult mergeResult = new SampleResult();
|
||||||
@ -128,6 +145,10 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
return mergeResult;
|
return mergeResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect application subscribe configinfos.
|
||||||
|
* @return configinfos results.
|
||||||
|
*/
|
||||||
public Map<String, Set<String>> collectApplicationSubscribeConfigInfos() {
|
public Map<String, Set<String>> collectApplicationSubscribeConfigInfos() {
|
||||||
if (allSubs == null || allSubs.isEmpty()) {
|
if (allSubs == null || allSubs.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
@ -208,6 +229,14 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add LongPollingClient.
|
||||||
|
*
|
||||||
|
* @param req HttpServletRequest.
|
||||||
|
* @param rsp HttpServletResponse.
|
||||||
|
* @param clientMd5Map clientMd5Map.
|
||||||
|
* @param probeRequestSize probeRequestSize.
|
||||||
|
*/
|
||||||
public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map,
|
public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map,
|
||||||
int probeRequestSize) {
|
int probeRequestSize) {
|
||||||
|
|
||||||
@ -216,13 +245,12 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
|
String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
|
||||||
String tag = req.getHeader("Vipserver-Tag");
|
String tag = req.getHeader("Vipserver-Tag");
|
||||||
int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
|
int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
|
||||||
/**
|
|
||||||
* 提前500ms返回响应,为避免客户端超时 @qiaoyi.dingqy 2013.10.22改动 add delay time for LoadBalance
|
// Add delay time for LoadBalance, and one response is returned 500 ms in advance to avoid client timeout.
|
||||||
*/
|
|
||||||
long timeout = Math.max(10000, Long.parseLong(str) - delayTime);
|
long timeout = Math.max(10000, Long.parseLong(str) - delayTime);
|
||||||
if (isFixedPolling()) {
|
if (isFixedPolling()) {
|
||||||
timeout = Math.max(10000, getFixedPollingInterval());
|
timeout = Math.max(10000, getFixedPollingInterval());
|
||||||
// do nothing but set fix polling timeout
|
// Do nothing but set fix polling timeout.
|
||||||
} else {
|
} else {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
List<String> changedGroups = MD5Util.compareMd5(req, rsp, clientMd5Map);
|
List<String> changedGroups = MD5Util.compareMd5(req, rsp, clientMd5Map);
|
||||||
@ -240,9 +268,11 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
String ip = RequestUtil.getRemoteIp(req);
|
String ip = RequestUtil.getRemoteIp(req);
|
||||||
// 一定要由HTTP线程调用,否则离开后容器会立即发送响应
|
|
||||||
|
// Must be called by http thread, or send response.
|
||||||
final AsyncContext asyncContext = req.startAsync();
|
final AsyncContext asyncContext = req.startAsync();
|
||||||
// AsyncContext.setTimeout()的超时时间不准,所以只能自己控制
|
|
||||||
|
// AsyncContext.setTimeout() is incorrect, Control by oneself
|
||||||
asyncContext.setTimeout(0L);
|
asyncContext.setTimeout(0L);
|
||||||
|
|
||||||
scheduler.execute(
|
scheduler.execute(
|
||||||
@ -259,7 +289,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
if (isFixedPolling()) {
|
if (isFixedPolling()) {
|
||||||
// ignore
|
// Ignore.
|
||||||
} else {
|
} else {
|
||||||
if (event instanceof LocalDataChangeEvent) {
|
if (event instanceof LocalDataChangeEvent) {
|
||||||
LocalDataChangeEvent evt = (LocalDataChangeEvent) event;
|
LocalDataChangeEvent evt = (LocalDataChangeEvent) event;
|
||||||
@ -268,7 +298,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isSupportLongPolling(HttpServletRequest req) {
|
public static boolean isSupportLongPolling(HttpServletRequest req) {
|
||||||
return null != req.getHeader(LONG_POLLING_HEADER);
|
return null != req.getHeader(LONG_POLLING_HEADER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,21 +318,17 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
scheduler.scheduleWithFixedDelay(new StatTask(), 0L, 10L, TimeUnit.SECONDS);
|
scheduler.scheduleWithFixedDelay(new StatTask(), 0L, 10L, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================
|
public static final String LONG_POLLING_HEADER = "Long-Pulling-Timeout";
|
||||||
|
|
||||||
static public final String LONG_POLLING_HEADER = "Long-Pulling-Timeout";
|
public static final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup";
|
||||||
|
|
||||||
static public final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup";
|
|
||||||
|
|
||||||
final ScheduledExecutorService scheduler;
|
final ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 长轮询订阅关系
|
* ClientLongPolling subscibers.
|
||||||
*/
|
*/
|
||||||
final Queue<ClientLongPolling> allSubs;
|
final Queue<ClientLongPolling> allSubs;
|
||||||
|
|
||||||
// =================
|
|
||||||
|
|
||||||
class DataChangeTask implements Runnable {
|
class DataChangeTask implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -312,18 +338,18 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) {
|
for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) {
|
||||||
ClientLongPolling clientSub = iter.next();
|
ClientLongPolling clientSub = iter.next();
|
||||||
if (clientSub.clientMd5Map.containsKey(groupKey)) {
|
if (clientSub.clientMd5Map.containsKey(groupKey)) {
|
||||||
// 如果beta发布且不在beta列表直接跳过
|
// If published tag is not in the beta list, then it skipped.
|
||||||
if (isBeta && !CollectionUtils.contains(betaIps, clientSub.ip)) {
|
if (isBeta && !CollectionUtils.contains(betaIps, clientSub.ip)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果tag发布且不在tag列表直接跳过
|
// If published tag is not in the tag list, then it skipped.
|
||||||
if (StringUtils.isNotBlank(tag) && !tag.equals(clientSub.tag)) {
|
if (StringUtils.isNotBlank(tag) && !tag.equals(clientSub.tag)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRetainIps().put(clientSub.ip, System.currentTimeMillis());
|
getRetainIps().put(clientSub.ip, System.currentTimeMillis());
|
||||||
iter.remove(); // 删除订阅关系
|
iter.remove(); // Delete subscribers' relationships.
|
||||||
LogUtil.clientLog
|
LogUtil.clientLog
|
||||||
.info("{}|{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - changeTime), "in-advance",
|
.info("{}|{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - changeTime), "in-advance",
|
||||||
RequestUtil
|
RequestUtil
|
||||||
@ -359,8 +385,6 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
final String tag;
|
final String tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================
|
|
||||||
|
|
||||||
class StatTask implements Runnable {
|
class StatTask implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -370,8 +394,6 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================
|
|
||||||
|
|
||||||
class ClientLongPolling implements Runnable {
|
class ClientLongPolling implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -381,9 +403,8 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
|
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
|
||||||
/**
|
|
||||||
* 删除订阅关系
|
// Delete subsciber's relations.
|
||||||
*/
|
|
||||||
allSubs.remove(ClientLongPolling.this);
|
allSubs.remove(ClientLongPolling.this);
|
||||||
|
|
||||||
if (isFixedPolling()) {
|
if (isFixedPolling()) {
|
||||||
@ -418,9 +439,8 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendResponse(List<String> changedGroups) {
|
void sendResponse(List<String> changedGroups) {
|
||||||
/**
|
|
||||||
* 取消超时任务
|
// Cancel time out task.
|
||||||
*/
|
|
||||||
if (null != asyncTimeoutFuture) {
|
if (null != asyncTimeoutFuture) {
|
||||||
asyncTimeoutFuture.cancel(false);
|
asyncTimeoutFuture.cancel(false);
|
||||||
}
|
}
|
||||||
@ -429,9 +449,8 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
|
|
||||||
void generateResponse(List<String> changedGroups) {
|
void generateResponse(List<String> changedGroups) {
|
||||||
if (null == changedGroups) {
|
if (null == changedGroups) {
|
||||||
/**
|
|
||||||
* 告诉容器发送HTTP响应
|
// Tell web container to send http response.
|
||||||
*/
|
|
||||||
asyncContext.complete();
|
asyncContext.complete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -439,17 +458,17 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
|
HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String respString = MD5Util.compareMd5ResultString(changedGroups);
|
final String respString = MD5Util.compareMd5ResultString(changedGroups);
|
||||||
|
|
||||||
// 禁用缓存
|
// Disable cache.
|
||||||
response.setHeader("Pragma", "no-cache");
|
response.setHeader("Pragma", "no-cache");
|
||||||
response.setDateHeader("Expires", 0);
|
response.setDateHeader("Expires", 0);
|
||||||
response.setHeader("Cache-Control", "no-cache,no-store");
|
response.setHeader("Cache-Control", "no-cache,no-store");
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
response.getWriter().println(respString);
|
response.getWriter().println(respString);
|
||||||
asyncContext.complete();
|
asyncContext.complete();
|
||||||
} catch (Exception se) {
|
} catch (Exception ex) {
|
||||||
pullLog.error(se.toString(), se);
|
pullLog.error(ex.toString(), ex);
|
||||||
asyncContext.complete();
|
asyncContext.complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,8 +485,6 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================
|
|
||||||
|
|
||||||
final AsyncContext asyncContext;
|
final AsyncContext asyncContext;
|
||||||
|
|
||||||
final Map<String, String> clientMd5Map;
|
final Map<String, String> clientMd5Map;
|
||||||
@ -500,15 +517,15 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String respString = MD5Util.compareMd5ResultString(changedGroups);
|
final String respString = MD5Util.compareMd5ResultString(changedGroups);
|
||||||
// 禁用缓存
|
// Disable cache.
|
||||||
response.setHeader("Pragma", "no-cache");
|
response.setHeader("Pragma", "no-cache");
|
||||||
response.setDateHeader("Expires", 0);
|
response.setDateHeader("Expires", 0);
|
||||||
response.setHeader("Cache-Control", "no-cache,no-store");
|
response.setHeader("Cache-Control", "no-cache,no-store");
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
response.getWriter().println(respString);
|
response.getWriter().println(respString);
|
||||||
} catch (Exception se) {
|
} catch (Exception ex) {
|
||||||
pullLog.error(se.toString(), se);
|
pullLog.error(ex.toString(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,5 +536,4 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
public void setRetainIps(Map<String, Long> retainIps) {
|
public void setRetainIps(Map<String, Long> retainIps) {
|
||||||
this.retainIps = retainIps;
|
this.retainIps = retainIps;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import java.util.Map;
|
|||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch
|
* SwitchService.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@ -78,6 +78,11 @@ public class SwitchService {
|
|||||||
return StringUtils.isBlank(value) ? defaultValue : value;
|
return StringUtils.isBlank(value) ? defaultValue : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load config.
|
||||||
|
*
|
||||||
|
* @param config config content string value.
|
||||||
|
*/
|
||||||
public static void load(String config) {
|
public static void load(String config) {
|
||||||
if (StringUtils.isBlank(config)) {
|
if (StringUtils.isBlank(config)) {
|
||||||
fatalLog.error("switch config is blank.");
|
fatalLog.error("switch config is blank.");
|
||||||
@ -125,5 +130,4 @@ public class SwitchService {
|
|||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user