NacosFactory (獲取工廠的統(tǒng)一入口)
// 通過(guò)配置類獲取?ConfigService
public static ConfigService createConfigService(Properties properties) throws NacosException {
????return ConfigFactory.createConfigService(properties);
}
// 通過(guò)服務(wù)端地址獲取?ConfigService
public static ConfigService createConfigService(String serverAddr) throws NacosException {?
? ?return ConfigFactory.createConfigService(serverAddr);
}
com.alibaba.nacos.api.NacosFactory 工廠類?
提供獲取ConfigFactory晌坤、NamingFactory厨诸、NamingMaintainFactory工廠的靜態(tài)方法。
設(shè)計(jì)模式:典型的 工廠模式 應(yīng)用
ConfigService (分布式配置接口)
// 根據(jù)dataid自赔、group獲取配置信息
String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException;
// 針對(duì)dataid、group增加監(jiān)聽(tīng)器
void addListener(String dataId, String group, Listener listener) throws NacosException;
// 發(fā)布配置
boolean publishConfig(String dataId, String group, String content) throws NacosException;
// 刪除配置
boolean removeConfig(String dataId, String group) throws NacosException;
// 刪除監(jiān)聽(tīng)器
void removeListener(String dataId, String group, Listener listener);
// 服務(wù)狀態(tài)
String getServerStatus();
// 關(guān)閉回收狀態(tài)
void shutDown() throws NacosException;
com.alibaba.nacos.api.config.ConfigService?
提供了一些針對(duì)配置的CRUD操作以及監(jiān)聽(tīng)配置的變更的能力
NacosConfigService (分布式配置接口實(shí)現(xiàn))
// http 代理類 根據(jù)名字就可以知道這個(gè)主要用于http協(xié)議對(duì)外交互
private final HttpAgent agent;
// long polling?
private final ClientWorker worker;
private String namespace;
// 關(guān)于配置的過(guò)濾器管理類?
private final ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
HttpAgent (http 代理類)
void start() throws NacosException;
HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues, String encoding, long readTimeoutMs) throws Exception;
HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues, String encoding, long readTimeoutMs) throws Exception;
HttpRestResult<String> httpDelete(String path, Map<String, String> headers, Map<String, String> paramValues, String encoding, long readTimeoutMs) throws Exception;
MetricsHttpAgent
public class MetricsHttpAgent implements HttpAgent {
? ? // 持有真正發(fā)起請(qǐng)求的 httpAgent
????private final HttpAgent httpAgent;
????public HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues, ????????String encode, long readTimeoutMs) throws Exception {
????????? ??Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
????????????HttpRestResult<String> result;? ??????????
????????????try {? ??????????
? ? ? ? ? ? ? ? result = httpAgent.httpGet(path, headers, paramValues, encode, readTimeoutMs);
? ??????????} catch (IOException e) {
? ??????????????throw e;
? ??????????} finally {}
? ??????????return result;
? ? }
}
ServerHttpAgent?
public class ServerHttpAgent implements HttpAgent {
? ? // 核心類:nacosRestTemplate
? ? // 和springboot RestTemplate差不多 使用http協(xié)議對(duì)外交互
?????private static final NacosRestTemplate NACOS_RESTTEMPLATE = ConfigHttpClientManager.getInstance() .getNacosRestTemplate();
? ? // 針對(duì)?nacosRestTemplate 進(jìn)行安全配置
????private SecurityProxy securityProxy;
? ? // 調(diào)度器
? ??private ScheduledExecutorService executorService;
}
ServerListManager
public class ServerListManager implements Closeable {
? ??volatile List<String> serverUrls = new ArrayList<String>();
}
維護(hù)多個(gè)服務(wù)端地址
SecurityProxy
public class SecurityProxy {
? ??private String accessToken;
? ??private long tokenTtl;
? ??private long lastRefreshTime;
? ??public boolean login(List<String> servers) {
? ??????if ((System.currentTimeMillis() - lastRefreshTime) < TimeUnit.SECONDS .toMillis(tokenTtl - tokenRefreshWindow))? ? ? ? ? {
? ? ? ? ? ??return true;
? ? ? ? }
? ??????for (String server : servers) {
? ??????????if (login(server)) {
????????????????lastRefreshTime = System.currentTimeMillis();? ??????????
? ??????????????return true;
? ? ? ? ? ? }
? ? ? ? }
? ??????return false;
? ? }
}
SecurityProxy 會(huì)調(diào)用服務(wù)端進(jìn)行登錄,獲取到的accessToken和有效時(shí)間進(jìn)行儲(chǔ)存。如果失效了會(huì)重新發(fā)起登錄伦糯。
NacosRestTemplate
public class NacosRestTemplate extends AbstractNacosRestTemplate {
? ? // 具體的http client?
? ? // httpclient有兩種實(shí)現(xiàn) 1:使用Apache HttpClient? 2:使用JDK HttpUrlConnection
? ??private final HttpClientRequest requestClient;
? ? // http調(diào)用 攔截器 可以根據(jù)需求 定制自己的攔截器
? ??private final List<HttpClientRequestInterceptor> interceptors = new ArrayList<HttpClientRequestInterceptor>();
}
HttpClientRequest?
public interface HttpClientRequest extends Closeable {
? ? // 執(zhí)行請(qǐng)求并且返回結(jié)果
????HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) throws Exception;
}
http調(diào)用統(tǒng)一接口
DefaultHttpClientRequest
public class DefaultHttpClientRequest implements HttpClientRequest {
? ? //?implementation that uses apache http client to execute streaming requests.
? ? // 使用 appche http client 實(shí)現(xiàn)
????private final CloseableHttpClient client;
}
HttpClientRequest 默認(rèn)實(shí)現(xiàn)
JdkHttpClientRequest
public class JdkHttpClientRequest implements HttpClientRequest {
? ??private HttpClientConfig httpClientConfig;
? ??public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity){
? ? ? ? ………………
? ??????HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
? ? ? ? ………………
? ? }
}
使用java? net包實(shí)現(xiàn)
InterceptingHttpClientRequest
public class InterceptingHttpClientRequest implements HttpClientRequest {
? ? // 持有httpClientRequest? 進(jìn)行包裝
? ? private final HttpClientRequest httpClientRequest;? ? private final Iterator<HttpClientRequestInterceptor> interceptors;
? ??public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity){
? ??????while (interceptors.hasNext()) {
? ??????????HttpClientRequestInterceptor nextInterceptor = interceptors.next();
? ??????????if (nextInterceptor.isIntercept(uri, httpMethod, requestHttpEntity)) {
? ??????????????return nextInterceptor.intercept();
? ? ? ? ? ? }
? ??????????return httpClientRequest.execute(uri, httpMethod, requestHttpEntity);
? ? }
}
包裝了httpClientRequest,在執(zhí)行httpClientRequest.execute 增加了攔截邏輯嗽元。
ClientWorker
public class ClientWorker implements Closeable {
? ? …………
? ? // 緩存了 配置信息 key = dataId+GroupId
? ??private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>( new HashMap<String, CacheData>());
? ? …………
}
checkConfigInfo 會(huì)根據(jù)cacheMap.size 進(jìn)行維護(hù)
ConfigService.getConfig 偽代碼
// 校驗(yàn)參數(shù) + 默認(rèn)配置
// 優(yōu)先使用本地配置??
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
if(content != null) return?content;
// 從服務(wù)端獲取配置信息 && 如果成功保存快照版本
try{
????String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs);
} …………
// 如果從服務(wù)端獲取異常 直接獲取本地快照版本返回
content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
return?content;
涉及到的模式:
1舔株、工廠模式?NacosFactory 典型的簡(jiǎn)單工廠
2、模板模式 NacosRestTemplate
3还棱、裝飾器模式?MetricsHttpAgent
以上就是針對(duì)ConfigService客戶端的分析 载慈,下一章進(jìn)行服務(wù)端分析。