温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Nacos Config中怎么配置监听

发布时间:2021-11-17 11:42:17 来源:亿速云 阅读:819 作者:iii 栏目:大数据

本篇内容介绍了“Nacos Config中怎么配置监听”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Nacos Config客户端通过http长轮询请求来订阅配置变更。Server支持两种形式的长轮训机制:

  • 固定间隔轮训(Fixed Polling)- 每次长轮询的时间是固定的,在固定间隔轮询时间结束后,计算期间发生的配置变更,返回group keys。

  • 非固定间隔轮训 - 长轮询时间不固定,一旦订阅的配置反生变更就立即返回group key。

Fixed Polling机制性能更好,但实时性较差。Unfixed Polling机制实时性好,但http请求数明显更多,性能较差。

变更订阅请求在ConfigController.listener方法中处理,client通过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通过LongPollingService.addLongPollingClient添加一个订阅的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返回响应,为避免客户端超时 @qiaoyi.dingqy 2013.10.22改动  add delay time for LoadBalance      */     long timeout = Math.max(10000, Long.parseLong(str) - delayTime);     if (isFixedPolling()) {         timeout = Math.max(10000, getFixedPollingInterval());         // Fixed Polling模式下,在timeout后才计算发生变化的配置项集合     } else {         long start = System.currentTimeMillis();         List<String> changedGroups = MD5Util.compareMd5(req, rsp, clientMd5Map);         if (changedGroups.size() > 0) {             // Unfixed Polling模式下立即计算变更,若存在变化则返回             generateResponse(req, rsp, changedGroups);             return;         } else if (noHangUpFlag != null && noHangUpFlag.equalsIgnoreCase(TRUE_STR)) {             return;         }     }     String ip = RequestUtil.getRemoteIp(req);     // 一定要由HTTP线程调用,否则离开后容器会立即发送响应     final AsyncContext asyncContext = req.startAsync();     // AsyncContext.setTimeout()的超时时间不准,所以只能自己控制     asyncContext.setTimeout(0L);     scheduler.execute(         new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag)); }

Fixed Polling模式的响应在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());                     /**                      * 删除订阅关系                      */                     allSubs.remove(ClientLongPolling.this);                     if (isFixedPolling()) {                         // timeout后计算变化                         List<String> changedGroups = MD5Util.compareMd5(                             (HttpServletRequest)asyncContext.getRequest(),                             (HttpServletResponse)asyncContext.getResponse(), clientMd5Map);                         if (changedGroups.size() > 0) {                             sendResponse(changedGroups);                         } else {                             sendResponse(null);                         }                     } else {                         // unfixed polling模式达到timeout,意味着期间没有变化                         sendResponse(null);                     }                 } catch (Throwable t) {                 }             }         }, timeoutTime, TimeUnit.MILLISECONDS);         allSubs.add(this);     } }

Unfixed Polling模式是在LocalDataChangeEvent事件发生时计算变化并响应的:

@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)) {                     // 当前client订阅了发生变化的group key                     .....                     clientSub.sendResponse(Arrays.asList(groupKey));                 }             }         } catch (Throwable t) {}     } }

“Nacos Config中怎么配置监听”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI