SpringCloud03-Eureka注册中心

一、Eureka 介绍

注册中心的作用一句话概括就是存放和调度服务,实现服务和注册中心,服务和服务之间的相互通信。注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。

Eureka 是 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如 Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。

Eureka 由两个组件组成:Eureka 服务器和 Eureka 客户端。

  • Eureka 服务器用作服务注册服务器。
  • Eureka 客户端是一个 java 客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix 在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

Eureka 的基本架构:
在这里插入图片描述
从上图可以看出 Eureka 由三个角色组成:
1、Eureka Server
Eureka Server 作为一个独立的部署单元,以 REST API 的形式为服务实例提供了注册、管理和查询等操作。同时,Eureka Server 也为我们提供了可视化的监控页面,可以直观地看到各个 Eureka Server 当前的运行状态和所有已注册服务的情况。
2、Service Provider
服务提供方
将自身服务注册到 Eureka,从而使服务消费方能够找到
3、Service Consumer
服务消费方
从 Eureka 获取注册服务列表,从而能够消费服务

二、创建一个EurekaServer 项目

在这里插入图片描述
在这里插入图片描述
选择依赖
在这里插入图片描述
继续下一步即可。

2.1 程序实现

1、在启动类上添加注解

@SpringBootApplication
@EnableEurekaServer //声明这是一个EurekaServer
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

2、编写 application.yml 配置文件

server:
  port: 10114
spring:
  application:
#    名字随便取 应用名称,会在 Eureka 中显示
    name: user-eureka
eureka:
  client:
    register-with-eureka: false  # 是否注册自己的信息到 EurekaServer,默认是  true
    fetch-registry: false        # 是否拉取其它服务的信息,默认是 true
    service-url:
      # EurekaServer 的地址,现在是自己的地址,如果是集群,需要加上其它 Server 的地址。
      defaultZone: http://127.0.0.1:${server.port}/eureka

3、测试
启动服务,并访问:http://127.0.0.1:10114
在这里插入图片描述

三、注册 user-service 到 Eureka

要将服务注册到 Eureka,那么需要在服务上添加 Eureka 客户端的依赖。这样 Eureka 的
客户端会自动将服务注册到注册中心中。
1、添加 SpringCloud 的依赖

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

<!-- SpringCloud 的依赖 -->
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、在启动类中开启 Eureka 客户端(添加注解)

@SpringBootApplication
@EnableDiscoveryClient //开启 Eureka 客户端
@MapperScan("com.zsn.cloud.dao")
public class CloudServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(CloudServiceApplication.class, args);
    }

}

3、修改 application.yml

server:
    port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 10
  application:
    name: user-service # 应用名称
mybatis:
  type-aliases-package: com.zsn.cloud.pojo
eureka:
  client:
      service-url: #EurekaServer 地址
        defaultZone: http://127.0.0.1:10114/eureka 
  instance:
      prefer-ip-address: true # 当调用 getHostname 获取实例的hostname 时,返回ip 而不是 host 名称
      ip-address: 127.0.0.1 # 指定自己的 ip 信息,不指定的话会自己寻找
   

4、测试
启动 EurekaServer,然后启动 user-service。重新打开 http://127.0.0.1:10114
在这里插入图片描述

服务提供者

服务提供者要向 EurekaServer 注册服务,并且完成服务续约等工作。
1、服务注册
服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-erueka=true 参数是否正确,事实上默认就是 true。如果值确实为 true,则会向 EurekaServer 发起一个 Rest请求,并携带自己的元数据信息,Eureka Server 会把这些信息保存到一个双层 Map 结构中。第一层 Map 的 Key 就是服务名称,第二层 Map 的 key 是服务的实例 id。
2、服务续约
在注册服务完成以后,服务提供者会维持一个心跳(定时向 EurekaServer 发起 Rest 请求),告诉 EurekaServer:“我还活着”。这个我们称为服务的续约(renew)
有两个重要参数可以修改服务续约的行为:

eureka:
 instance:
  #服务失效时间,默认值 90 秒
  lease-expiration-duration-in-seconds: 90
  #服务续约(renew)的间隔,默认为 30 秒
  lease-renewal-interval-in-seconds: 30

也就是说,默认情况下每个 30 秒服务会向注册中心发送一次心跳,证明自己还活着。
如果超过 90 秒没有发送心跳,EurekaServer 就会认为该服务宕机,会从服务列表中移除

四、消费者从 Eureka 中获取服务

前面将服务发布到了 Eureka 中,下面修改 consumer 工程,让其从 Eureka 中获取服务。
要从 Eureka 中获取服务就需要引用 Eureka 的客户端。
1、添加 SpringCloud 的依赖

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

<!-- SpringCloud 的依赖 -->
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、修改 application.yml

server:
  port: 8081
spring:
  application:
    name: customer # 应用名称
eureka:
  client:
    service-url: # EurekaServer 地址
      defaultZone: http://127.0.0.1:10114/eureka #,http://127.0.0.1:11114/eureka
  instance:
    prefer-ip-address: true # 当其它服务获取地址时提供 ip 而不是 hostname
    ip-address: 127.0.0.1

