Eureka 学习笔记3:EurekaHttpClient

这篇具有很好参考价值的文章主要介绍了Eureka 学习笔记3:EurekaHttpClient。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

版本 awsVersion = ‘1.11.277’

EurekaTransport 用于客户端和服务端之间进行通信,封装了以下接口的实现:

  1. ClosableResolver 接口实现
  2. TransportClientFactory 接口实现
  3. EurekaHttpClient 接口实现及其对应的 EurekaHttpClientFactory 接口实现
private static final class EurekaTransport {
    // 服务端集群解析器,用于获取服务端列表
    private ClosableResolver bootstrapResolver;

    // 底层工厂,用于创建具体通信协议的实现
    private TransportClientFactory transportClientFactory;

    // EurekaHttpClient实现,用于注册实例、取消注册、续约
    private EurekaHttpClient registrationClient;
    // 上层工厂,用于创建registrationClient
    private EurekaHttpClientFactory registrationClientFactory;

    // EurekaHttpClient实现,用于全量拉取、增量拉取服务列表
    private EurekaHttpClient queryClient;
    // 上层工厂,用于创建queryClient
    private EurekaHttpClientFactory queryClientFactory;
}

EurekaHttpClientFactory 是上层工厂接口(A top level factory interface),用于创建 EurekaHttpClientDecorator 对象(to create http clients for application/eurekaClient use)。

public interface EurekaHttpClientFactory {

    EurekaHttpClient newClient();

    void shutdown();
}

例如 DiscoveryClient # scheduleServerEndpointTask 方法:

newRegistrationClientFactory = EurekaHttpClients
    .registrationClientFactory(
        eurekaTransport.bootstrapResolver,
        eurekaTransport.transportClientFactory,
        transportConfig
    );
newRegistrationClient = newRegistrationClientFactory.newClient();

TransportClientFactory 是底层工厂接口(A low level client factory interface),用于创建 JerseyApplicationClient(Eureka 原生实现)、Jersey2ApplicationClient(Eureka 原生实现)、RestTemplateEurekaHttpClient(SpringCloud 实现)等具体协议相关的实现。底层工厂创建的对象不建议直接使用(Not advised to be used by top level consumers),需要经过上层工厂加工。

public interface TransportClientFactory {

    EurekaHttpClient newClient(EurekaEndpoint serviceUrl);

    void shutdown();
}

例如 DiscoveryClient # scheduleServerEndpointTask 方法:

TransportClientFactories transportClientFactories = 
    argsTransportClientFactories == null
        ? new Jersey1TransportClientFactories()
        : argsTransportClientFactories;
        

EurekaHttpClient 接口,用于客户端和服务端之间进行通信,封装了注册、取消注册、续约、拉取服务列表等一系列操作。

public interface EurekaHttpClient {
    // 注册实例(服务注册)
    EurekaHttpResponse<Void> register(InstanceInfo info);
    // 取消注册(服务下线)
    EurekaHttpResponse<Void> cancel(String appName, String id);
    // 发送心跳(服务续约)
    EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id, InstanceInfo info, InstanceStatus overriddenStatus);
    // 更新实例的服务状态InstanceStatus(服务状态更新)
    EurekaHttpResponse<Void> statusUpdate(String appName, String id, InstanceStatus newStatus, InstanceInfo info);
    // 删除实例的覆盖状态,overriddenStatus将变成UNKNOWN
    EurekaHttpResponse<Void> deleteStatusOverride(String appName, String id, InstanceInfo info);
    // 获取指定区域regions的注册表(全量获取)
    EurekaHttpResponse<Applications> getApplications(String... regions);
    // 获取指定区域regions的注册列表(增量获取)
    EurekaHttpResponse<Applications> getDelta(String... regions);

    EurekaHttpResponse<Applications> getVip(String vipAddress, String... regions);

    EurekaHttpResponse<Applications> getSecureVip(String secureVipAddress, String... regions);
    // 获取指定应用的实例列表
    EurekaHttpResponse<Application> getApplication(String appName);
    // 获取指定实例
    EurekaHttpResponse<InstanceInfo> getInstance(String appName, String id);
    // 获取指定实例
    EurekaHttpResponse<InstanceInfo> getInstance(String id);

    void shutdown();
}

Eureka 学习笔记3:EurekaHttpClient,eureka,eureka
HttpReplicationClient 用于服务端和服务端之间进行通信,在 EurekaHttpClient 的基础上封装了更新服务端实例状态、批量同步数据等操作。

