spring cloud服务注册与发现

Eureka

分布式微服务架构中,服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,消费者 通过主动查询和被动通知的方式获取服务提供者的地址信息,消费者只需要知道当前系统发布了那些服务,而不需要知道服务具体存在于什么位置。

服务端:eureka注册中心,需要创建工程,引入服务端jar
客户端:服务提供者和消费者对于,eureka来说都是客户端,提供者和消费者向eureka注册自己的信息,消费者调用提供者的时候会通过eureka获得服务提供者的信息。客户端需要引入eureka client相关的jar,然后进行相关配置,和eureka server建立联系

微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息
Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)

每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册列表的同步

Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消 费者依然可以使用缓存中的信息找到服务提供者

搭建集群Eureka-Server

创建parent工程,引入依赖(父工程)

<dependencyManagement>
    <dependencies>
        <!--spring cloud依赖管理,引入了Spring Cloud的版本-->
        <!--用dependencyManagement管理其他dependency的版本-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在父工程下创建子模块eureka-server
在子模块中引入Eureka server的依赖

<dependencies>
    <!--Eureka server依赖-->
    <dependency>
    	<!--版本号在父工程已经控制了-->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

在父工程的pom文件中手动引入jaxb的jar,因为Jdk9之后默认没有加载该模块, EurekaServer使用到,所以需要手动导入,否则EurekaServer服务无法启动
在parent pom加入

<!--eureka server 需要引入Jaxb,开始-->
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.2.10-b140310.1920</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<!--引入Jaxb,结束-->

在子工程eureka-server中创建src/main/resources/application.yml

#eureka server服务端口
server:
  port: 8761
spring:
  application:
    name: cloud-eureka-server # 应用名称,应用名称会在Eureka中作为服务名称

    # eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Client
eureka:
  instance:
    hostname: CloudEurekaServerA  # 当前eureka实例的主机名
  client:
    service-url:
      # 配置客户端所交互的Eureka Server的地址(Eureka Server集群中每一个Server其实相对于其它Server来说都是Client)
      # 集群模式下,defaultZone应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可
      defaultZone: http://CloudEurekaServerB:8762/eureka
    register-with-eureka: true  # 集群模式下可以改成true
    fetch-registry: true # 集群模式下可以改成true
  dashboard:
    enabled: true

创建启动类

@SpringBootApplication
// 声明当前项目为Eureka服务
@EnableEurekaServer
public class EurekaServerApplicationA {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplicationA.class,args);
    }
}

创建在父工程下创建另外一个子模块EurekaServerApplicationB
修改application.yml配置

#eureka server服务端口
server:
  port: 8762
spring:
  application:
    name: cloud-eureka-server # 应用名称,应用名称会在Eureka中作为服务名称

    # eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Client
eureka:
  instance:
    hostname: CloudEurekaServerB  # 当前eureka实例的主机名
  client:
    service-url: # 配置客户端所交互的Eureka Server的地址
      defaultZone: http://CloudEurekaServerA:8761/eureka
    register-with-eureka: true
    fetch-registry: true

本地环境搭建修改hosts文件加入
127.0.0.1 CloudEurekaServerA
127.0.0.1 CloudEurekaServerB

启动两个server,浏览器进入http://localhost:8761/
在这里插入图片描述

eureka服务端的作用

服务下线
当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
服务中心接受到请求后,将该服务置为下线状态

失效剔除
Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查, 如果发现实例在在一定时间(此值由客户端设置的eureka.instance.lease-expiration-duration-in- seconds定义,默认值为90s)内没有收到心跳,则会注销此实例。

自我保护
服务提供者 —> 注册中心
定期的续约(服务提供者和注册中心通信),假如服务提供者和注册中心之间的网络有点问题,不代表 服务提供者不可用,不代表服务消费者无法访问服务提供者

如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了 网络故障,Eureka Server自动进入自我保护机制。
当处于自我保护模式时
1)不会剔除任何服务实例(可能是服务提供者和EurekaServer之间网络问题),保证了大多数服务依然可用
2)Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用,当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
3)在Eureka Server工程中通过eureka.server.enable-self-preservation配置可用关停自我保护,默认值是打开

