EventDispatcher.fireEvent(new ConfigDataChangeEvent(true, dataId, group, tenant, time.getTime()));

跟着代码一步步往下看:

public class EventDispatcher {/*** add event listener*/static public void addEventListener(AbstractEventListener listener) {for (Class<? extends Event> type : listener.interest()) {getEntry(type).listeners.addIfAbsent(listener);}}/*** fire event, notify listeners.*/static public void fireEvent(Event event) {if (null == event) {throw new IllegalArgumentException();}for (AbstractEventListener listener : getEntry(event.getClass()).listeners) {try {listener.onEvent(event);} catch (Exception e) {log.error(e.toString(), e);}}}

这个getEntry(event.getClass()).listeners需要重点看下

/*** get event listener for eventType. Add Entry if not exist.*/static Entry getEntry(Class<? extends Event> eventType) {for (; ; ) {for (Entry entry : LISTENER_HUB) {if (entry.eventType == eventType) {return entry;}}Entry tmp = new Entry(eventType);/***  false means already exists*/if (LISTENER_HUB.addIfAbsent(tmp)) {return tmp;}}}

    static final CopyOnWriteArrayList<Entry> LISTENER_HUB = new CopyOnWriteArrayList<Entry>();

这个LISTENER_HUB 会预先把几个相应的Entry 加载进去(这个我们后面分析),然后就开始onEvent,通知Listeners了;

@Service
public class AsyncNotifyService extends AbstractEventListener {@Overridepublic List<Class<? extends Event>> interest() {List<Class<? extends Event>> types = new ArrayList<Class<? extends Event>>();// 触发配置变更同步通知types.add(ConfigDataChangeEvent.class);return types;}@Overridepublic void onEvent(Event event) {// 并发产生 ConfigDataChangeEventif (event instanceof ConfigDataChangeEvent) {ConfigDataChangeEvent evt = (ConfigDataChangeEvent)event;long dumpTs = evt.lastModifiedTs;String dataId = evt.dataId;String group = evt.group;String tenant = evt.tenant;String tag = evt.tag;           // listen的服务地址List<?> ipList = serverListService.getServerList();// 其实这里任何类型队列都可以 Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();for (int i = 0; i < ipList.size(); i++) { queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, (String)ipList.get(i), evt.isBeta));}    EXCUTOR.execute(new AsyncTask(httpclient, queue));}}

把这个配置关联的服务一个个通知下,建议大家可以结合观察者模式来理解这个;

    private static final Executor EXCUTOR = Executors.newScheduledThreadPool(100, new NotifyThreadFactory());

然后把这个通知服务扔到县线程池,放到另外一个线程中去执行通知任务;