public interface HttpReplicationClient extends EurekaHttpClient {
    // 更新服务端实例的状态
    EurekaHttpResponse<Void> statusUpdate(String asgName, ASGStatus newStatus);
    // 向其他服务端批量同步数据
    EurekaHttpResponse<ReplicationListResponse> submitBatchUpdates(ReplicationList replicationList);
}

Eureka 服务端集群节点是对等节点(peerNode),对等节点之间进行数据同步会产生循环问题和数据冲突问题。

  • 对于循环问题,Eureka 使用 Http 请求头 x-netflix-discovery-replication 表示是否是服务端同步数据操作,如果是服务端同步数据,就不会再继续向其他服务端进行同步数据。
// com.netflix.eureka.resources.InstanceResource
@PUT
public Response renewLease(
            @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,
            @QueryParam("overriddenstatus") String overriddenStatus,
            @QueryParam("status") String status,
            @QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {
    boolean isFromReplicaNode = "true".equals(isReplication);
    boolean isSuccess = registry.renew(app.getName(), id, isFromReplicaNode);
    // ...
}

// com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl
private void replicateToPeers(Action action,
                              String appName,
                              String id,
                              InstanceInfo info /* optional */,
                              InstanceStatus newStatus /* optional */,
                              boolean isReplication) {
    // ...
    // If it is a replication already,
    // do not replicate again as this will create a poison replication
    if (peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
        return;
    }
    // ...
}
  • 对于数据冲突问题,Eureka 通过比较 ReplicationInstance 类的 lastDirtyTimestamp 属性解决。lastDirtyTimestamp 是服务实例 InstanceInfo 的属性,表示服务实例最近一次变更时间。

例如 Server A 向 Server B 同步数据:

  1. 如果 Server A 的数据比 Server B 的新,Server B 返回 Status.NOT_FOUND,Server A 重新将该服务实例注册到 Server B
  2. 如果 Server A 的数据比 Server B 的旧,Server B 返回 Status.CONFLICT,要求 Server A 同步 Server B 的数据
// com.netflix.eureka.resources.InstanceResource # renewLease
private Response validateDirtyTimestamp(Long lastDirtyTimestamp,
                                            boolean isReplication) {
    InstanceInfo appInfo = registry.getInstanceByAppAndId(app.getName(), id, false);
    if (appInfo != null) {
        if ((lastDirtyTimestamp != null) 
            && (!lastDirtyTimestamp.equals(appInfo.getLastDirtyTimestamp()))) {

            Object[] args = {
                                id,
                                appInfo.getLastDirtyTimestamp(),
                                lastDirtyTimestamp,
                                isReplication
                            };

            if (lastDirtyTimestamp > appInfo.getLastDirtyTimestamp()) {
                logger.debug(
                    "Time to sync, " + 
                    "since the last dirty timestamp differs - " + 
                    "ReplicationInstance id : {}," + 
                    "Registry: {} Incoming: {} Replication: {}",
                    args);
                return Response.status(Status.NOT_FOUND).build();
            } else if (appInfo.getLastDirtyTimestamp() > lastDirtyTimestamp) {
                // In the case of replication, 
                // send the current instance info in the registry 
                // for the replicating node to sync itself with this one.
                if (isReplication) {
                    logger.debug(
                        "Time to sync, " + 
                        "since the last dirty timestamp differs - " + 
                        "ReplicationInstance id : {}," + 
                        "Registry: {} Incoming: {} Replication: {}",
                        args);
                    return Response.status(Status.CONFLICT)
                                   .entity(appInfo)
                                   .build();
                } else {
                    return Response.ok().build();
                }
            }
        } // end if ((lastDirtyTimestamp != null)
    }// end if (appInfo != null)
    return Response.ok().build();
}

抽象类 EurekaHttpClientDecorator 使用装饰者模式为 EurekaHttpClient 添加新的功能。

Eureka 学习笔记3:EurekaHttpClient,eureka,eureka

  • SessionedEurekaHttpClient 为 EurekaHttpClient 设置随机的会话时间,超过会话时间则调用 EurekaHttpClientFactory 的 newClient 方法创建一个新的 EurekaHttpClient 执行请求。随机的会话时间在配置 sessionedClientReconnectIntervalSeconds0.5-1.5 之间。

  • RetryableEurekaHttpClient 为 EurekaHttpClient 提供重试功能,默认重试 3 次。当服务端响应异常时,将服务端添加到 quarantineSet 中,并从 ClusterResolver 解析得到的服务端列表中移除 quarantineSet ,选择其他的服务端创建一个新的 EurekaHttpClient 执行请求,超过重试次数则抛出 TransportException 异常。

  • RedirectingEurekaHttpClient 为 EurekaHttpClient 提供重定向功能,默认可重定向次数 10 次。当服务端响应 302 时,获取响应中的 targetUrl,创建一个新的 EurekaHttpClient 执行请求,超过重定向次数则抛出 TransportException 异常。

  • MetricsCollectingEurekaHttpClient 为 EurekaHttpClient 提供指标收集功能,用于集成 Netflix Servo 监控组件,统计各类型请求的耗时以及不同响应码和异常的计数。文章来源地址https://www.toymoban.com/news/detail-616697.html

到了这里,关于Eureka 学习笔记3:EurekaHttpClient的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud学习笔记-Eureka的服务拉取

    假设是OrderService里面拉取Eureka的服务之一User Service 通过服务名称获取IP地址的原理如下图所示,其中由于WIndows电脑的设置,原来的IP地址被替换成为了电脑名称LAPTOPXXX,其实还是可以获取到具体的IP

    2024年02月07日
    浏览(30)
  • SpringCloud学习笔记(二)_Eureka注册中心

    一、Eureka简介 Eureka是一项基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka Server。Eureka还带有一个基于Java的客户端组件Eureka Client,它使与服务的交互更加容易。客户端还具有一个内置的负载

    2024年02月11日
    浏览(31)
  • 基于SpringCloud的微服务架构学习笔记(2)注册中心Eureka和负载均衡Ribbon

    1.7.1 远程调用的问题 地址信息获取 : 服务消费者 如何获取 服务提供者 的 地址信息 (不能每次都写死): URL:http://localhost:8081/user/\\\"+order.getUserId() 多选一 :如果有多个服务提供者,消费者如何进行选择 监测健康状态 :消费者如何获知提供者的健康状态 1.7.2 eureka原理 地址

    2024年02月13日
    浏览(28)
  • SpringCloud学习笔记(上):服务注册与发现:Eureka、Zookeeper、Consul+负载均衡服务调用:Ribbon

    SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。 springboot版本选择: git源码地址:https://github.com/spring-projects/spring-boot/releases/ SpringBoot2.0新特性:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release springcloud版本选

    2024年02月08日
    浏览(33)
  • Eureka 笔记

    创建springBoot 项目 1.步骤 导入在pom.xml中         导入        eureka-server的 jar包 2.步骤 在主方法加注解        @EnableEurekaServer 3. 步骤 在配置config 1.步骤pox.xml: 2.步骤 :加注解@EnableEurekaServer 3. 步骤 : resources/application.properties 进行配置 1.步骤 导入在pom.xml中      

    2024年02月09日
    浏览(19)
  • Springcloud笔记(2)-Eureka服务注册中心

    Eureka作为一个微服务的治理中心,它是一个服务应用,可以接收其他服务的注册,也可以发现和治理服务实例。 服务治理中心是微服务(分布式)架构中最基础和最核心的功能组件,它主要对各个服务实例进行管理,包括 服务注册和服务发现 等 本文参考:springcloud教程 --

    2024年02月05日
    浏览(32)
  • SpringCloud&Eureka学习教程

    SpringCloud是目前国内使用最广泛的微服务框架,集成了各种微服务功能组件,并基于Springboot实现了这些组件的自动装配,从而提供了良好的开箱即用体验 官网地址:https://spring.io/projects/spring-cloud 服务拆分注意事项: 单一职责:不同微服务,不要重复开发相同业务 数据独立:

    2024年02月03日
    浏览(31)
  • 微服务学习 Eureka注册中心

    服务调用时候出现问题,当服务者很多时候,比如不同的端口。消费者如何找到服务者的地址?又如何判断服务者是否健康。 Eureka基本原理: 总结:如果有多个服务提供者,消费者该如何选择? 搭建Eureka注册中心: 1.引入依赖 2.编写启动类,添加@EnableEurekaServer注解 这里在启动

    2024年04月16日
    浏览(23)
  • springCloud学习一之Eureka

    上面例子中如果service-url为空,且register-with-eureka,fetch-registry为true,则会报错,Cannot execute request on any known server,因为server同时也是一个client,他会尝试注册自己,所以要有一个注册中心url去注册。 Netflix开源的组件。包括server和client两部分。 SpringCloud Eureka创建单机启动:

    2024年04月16日
    浏览(32)
  • SpringCloud之Eureka的学习【详细】

    目录 服务架构演变 单体架构 分布式架构 分布式架构需要考虑的问题 微服务 架构比较 微服务技术对比 服务拆分注意事项 案例 服务远程调用 RestTemplate Eureka注册中心 RestTemplate存在的问题 服务调用考虑的问题 Eureka的作用 搭建EurekaServer 服务注册 服务发现 Ribbon负载均衡 负载

    2024年02月06日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包