您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Nacos Config中怎么配置監(jiān)聽”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
Nacos Config客戶端通過(guò)http長(zhǎng)輪詢請(qǐng)求來(lái)訂閱配置變更。Server支持兩種形式的長(zhǎng)輪訓(xùn)機(jī)制:
固定間隔輪訓(xùn)(Fixed Polling)- 每次長(zhǎng)輪詢的時(shí)間是固定的,在固定間隔輪詢時(shí)間結(jié)束后,計(jì)算期間發(fā)生的配置變更,返回group keys。
非固定間隔輪訓(xùn) - 長(zhǎng)輪詢時(shí)間不固定,一旦訂閱的配置反生變更就立即返回group key。
Fixed Polling機(jī)制性能更好,但實(shí)時(shí)性較差。Unfixed Polling機(jī)制實(shí)時(shí)性好,但http請(qǐng)求數(shù)明顯更多,性能較差。
變更訂閱請(qǐng)求在ConfigController.listener方法中處理,client通過(guò)http params傳入訂閱的所有配置keys:
@RequestMapping(value = "/listener", method = RequestMethod.POST) public void listener(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); String probeModify = request.getParameter("Listening-Configs"); if (StringUtils.isBlank(probeModify)) { throw new IllegalArgumentException("invalid probeModify"); } probeModify = URLDecoder.decode(probeModify, Constants.ENCODE); Map<String, String> clientMd5Map; try { // 解析訂閱的groupKey -> MD5列表 clientMd5Map = MD5Util.getClientMd5Map(probeModify); } catch (Throwable e) { throw new IllegalArgumentException("invalid probeModify"); } // do long-polling inner.doPollingConfig(request, response, clientMd5Map, probeModify.length()); }
ConfigServletInner.doPollingConfig通過(guò)LongPollingService.addLongPollingClient添加一個(gè)訂閱的client信息:
public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map, int probeRequestSize) { String str = req.getHeader(LongPollingService.LONG_POLLING_HEADER); String noHangUpFlag = req.getHeader(LongPollingService.LONG_POLLING_NO_HANG_UP_HEADER); String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER); String tag = req.getHeader("Vipserver-Tag"); int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500); /** * 提前500ms返回響應(yīng),為避免客戶端超時(shí) @qiaoyi.dingqy 2013.10.22改動(dòng) add delay time for LoadBalance */ long timeout = Math.max(10000, Long.parseLong(str) - delayTime); if (isFixedPolling()) { timeout = Math.max(10000, getFixedPollingInterval()); // Fixed Polling模式下,在timeout后才計(jì)算發(fā)生變化的配置項(xiàng)集合 } else { long start = System.currentTimeMillis(); List<String> changedGroups = MD5Util.compareMd5(req, rsp, clientMd5Map); if (changedGroups.size() > 0) { // Unfixed Polling模式下立即計(jì)算變更,若存在變化則返回 generateResponse(req, rsp, changedGroups); return; } else if (noHangUpFlag != null && noHangUpFlag.equalsIgnoreCase(TRUE_STR)) { return; } } String ip = RequestUtil.getRemoteIp(req); // 一定要由HTTP線程調(diào)用,否則離開后容器會(huì)立即發(fā)送響應(yīng) final AsyncContext asyncContext = req.startAsync(); // AsyncContext.setTimeout()的超時(shí)時(shí)間不準(zhǔn),所以只能自己控制 asyncContext.setTimeout(0L); scheduler.execute( new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag)); }
Fixed Polling模式的響應(yīng)在ClientLongPolling中處理:
class ClientLongPolling implements Runnable { @Override public void run() { asyncTimeoutFuture = scheduler.schedule(new Runnable() { public void run() { try { getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis()); /** * 刪除訂閱關(guān)系 */ allSubs.remove(ClientLongPolling.this); if (isFixedPolling()) { // timeout后計(jì)算變化 List<String> changedGroups = MD5Util.compareMd5( (HttpServletRequest)asyncContext.getRequest(), (HttpServletResponse)asyncContext.getResponse(), clientMd5Map); if (changedGroups.size() > 0) { sendResponse(changedGroups); } else { sendResponse(null); } } else { // unfixed polling模式達(dá)到timeout,意味著期間沒有變化 sendResponse(null); } } catch (Throwable t) { } } }, timeoutTime, TimeUnit.MILLISECONDS); allSubs.add(this); } }
Unfixed Polling模式是在LocalDataChangeEvent事件發(fā)生時(shí)計(jì)算變化并響應(yīng)的:
@Override public void onEvent(Event event) { if (isFixedPolling()) { // ignore } else { if (event instanceof LocalDataChangeEvent) { LocalDataChangeEvent evt = (LocalDataChangeEvent)event; scheduler.execute(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); } } } class DataChangeTask implements Runnable { @Override public void run() { try { ConfigService.getContentBetaMd5(groupKey); for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) { ClientLongPolling clientSub = iter.next(); if (clientSub.clientMd5Map.containsKey(groupKey)) { // 當(dāng)前client訂閱了發(fā)生變化的group key ..... clientSub.sendResponse(Arrays.asList(groupKey)); } } } catch (Throwable t) {} } }
“Nacos Config中怎么配置監(jiān)聽”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。