 class AsyncTask implements Runnable {public AsyncTask(CloseableHttpAsyncClient httpclient, Queue<NotifySingleTask> queue) {this.httpclient = httpclient;this.queue = queue;}@Overridepublic void run() { executeAsyncInvoke();
}private void executeAsyncInvoke() {while (!queue.isEmpty()) {NotifySingleTask task = queue.poll();String targetIp = task.getTargetIP();if (serverListService.getServerList().contains(targetIp)) {// 启动健康检查且有不监控的ip则直接把放到通知队列,否则通知if (serverListService.isHealthCheck()&& ServerListService.getServerListUnhealth().contains(targetIp)) {// target ip 不健康,则放入通知列表中ConfigTraceService.logNotifyEvent(task.getDataId(), task.getGroup(), task.getTenant(), null,task.getLastModified(),LOCAL_IP, ConfigTraceService.NOTIFY_EVENT_UNHEALTH, 0, task.target);// get delay time and set fail count to the taskint delay = getDelayTime(task);Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();queue.add(task);AsyncTask asyncTask = new AsyncTask(httpclient, queue);((ScheduledThreadPoolExecutor)EXCUTOR).schedule(asyncTask, delay, TimeUnit.MILLISECONDS);} else {HttpGet request = new HttpGet(task.url);request.setHeader(NotifyService.NOTIFY_HEADER_LAST_MODIFIED,String.valueOf(task.getLastModified()));request.setHeader(NotifyService.NOTIFY_HEADER_OP_HANDLE_IP, LOCAL_IP);if (task.isBeta) {request.setHeader("isBeta", "true");}httpclient.execute(request, new AyscNotifyCallBack(httpclient, task));}}}}private Queue<NotifySingleTask> queue;private CloseableHttpAsyncClient httpclient;}

上面这段代码明天再慢慢解析吧,加油!

转载于:https://www.cnblogs.com/longxok/p/11011722.html

Nacos深入浅出(三)相关推荐

  1. Nacos系列:Nacos的三种部署模式

    三种部署模式 Nacos支持三种部署模式 1.单机模式:可用于测试和单机使用,生产环境切忌使用单机模式(满足不了高可用) 2.集群模式:可用于生产环境,确保高可用 3.多集群模式:可用于多数据中心场景 ...

  2. Nacos支持三种部署模式

    Nacos支持三种部署模式 Nacos支持三种部署模式 单机模式 - 用于测试和单机试用. 集群模式 - 用于生产环境,确保高可用. 多集群模式 - 用于多数据中心场景. 单机模式下运行Nacos L ...

  3. Nacos系列:Nacos的三种部署模式 1

    三种部署模式 Nacos支持三种部署模式 1.单机模式:可用于测试和单机使用,生产环境切忌使用单机模式(满足不了高可用) 2.集群模式:可用于生产环境,确保高可用 3.多集群模式:可用于多数据中心场景 ...

  4. Nacos(三)之架构

    转载自  Nacos 架构 基本架构及概念 服务 (Service) 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调 ...

  5. java xml 推模式 拉模式_Alibaba Sentinel规则持久化-推模式-手把手教程(基于Nacos)...

    点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.推模式架构图 TIPS 图片来自官方. 引用自 https://github.com/alibab ...

  6. nacos 怎么配置 里的配置ip_Nacos部署--配置中心

    Nacos 0.8部署文档 Nacos支持三种类型的部署模式: 独立模式 - 在DEV或TEST环境中使用. 群集模式 - 用于生产环境以确保高可用性. 多群集模式 - 在复杂的生产模式下部署多群集模 ...

  7. Nacos 集群部署模式最佳实践

    作者 | kiritomoe 来源 | https://mp.weixin.qq.com/s/sSTY5BivxrH4wR2-dNMkzw 1 前言 Nacos 支持两种部署模式:单机模式和集群模式. ...

  8. Spring Cloud Alibaba基础教程:Nacos的集群部署

    点击蓝色"程序猿DD"关注我哟 <Spring Cloud Alibaba基础教程>连载中,关注我一起学习!前情回顾: <使用Nacos实现服务注册与发现> ...

  9. Nacos服务的注册,服务的调用,修改配置文件自动刷新和命名空间

    一.nacos配置中心的配置 使用nacos作为配置中心,不需要再到远端仓库拉取配置文件. 详细的nacos控制台配置参见官方链接 二.服务的注册 创建项目并引入依赖 <!--引入nacos c ...

最新文章

  1. 7、vue中将token存到cookie
  2. ZooKeeper和CAP理论及一致性原则
  3. linux oracle 用户创建,LINUX下Oracle数据库用户创建方法详解
  4. firefox是什么浏览器_我为什么不使用Firefox(火狐)浏览器
  5. DELPHI的DBGRID有两个难点
  6. 开放网络的承诺:它真的做到了吗?
  7. 实现 通过数据库里一个字段值相等 则把 他合为一条数据
  8. python中if嵌套语句的作用_讲解Python中if语句的嵌套用法
  9. 读书笔记_中国期货市场量化交易(李尉)05
  10. CVE-2020-10148: SolarWinds 远程代码执行漏洞通告
  11. CSS单行文本溢出显示省略号(…)
  12. python数字右对齐_python怎么让数字右对齐?
  13. linux pulseaudio模块关系,ALSA和PulseAudio有何关系?
  14. 我太机智了……30条关于数据行业内涵笑话漫画
  15. oracle百度坐标系火星转换,标准坐标系与火星坐标系(高德)百度坐标系之间互转...
  16. 微信小程序成语小秀才,成语接龙超详细搭建教程
  17. 百度浏览器的编程html,百度来路浏览器劫持代码(替换浏览器正在浏览页面)...
  18. 使用 Kitten 编程猫绘制一个魔方
  19. windows系统的定时任务
  20. Eclipse开发必备干货分享

热门文章

  1. HLSL的一些常见渲染特效的实现
  2. 我也来说说Dynamic
  3. 2006世界杯赛程表,不能错过:)
  4. 使用php蓝天采集器抓取今日头条ajax的文章内容
  5. 关于linux LVM
  6. Oracle10g数据库归档与非归档模式下的备份与恢复
  7. 5.VMware View 4.6安装与部署-安装view agent与模版
  8. 采购杀毒软件,你说话能算数么?
  9. 体验一下Oracle 11g物理Active Data Guard实时查询(Real-time query)
  10. android Formatter 的使用