eureka:
  server:
    enable-self-preservation: false # 关闭自我保护模式(缺省为打开)

服务提供者Eureka-Client

父工程引入依赖

<dependency> 
	<groupId>org.springframework.cloud</groupId> 
	<artifactId>spring-cloud-commons</artifactId>
</dependency>

在父工程下创建子模块service-resume并加入客户端依赖

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

配置application.yml

spring:
  application:
    name: service-resume
eureka:
  client:
    service-url:
      # 注册到集群,就把多个Eurekaserver地址使用逗号连接起来即可;注册到单实例(非集群模式),那就写一个就ok
      defaultZone: http://CloudEurekaServerA:8761/eureka,http://CloudEurekaServerB:8762/eureka
  instance:
    prefer-ip-address: true  #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
    #自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddress
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@  

创建启动类

@SpringBootApplication
//@EnableEurekaClient  // 开启Eureka Client(Eureka独有)
@EnableDiscoveryClient // 开启注册中心客户端 (通用型注解,比如注册到Eureka、Nacos等)
                       // 说明:从SpringCloud的Edgware版本开始,不加注解也ok
    public static void main(String[] args) {
        SpringApplication.run(ServiceResumeApplication.class,args);
    }

}

使用服务提供者

@Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/checkState/{userId}")
    public Integer findResumeOpenState(@PathVariable Long userId) {
        // TODO 从Eureka Server中获取我们关注的那个服务的实例信息以及接口信息
        // 1、从 Eureka Server中获取service-resume服务的实例信息(使用客户端对象做这件事)
        List<ServiceInstance> instances = discoveryClient.getInstances("service-resume");
        // 2、如果有多个实例,选择一个使用(负载均衡的过程)
        ServiceInstance serviceInstance = instances.get(0);
        // 3、从元数据信息获取host port
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        String url = "http://" + host + ":" + port + "/resume/openstate/" + userId;
        System.out.println("===============>>>从EurekaServer集群获取服务实例拼接的url:" + url);
        // 调用远程服务—> 简历微服务接口  RestTemplate  -> JdbcTempate
        // httpclient封装好多内容进行远程调用
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

向服务加入自定义数据

eureka:
  instance:
    # 自定义Eureka元数据
    metadata-map:
      cluster: cl1
      region: rn1

使用元数据

		List<ServiceInstance> instances = discoveryClient.getInstances("service-resume");
        ServiceInstance serviceInstance = instances.get(0);
        //获得元数据
        Map<String, String> metadata = serviceInstance.getMetadata();
eureka客户端的作用

服务提供者(也是Eureka客户端)要向EurekaServer注册服务,并完成服务续约等工作

服务注册(服务提供者):
1)当我们导入了eureka-client依赖坐标,配置Eureka服务注册中心地址
2)服务在启动时会向注册中心发起注册请求,携带服务元数据信息
3)Eureka注册中心会把服务的信息保存在Map中。

服务续约(提供者):
服务每隔30秒会向注册中心续约(心跳)一次(也称为报活),如果没有续约,租约在90秒后到期,然后 服务会被失效。每隔30秒的续约操作我们称之为心跳检测

#向Eureka服务中心集群注册服务 
eureka:
  instance:
    # 租约续约间隔时间,默认30秒
    lease-renewal-interval-in-seconds: 30
    # 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
    lease-expiration-duration-in-seconds: 90

获取服务列表(消费者):
每隔30秒服务会从注册中心中拉取一份服务列表,这个时间可以通过配置修改。
1)服务消费者启动时,从 EurekaServer服务列表获取只读备份,缓存到本地
2)每隔30秒,会重新获取并更新数据
3)每隔30秒的时间可以通过配置eureka.client.registry-fetch-interval-seconds修改

#向Eureka服务中心集群注册服务 
eureka:
  client:
    # 每隔多久拉取一次服务列表 
    registry-fetch-interval-seconds: 30
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值