SpringCloud Netflix(三):Eureka注册与发现

Eureka简介

在微服务架构里说过微服务架构有四大问题,其一就是 这么多服务,如何管理?

Eureka就是Netflix提供给我们来管理众多服务的。

Eureka是一个基于REST(Representational State Transfer)的服务,主要用于AWS云中定位服务,以实现中间层服务器的负载平衡和故障转移。

在Netflix,Eureka除了在中端负载平衡中发挥关键作用外,还用于以下目的。

  • 为了帮助Netflix Asgard—一个使云部署更容易的开源服

    • 在遇到问题时快速回滚版本,避免重新启动100个实例,这可能需要很长时间。

    • 在滚动推送中,为了避免在出现问题时向所有实例传播新版本。

  • 为了我们的cassandra部署,将实例从流量中取出进行维护。

  • 为了我们的memcached缓存服务来识别环中的节点列表。

  • 出于各种其他原因,用于携带有关服务的其他特定于应用程序的元数据。

 

 

Eureka使用实例

1. 创建Eureka Server

添加 eureka-server 依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>

添加配置

server:
  port: 7001

eureka:
  instance:
    hostname: server1
  client:
    register-with-eureka: false # 是否将自己注册到Eureka Server, 默认为true
    fetch-registry: false # 是否从Eureka Server获取注册信息,默认为true
    service-url:
      defaultZone: http://localhost:7001/eureka/

在启动类使用@EnableEurekaServer注解

@SpringBootApplication
@MapperScan("com.example.springcloud.mapper") @EnableEurekaServer
//声明该应用为Eureka Server public class Eureka7001 { public static void main(String[] args) { SpringApplication.run(Eureka7001.class, args); } }

2.创建Eureka Client(即服务提供者)

在之前的服务提供者的基础上,添加 eureka 依赖

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

添加配置

server:
  port: 8888

spring:
  application:
    name: springcloud-provider #注册中心中的服务名
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: "123456"
    type: com.alibaba.druid.pool.DruidDataSource

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/ #对应Eureka Server的defaultZone

在启动类添加@EnableEurekaClient注解

@SpringBootApplication
@EnableEurekaClient //声明该应用为Eureka Client
public class Provider_8888 {
    public static void main(String[] args) {
        SpringApplication.run(Provider_8888.class,args);
    }
}

3.消费者

添加配置

server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:7001/eureka/ #对应Eureka Server的defaultZone

通过服务名调用服务者

package com.example.springcloud.controller;

import com.example.springcloud.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

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

    @Autowired
    private RestTemplate restTemplate;

     // “http://服务名/[controller类上的RequestMapping]”,服务名是服务者配置里的spring.application.name
    // 如果服务提供者controller类上不加RequestMapping,[]里的路径可去掉 private static final String URL = "http://SPRINGCLOUD-PROVIDER/user/"; @RequestMapping("/user/{id}") public User getUserById(@PathVariable("id")Integer id) { return restTemplate.getForObject(URL+id, User.class); } @RequestMapping("/user/list") public List<User> getAllUser(){ return restTemplate.getForObject(URL, List.class); } @RequestMapping("/user/add") public int addUser(User dept){ return restTemplate.postForObject(URL+"add", dept, Integer.class); } }

创建启动类,添加@EnableEurekaClient注解

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableEurekaClient //声明该应用为Eureka Client
public class Consumer {
    public static void main(String[] args) {
        SpringApplication.run(Consumer.class, args);
    }
}

访问 http://localhost:7001/

 

Eureka集群

1.创建多一个Eureka Server,依赖和启动类和之前一样,只需更改配置中的defaultZone

server:
  port: 7002

eureka:
  instance:
    hostname: server2 #在注册中心中的Eureka Server名
  client:
    register-with-eureka: false # 是否将自己注册到Eureka Server, 默认为true
    fetch-registry: false # 是否从Eureka Server获取注册信息,默认为true
    service-url:
      defaultZone: http://localhost:7001/eureka/ #对集群中其他Eureka Server,多个用逗号分开

把之前的Eureka Server的配置中的defaultZone也改成

server:
  port: 7001

eureka:
  instance:
    hostname: server1 #在注册中心中的Eureka Server名
  client:
    register-with-eureka: false # 是否将自己注册到Eureka Server, 默认为true
    fetch-registry: false # 是否从Eureka Server获取注册信息,默认为true
    service-url:
      defaultZone: http://localhost:7002/eureka/ #对集群中其他Eureka Server,多个用逗号分开

2.更改服务者和消费者的配置中的defaultZone

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #对集群中所有Eureka Server,多个用逗号分开

 

自我保护机制

默认情况下,如果 Eureka Server 在一定的 90s 内没有接收到某个微服务实例的心跳,会注销该实例。但是在微服务架构下服务之间通常都是跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,网络分区故障,导致此实例被注销。

固定时间内大量实例被注销,可能会严重威胁整个微服务架构的可用性。为了解决这个问题,Eureka 开发了自我保护机制,那么什么是自我保护机制呢?

Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 即会进入自我保护机制。

Eureka Server 触发自我保护机制后,页面会出现提示:

Eureka Server 进入自我保护机制,会出现以下几种情况:

  • Eureka 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务

  • Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)

  • 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

Eureka 自我保护机制是为了防止误杀服务而提供的一个机制。当个别客户端出现心跳失联时,则认为是客户端的问题,剔除掉客户端;当 Eureka 捕获到大量的心跳失败时,则认为可能是网络问题,进入自我保护机制;当客户端心跳恢复时,Eureka 会自动退出自我保护机制。

如果在保护期内刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,即会调用失败。对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。

通过在 Eureka Server 配置如下参数,开启或者关闭保护机制,生产环境建议打开:

eureka:
  server:
    enable-self-preservation: true

 

我的个人博客站

 

 

 

posted @ 2020-05-10 23:34  小高飞  阅读(375)  评论(0编辑  收藏  举报