框架篇-springcloud.erueka

框架篇-springcloud.erueka

定义电脑

​ 微服务化后,服务将越来越多,已经云化动态分配IP,传统的手工配置 比如ngnix的ip配置将会变得越来越不满足要求,于是需要一个组件去管理服务,eureka就是来干这个的。

​ 1.eureka作用是服务注册与发现中心,在springcloud中的作用可以和spring的IOC容器作为对比,是服务管理的基础组件

​ 2.而管理服务需要几个基本能力:

​ a.服务注册表(服务端存储服务数据的地方 可以理解为表) 存数据的地方

​ b.服务发现 服务的注册与注销

​ c.健康监测 服务的续约

​ eureka就是在实现这三个能力进行开发

​ 其实感觉大部分的组件都只是工具级别 都是可以自定义实现的

这里写图片描述

使用电脑

​ springcloud的组件用起来都比较简单,基本上就是三步走

​ a、导包

​ b、加注解

​ c、改配置

​ 对于改配置这一点,是觉得springcloud还需要优化的地方,springboot将配置项变少,springcloud又回到配置了

服务端

​ a、导包

<dependency>
    <!--eureka服务端-->
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

​ b、注解

@SpringBootApplication
@EnableEurekaServer//eureka服务端
public class EurekaServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class, args);
    }
}

​ c、配置application.yml

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    #是否向服务注册中心注册自己
    registerWithEureka: false
    #是否检索服务
    fetchRegistry: false
    serviceUrl:
      #eureka服务端的位置  有需要用户名密码的形式 需要导Security包
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

客户端

​ a、导包

        <!--eureka客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--健康检查客户端包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

​ b、注解

@EnableDiscoveryClient
//@EnableEurekaClient//仅用于eureka作为服务治理中心

@Autowired
private DiscoveryClient discoveryClient;//可以通过这个获取服务实例信息

​ c、配置application.yml

eureka:
  #eureka服务端地址
  serviceUrl:
     defaultZone: http://localhost:8761/eureka/
  #注册的实例信息 用于页面显示
  instance:
      instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
  #开启健康检查
  client:
        healthcheck:
          enabled: true

服务端高可用方案

​ 注册信息和更新会被复制到其他Eureka 节点,来自任何区域的客户端科可以查找到注册中心信息,每30s发生一次复制来定位他们的服务,并进行远程调用 注册是服务端会通信

拆解电脑

​ 如上所见 使用起来还是蛮简单的 现在我们来分析源码

客户端源码

当我们启动服务时,会发现服务端会出现一段日志,这是因为客户端调用了请求

客户端日志

com.netflix.discovery.DiscoveryClient : DiscoveryClient_AIS/ais:8081: registering service…

//….

com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server

服务端日志

c.n.e.registry.AbstractInstanceRegistry : Registered instance AIS/ais:8081 with status UP (replication=false)

根据这个日志我们找到这个类

package com.netflix.discovery;

@Singleton//单例
public class DiscoveryClient implements EurekaClient

a、服务注册 注销->客户端启动时发送请求到服务端

我们看下客户端打这个日志的地方–>register()方法 其实就是发送了一个请求到服务端而已

boolean register();//服务注册 发送http请求到服务端
void getAndStoreFullRegistry();//本地服务缓存 发送http请求到服务端 然后存到本地

​ b、心跳 也可以叫续约->客户端开启定时任务发送请求到服务端

boolean renew();//调用register()注册方法 发送注册请求

​ 定时任务那里来的

@Inject
DiscoveryClient(..){
  //...
  //构造函数里面做了很多初始化 其中就包括定时任务
  this.initScheduledTasks();

}

private void initScheduledTasks() {
        int renewalIntervalInSecs;
        int expBackOffBound;
        //是否服务获取 也就是eureka.client.fetch-registry=true 默认是ture
        if (this.clientConfig.shouldFetchRegistry()) {
            //定时任务 服务获取 默认每30s获取服务端服务
            this.scheduler.schedule(new TimedSupervisorTask("cacheRefresh", this.scheduler, this.cacheRefreshExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new DiscoveryClient.CacheRefreshThread()), (long)renewalIntervalInSecs, TimeUnit.SECONDS);
        }

        //是否注册服务
        if (this.clientConfig.shouldRegisterWithEureka()) {
            renewalIntervalInSecs = this.instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
            expBackOffBound = this.clientConfig.getHeartbeatExecutorExponentialBackOffBound();
            logger.info("Starting heartbeat executor: renew interval is: {}", renewalIntervalInSecs);
            //定时任务 心跳检测HeartbeatThread 频率配置同上
            this.scheduler.schedule(new TimedSupervisorTask("heartbeat", this.scheduler, this.heartbeatExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new DiscoveryClient.HeartbeatThread()), (long)renewalIntervalInSecs, TimeUnit.SECONDS);

            this.instanceInfoReplicator = new InstanceInfoReplicator(this, this.instanceInfo, this.clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2);
            //...
            if (this.clientConfig.shouldOnDemandUpdateStatusChange()) {
                this.applicationInfoManager.registerStatusChangeListener(this.statusChangeListener);
            }

           //服务注册线程 类的是runnable类  run方法中会调用register方法
   this.instanceInfoReplicator.start(this.clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
        } else {
            logger.info("Not registering with Eureka server per configuration");
        }

    }

//心跳检测线程
private class HeartbeatThread implements Runnable {
        private HeartbeatThread() {
        }

        public void run() {
            // 续约成功 就更新下最后心跳的时间
            if (DiscoveryClient.this.renew()) {
                DiscoveryClient.this.lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis();
            }

        }
    }

服务端源码

服务端就是提供接口 可以跟踪到com.netflix.eureka.resources包下的内容 大体相同 以注册服务为例

就是ApplicationResource下的addInstance方法

@POST
@Consumes({"application/json", "application/xml"})
public Response addInstance(InstanceInfo info, @HeaderParam("x-netflix-discovery-replication") String isReplication) {
    //注册
  this.registry.register(info, "true".equals(isReplication));
            return Response.status(204).build();
}

public void register(InstanceInfo info, boolean isReplication) {
        int leaseDuration = 90;
        if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
            leaseDuration = info.getLeaseInfo().getDurationInSecs();
        }
        //调用父类的注册方法
        super.register(info, leaseDuration, isReplication);
        //同步到其他集群的服务端
        this.replicateToPeers(PeerAwareInstanceRegistryImpl.Action.Register, info.getAppName(), info.getId(), info, (InstanceStatus)null, isReplication);
    }

这里写图片描述

拓展电脑

配置

​ 配置项主要在于配置定时任务的频率 是否集群等

手写实现

比较电脑

erueka vs zk

服务治理目前比较流行的就是这两种了

erueka vs nignx 客户端vs 服务端 服务发现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值