当前位置: 首页 > news >正文

哪里去找做的好看的网站深圳关键词优化软件

哪里去找做的好看的网站,深圳关键词优化软件,南京关键词优化软件,网站后台上传文字图片一、引言 在 Nacos 后台管理服务列表中,我们可以看到微服务列表,其中有一栏叫“健康实例数” (如下图),表示对应的客户端实例信息是否可用状态。 那Nacos服务端是怎么感知客户端的状态是否可用呢 ? 本章…
一、引言

  在 Nacos 后台管理服务列表中,我们可以看到微服务列表,其中有一栏叫“健康实例数”    (如下图),表示对应的客户端实例信息是否可用状态。

 

那Nacos服务端是怎么感知客户端的状态是否可用呢 ?

本章重点:

  • 实例心跳接口做了哪些事情 ?
  • 服务端是怎么维护不健康的实例的,怎么下线不健康实例的,做了哪些操作 ?

二、目录     

目录

一、引言

二、目录        

三、服务端实例心跳接口源码分析

四、服务端实例心跳健康检查定时任务源码分析

五、总结


   

三、服务端实例心跳接口源码分析

主线任务:实例心跳接口做了哪些事情 ?

 在客户端服务发起注册的时候 (在第二章节),会开启一个心跳任务,每5s发送一次健康心跳检查,告诉服务端我这个服务还活着。(前面已经讲过

public JsonNode sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {if (NAMING_LOGGER.isDebugEnabled()) {NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());}// 组装请求参数Map<String, String> params = new HashMap<String, String>(8);Map<String, String> bodyMap = new HashMap<String, String>(2);if (!lightBeatEnabled) {bodyMap.put("beat", JacksonUtils.toJson(beatInfo));}params.put(CommonParams.NAMESPACE_ID, namespaceId);params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());params.put(CommonParams.CLUSTER_NAME, beatInfo.getCluster());params.put("ip", beatInfo.getIp());params.put("port", String.valueOf(beatInfo.getPort()));// 发送实例心跳接口请求String result = reqApi(UtilAndComs.nacosUrlBase + "/instance/beat", params, bodyMap, HttpMethod.PUT);return JacksonUtils.toObj(result);
}

服务端接受到实例心跳接口,会现在内存注册表中找 Instance,如果找不到会重新注册。然后提交一个 clientBeatProcessor 异步任务,更改 lastBeat 属性

@CanDistro
@PutMapping("/beat")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public ObjectNode beat(HttpServletRequest request) throws Exception {// 省略部分代码// 获取请求参数namespaceId、serviceNameString namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);NamingUtils.checkServiceNameFormat(serviceName);Loggers.SRV_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}", clientBeat, serviceName);// 通过namespaceId、serviceName、ip、port、clusterName 从内存注册表当中获取对应的 Instance 实例对象Instance instance = serviceManager.getInstance(namespaceId, serviceName, clusterName, ip, port);// 如果 instance 为空,那么会重新注册if (instance == null) {if (clientBeat == null) {result.put(CommonParams.CODE, NamingResponseCode.RESOURCE_NOT_FOUND);return result;}instance = new Instance();instance.setPort(clientBeat.getPort());instance.setIp(clientBeat.getIp());instance.setWeight(clientBeat.getWeight());instance.setMetadata(clientBeat.getMetadata());instance.setClusterName(clusterName);instance.setServiceName(serviceName);instance.setInstanceId(instance.getInstanceId());instance.setEphemeral(clientBeat.isEphemeral());// 这里调用重新注册的方法serviceManager.registerInstance(namespaceId, serviceName, instance);}// 通过namespaceId、serviceName获取对应的 ServiceService service = serviceManager.getService(namespaceId, serviceName);if (service == null) {throw new NacosException(NacosException.SERVER_ERROR,"service not found: " + serviceName + "@" + namespaceId);}if (clientBeat == null) {clientBeat = new RsInfo();clientBeat.setIp(ip);clientBeat.setPort(port);clientBeat.setCluster(clusterName);}// 重点:开启异步任务,更改 lastBeat 属性service.processClientBeat(clientBeat);// 省略部分代码return result;
}

接着往下看重点 service.processClientBeat() 任务,这个方法会开启一个异步任务,异步任务的话肯定会有run 方法,那我们直接看 clientBeatProcessor 对象中的 run 方法

public void processClientBeat(final RsInfo rsInfo) {ClientBeatProcessor clientBeatProcessor = new ClientBeatProcessor();clientBeatProcessor.setService(this);clientBeatProcessor.setRsInfo(rsInfo);// 立即执行HealthCheckReactor.scheduleNow(clientBeatProcessor);
}