3、修改代码,用 DiscoveryClient 对象的方法,根据服务的名称来获取服务的实例

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate template;
    @Autowired
    private DiscoveryClient discoveryClient;

    //在 SpringBoot 集成了 Eureka 后,转换成 xml 的优先级要高于 json,
    //所以如果需要 json 格式的数据,就需要加入下面的代码
    @RequestMapping(value="/detail/{id}" ,produces= MediaType.APPLICATION_JSON_VALUE)
    public User consumer(@PathVariable("id") String id){
//        return template.getForObject("http://127.0.0.1:8080/user/"+id, User.class);

        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        // 因为只有一个 UserService,因此我们直接 get(0)获取
        ServiceInstance instance = instances.get(0);
        //获取服务的 ip 地址和端口号
        String serviceurl ="http://"+instance.getHost()+":"+instance.getPort()+"/user/"+id;
        return template.getForObject(serviceurl, User.class);
    }
    }

4、测试
启动 Eureka,user-service,consumer。然后访问 consumer 可以得到如下结果:
在这里插入图片描述

4.2 服务消费者

获取服务列表,
当服务消费者启动是,会检测 eureka.client.fetch-registry=true 参数的值,如果为 true,则会从 Eureka Server 服务的列表只读备份,然后缓存在本地。并且每隔 30 秒会重新获取并更新数据。
我们可以通过下面的参数来修改:

eureka:
 client:
  #在开发环境下,可以修改为 5 秒获取一次。生产环境下一般不用修改
  registry-fetch-interval-seconds: 5

4.5 失效剔除和自我保护

1、失效剔除
有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server 需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔 60 秒对所有失效的服务(超过 90 秒未响应的服务)进行剔除。
可以通过 eureka.server.eviction-interval-timer-in-ms 参数对其进行修改,单位是毫秒,生产环境不要修改。但是这个时长会对我们开发带来极大的不变,对服务进行了重启,隔了60 秒 Eureka 才会反应过来。所以开发阶段可以适当调整,比如 5 秒
2、自我保护
我们关停一个服务,就会在 Eureka 面板看到一条警告
在这里插入图片描述
这是触发了 Eureka 的自我保护机制。当一个服务未按时进行心跳续约时,Eureka 会统计最近 15 分钟心跳失败的服务实例的比例是否超过了 85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka 就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。
但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式

eureka:
 server:
  enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
  eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为 60*1000ms)

4.6 搭建 Eureka 集群

Eureka Server 即服务的注册中心,在上面的案例中,只有一个EurekaServer,如果这个Server 挂掉,那么就会导致整个系统不可用。所以 EurekaServer 在设计时就设计成为可以部署集群,形成高可用的注册中心。
多个 Eureka Server 之间也会互相注册为服务,当服务提供者注册到 Eureka Server 集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到 Eureka Server 集群中的任意一个节点,都可以获取到完整的服务列表信息。

示例:搭建高可用的 EurekaServer。搭建包含两个 EurekaServer 的集群,端口分别为:
10114 和 11114
集群配置:
1、修改原来的 EurekaServer 配置

server:
  port: 10114
spring:
  application:
# 名字随便取 应用名称,会在 Eureka 中显示
    name: user-eureka
eureka:
  client:
    register-with-eureka: false  # 是否注册自己的信息到 EurekaServer,默认是  true
    fetch-registry: false        # 是否拉取其它服务的信息,默认是 true
    service-url:
      #配置成其他服务的地址,不是自己的地址。。
      defaultZone: http://127.0.0.1:11114/eureka

2、修改另外一个服务的配置。配置与上面的配置刚好相反

server:
  port: 11114
spring:
  application:
# 名字随便取 应用名称,会在 Eureka 中显示
    name: user-eureka
eureka:
  client:
    register-with-eureka: false  # 是否注册自己的信息到 EurekaServer,默认是  true
    fetch-registry: false        # 是否拉取其它服务的信息,默认是 true
    service-url:
      #配置成其他服务的地址,不是自己的地址。。
      defaultZone: http://127.0.0.1:10114/eureka

所谓的高可用注册中心,其实就是把 EurekaServer 自己也作为一个服务进行注册,这样
多个 EurekaServer 之间就能互相发现对方,从而形成集群。因此我们做了以下修改:
1、删除了 register-with-eureka=false 和 fetch-registry=false 两个配置。因为默认值是 true,
这样就会吧自己注册到注册中心了。
2、把 service-url 的值改成了另外一台 EurekaServer 的地址,而不是自己
这样就搭建好了一个 Eureka 集群。然后可以分别启动两个服务。这时候,服务的提供者和服务的消费者,只需要修改一下配置文件,指定多个 eurekaserver 的地址,就能将服务发布到集群中,或者从集群中获取服务了。

配置文件如下:

eureka:
 client:
  service-url: #EurekaServer 地址,集群配置
   defaultZone:http://127.0.0.1:10114/eureka,http://127.0.0.1:11114/eureka
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值