Eureka中的心跳机制

前言

        从以前的单体架构到现在的微服务分布式架构, 随着架构的演变, 所需要的技术越来越多, 要求的也越来越多了, 今天来谈一下微服务领域中的心跳机制
        在微服务领域,心跳机制很常见了, 比如Eureka. Nacos中的客户端和服务端的服务续约, Redis的主从复制等
        本文主要来谈一下Eureka中的服务续约机制来展示心跳机制实现
        对于Eureka, 会涉及到两个端, 一个客户端, 一个服务端. 客户端就相当于我们的微服务: 订单服务, 商品服务等. 而服务端就是指Eureka注册中心的这个服务, 而保持续约就是客户端在相隔一段时间内向服务端发送一次心跳, 告诉Eureka一个自己的状态是存活的
 

主要知识点
  • 谁发送的心跳请求?
  • 多久发送一次?
  • 如何发送?
  • 如何接收心跳请求?
  • 接收了之后做了什么?
     

谁发送的心跳请求

Eureka采用的是客户端向服务端发送心跳请求, 如下图:
Eureka发送心跳请求
上图中左边三个客户端都已经注册到了Eureka服务端上, 之后每个微服务都会自己单独发送心跳请求到注册中心
 

多久发送一次

        客户端进行初始化时, 会调度一些定时任务, Eureka初始化了发送了心跳请求的线程池heartbeatExecutor, 用来创建发送心跳的线程HeartbeatThread, 如下图:
在这里插入图片描述
线程池有核心参数 :

  1. maximumPoolSize:最大线程数, 线程池允许创建的最大线程数
  2. corePoolSize:核心线程数。当提交一个任务到线程池时,线程池会创建一个线程来执行任务, 即使其他空闲的核心线程能够执行新任务也会创建线程, 等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的 prestartAllCoreThreads() 方法, 则线程池会提前创建并启动所有基本线程
  3. keepAliveTime:线程活动保持时间, 线程池的工作线程空闲后, 保持存活的时间
  4. runnableTaskQueue:任务队列, 用于保存等待执行的任务的阻塞队列。有四种:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue
     
    利用此线程池来执行定时调度任务, 在定时任务开始后, 延迟30s开始执行发送心跳请求, 然后每隔30s发送一次心跳请求
     

如何发送心跳请求

        HeartbeatThread类实现了Runnable类的run方法, 这个里面有执行发送心跳的具体逻辑
在这里插入图片描述
进入 renew 方法中 ,核心逻辑就这一行

eurekaTransport.registrationClient.sendHeartBeat(
    instanceInfo.getAppName(), 
    instanceInfo.getId(), 
    instanceInfo, 
    null);

调用 EurekaHttpClient 的 sentHeartBeat 方法, 将实例信息发送给注册中心。

拼接的请求URL示例如下:

http://localhost:8080/v2/apps/order/i-000000-1

而且这个请求是个PUT请求。
 

如何接收心跳请求的

        从客户端发起心跳请求之后, 服务端就要接收这个请求了
负责接受请求的类为 ApplicationsResource,它相当于 MVC 中的Controller。
        根据请求的 URL 格式和请求方式(PUT),我们可以找到服务端的方法为InstanceResource.renewLease()。

ApplicationsResource->ApplicationResource->InstanceResource

 

接收后做了什么

        里面的核心代码就是 renew 方法, 将实例的一个字段给更新了, 这个字段叫做 ‘lastupdateTimestamp’, 也就是最后更新时间。

public void renew() {
    lastUpdateTimestamp = System.currentTimeMillis() + duration;
}

 
在这里插入图片描述
        这个实例其实是从服务端注册表 registry 中拿到的, 它是一个ConcurrentHashMap, 实例名当做 key, 来获取value(实例), 也就是说实例信息是存在内存中的
        拿到的是一个 Lease 实例, 数据结构是这样的:Lease, 它有一个 volatile 修饰的字段 lastUpdateTimestamp。通过更新这个字段来记录实例信息确实存活着在, 而且刚刚还跟 Eureka 通信了。
        那么有了这个字段更新, Eureka Server 自身还会有个定时任务, 去检查服务实例的最后更新时间, 如果过期了, 则认为该实例状态异常, 需要进行服务下线。
 
本文到此结束

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值