在异步任务当中,首先会获取当前节点下所有的临时实例,然后通过 ip+port 找到当前 instance,然后把 instance 中的 lastBeat属性更改为当前时间,并且如果 该 instance 为不健康状态,更改为健康状态

public class ClientBeatProcessor implements Runnable {public static final long CLIENT_BEAT_TIMEOUT = TimeUnit.SECONDS.toMillis(15);private RsInfo rsInfo;private Service service;@JsonIgnorepublic PushService getPushService() {return ApplicationUtils.getBean(PushService.class);}public RsInfo getRsInfo() {return rsInfo;}public void setRsInfo(RsInfo rsInfo) {this.rsInfo = rsInfo;}public Service getService() {return service;}public void setService(Service service) {this.service = service;}@Overridepublic void run() {Service service = this.service;if (Loggers.EVT_LOG.isDebugEnabled()) {Loggers.EVT_LOG.debug("[CLIENT-BEAT] processing beat: {}", rsInfo.toString());}// 本小节重点方法// 获取当前 ip、clusterNameString ip = rsInfo.getIp();String clusterName = rsInfo.getCluster();int port = rsInfo.getPort();Cluster cluster = service.getClusterMap().get(clusterName);// 获取当前 cluster 下所有的临时实例List<Instance> instances = cluster.allIPs(true);// 遍历临时实例for (Instance instance : instances) {// 通过判断ip、port,确认是否是当前 instance 的实例if (instance.getIp().equals(ip) && instance.getPort() == port) {if (Loggers.EVT_LOG.isDebugEnabled()) {Loggers.EVT_LOG.debug("[CLIENT-BEAT] refresh beat: {}", rsInfo.toString());}// 把 lastBeat属性更改为当前时间instance.setLastBeat(System.currentTimeMillis());if (!instance.isMarked()) {// 如果 instance 为不健康状态,更改为健康状态if (!instance.isHealthy()) {instance.setHealthy(true);Loggers.EVT_LOG.info("service: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: client beat ok",cluster.getService().getName(), ip, port, cluster.getName(),UtilsAndCommons.LOCALHOST_SITE);getPushService().serviceChanged(service);}}}}}
}

小结

     首先在 客户端服务发起注册的时候 (在第二章节),会开启一个心跳任务,每5s发送一次健康心跳检查,告诉服务端我这个服务还活着。(前面已经讲过)

    那么服务端接受到了 实例心跳接口的请求,会现在内存注册表中找 Instance,如果找不到会重新注册。然后提交一个 clientBeatProcessor 异步任务,在异步任务当中,首先会找到当前集群下的所有临时实例,然后通过 ip +port 找到当前instance 实例,把当前instance 中的 lastBeat属性更改为当前时间,如果 instance 为不健康状态,更改为健康状态,到此实例心跳接口就结束了。

四、服务端实例心跳健康检查定时任务源码分析

主线任务:服务端是怎么维护不健康的实例的,怎么下线不健康实例的,做了哪些操作 ?

     这块代码是在服务端 register(注册)接口当中的,之前分析过 register 注册逻辑,因为这块是分支代码,前面没细看。

   我们来看下 createEmptyService 这个方法了,里面有个异步任务,作用就是:检查有哪些客户端是不健康的状态,如果不健康就需要对它进行处理

public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {// 不知道是创建了一个什么服务createEmptyService(namespaceId, serviceName, instance.isEphemeral());// 根据namespaceId、serviceName获取 Service服务Service service = getService(namespaceId, serviceName);// service为空就抛出异常if (service == null) {throw new NacosException(NacosException.INVALID_PARAM,"service not found, namespace: " + namespaceId + ", service: " + serviceName);}// 上面都是分支代码// 主线任务:添加服务实例addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);
}

我们直接看重点代码,直接跳到开启异步任务这里。上面的代码流程:createEmptyService()-> createServiceIfAbsent()-> putServiceAndInit(service) -> service.init();

public void init() {// 开启异步延时任务 clientBeatCheckTask ,每5s执行一次HealthCheckReactor.scheduleCheck(clientBeatCheckTask);for (Map.Entry<String, Cluster> entry : clusterMap.entrySet()) {entry.getValue().setService(this);entry.getValue().init();}
}

本章重点,开启了一个 clientBeatCheckTask 异步任务。

@Override
public void run() {try {// 本章重点// 获取全部临时实例List<Instance> instances = service.allIPs(true);for (Instance instance : instances) {// 当前时间 - instance中 lastBeat属性时间  > 15sif (System.currentTimeMillis() - instance.getLastBeat() > instance.getInstanceHeartBeatTimeOut()) {if (!instance.isMarked()) {if (instance.isHealthy()) {// 如果这个 instance 实例还是健康状态,就更改为 "不健康状态"!instance.setHealthy(false);Loggers.EVT_LOG.info("{POS} {IP-DISABLED} valid: {}:{}@{}@{}, region: {}, msg: client timeout after {}, last beat: {}",instance.getIp(), instance.getPort(), instance.getClusterName(),service.getName(), UtilsAndCommons.LOCALHOST_SITE,instance.getInstanceHeartBeatTimeOut(), instance.getLastBeat());// 事件发布监听事件,通过 upd 协议发送通知getPushService().serviceChanged(service);ApplicationUtils.publishEvent(new InstanceHeartbeatTimeoutEvent(this, instance));}}}}if (!getGlobalConfig().isExpireInstance()) {return;}// 这里还是遍历 临时实例for (Instance instance : instances) {if (instance.isMarked()) {continue;}// 当前时间 - instance中 lastBeat属性时间  > 30sif (System.currentTimeMillis() - instance.getLastBeat() > instance.getIpDeleteTimeout()) {Loggers.SRV_LOG.info("[AUTO-DELETE-IP] service: {}, ip: {}", service.getName(),JacksonUtils.toJson(instance));// 直接从注册表中删除当前 instancedeleteIp(instance);}}} catch (Exception e) {Loggers.SRV_LOG.warn("Exception while processing client beat time out.", e);}}

小结:

  • 第一个循环的作用,为了筛选出不健康的 Instance 实例,并且把 Instance 中的 healthy  属性改为 false。那么怎么筛选出不健康的实例的 ?利用的就是 Instance 中的 lastBeat 属性。如果是健康的实例,那么客户端就会每5s调一次实例心跳接口,更新 lastBeat 属性为当前时间。如果是不健康的实例,那么 Instance 实例 中的 lastBeat 属性是不会变化的,一旦 lastBeat 跟当前时间比超过 15s,就会被认定为不健康的实例。
  • 第二个循环的作用,找出那些 Instance 是需要删除的,如果 lastBeat 跟当前时间比超过 30s,Nacos 会把该 Instance 从注册表当中进行删除。
五、总结

总结:

     本章讲了Nacos怎么维护整个微服务实例健康状态的流程,在客户端发起注册服务时会有心跳任务,每5s给服务端发送一次心态,服务端会把该 Instance 实例中的lastBeat 属性更新为当前时间。并且在服务端实例注册的时候,会开启心跳健康检查任务,把 lastBeat 跟当前时间比超过 15s,就会被标识为不健康的实例,把lastBeat 跟当前时间比超过 30s,Nacos 会把该 Instance 从注册表当中进行删除

最后的最后,别忘了把源码分析图补充完整: 

http://www.sczhlp.com/news/45103/

相关文章:

  • 帝国做的网站怎么上传图片网络推广公司名字
  • 怎么做网站实惠外链代发公司
  • wordpress主题 破解网络优化工程师招聘信息
  • wordpress 表单 验证码免费优化推广网站的软件
  • 专门做爬虫的网站免费网络推广100种方法
  • 平面设计公司排名前十常德seo
  • 佛山建站 网站 商城百度网址浏览大全
  • 如何查网站是织梦做的小姐关键词代发排名
  • 南昌网站seo厂家百度浏览器官网在线使用
  • 青岛做网站的公司排名最佳的资源搜索引擎
  • 南通网站搭建定制北京网站推广排名服务
  • 西安百度推广代运营北京seo诊断
  • 包头市委组织部网站作风建设年2022年最火的新闻摘抄
  • 邢台网站建设好蜘蛛黄冈seo
  • 建网站的步骤和方法seo实战密码电子版
  • 平面设计培训班哪里有重庆seo论坛
  • 心雨在线高端网站建设市场推广是做什么的
  • 网站上的广告是怎么做的宁德市属于哪个省
  • 如何给网站做优化合肥网站建设
  • dreawever如何做本地网站seo关键词排名注册价格
  • 网站banner图怎么做百度软件下载安装
  • 建设工程规划许可证在哪个网站查询杭州网络优化公司排名
  • 垂直网站建设方案长沙百度公司
  • 做外贸收费的网站edm营销
  • 织梦可以做导航网站今天的热点新闻
  • 网站建设速成班培训厦门seo排名收费
  • 如何做赚钱的网站seo教程培训
  • 网站建设和运营哪家公司好谷歌推广教程
  • WordPress 5.0.1怎麼使用朝阳区seo搜索引擎优化介绍
  • 如何通过做网站挣钱黑龙江新闻头条最新消息