二、Eureka

Eureka

Eureka基础知识

什么是服务治理

Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。

什么是服务注册

什么是服务注册与发现

Eureka采用了CS的设计架构, Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心
跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以别名方式注册到注册中心上。另- -方(消费者|服务提供
者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与
服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
在这里插入图片描述

Eureka两组件

Eureka包含两个组件: Eureka Server和Eureka Client

  • Eureka Server提供服务注册服务
    各个微服务节点通过配置启动后,会在EurekaServer中进行注册, 这样EurekaServer中的服务注册表中将 会存储所有可用服务节点的
    信息,服务节点的信息可以在界面中直观看到。
  • EurekaClient通过注册中心进行访问
    是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、 使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心
    跳, EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

maven配置

  • sprinboot启动类添加@EnableEurekaServer
  • 服务端maven
以前的老版本(当前使用2018)
<dependency>
<groupId>org.springframework.cloud</ groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
现在新版本(当前使用2020.2)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • springboot启动类添加@EnableEurekaClient
  • 客户端maven
以前老版本,别再使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</ artifactId>
</dependency>

现在新版本,当前使用
<dependency>
<groupId>org.springframework.cloud</ groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

单机配置

服务端配置

  • yml配置
eureka:
  instance:
    hostname: localhost  #eureka服务端的实例名字
  client:
    register-with-eureka: false    #表识不向注册中心注册自己
    fetch-registry: false   #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/    #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址

客户端配置

  • yml配置
eureka:
  client:
    register-with-eureka: true #表示将自己注册到eureka
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

微服务注册名配置说明

在这里插入图片描述

集群配置

问题:微服务RPC远程服务调用最核心的是什么

高可用,试想你的注册中心只有一个only one,它出故障了那就呵呵(厂v )" 了会导致整个为服务环境不可用,所以

在这里插入图片描述

配置

项目注册 项目守望

项目目录
在这里插入图片描述

服务端配置

N台服务端 需要项目配置才能发现其他服务端
如7001 中 defaultZone: http://eureka7002.com:7002/eureka/ 如果有多个需要添加多个

  • cloud-eureka-server7001
server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com    #eureka服务端的实例名字
  client:
    register-with-eureka: false    #表识不向注册中心注册自己
    fetch-registry: false   #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/    #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
  • cloud-eureka-server7002
server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com #eureka服务端的实例名字
  client:
    register-with-eureka: false    #表识不向注册中心注册自己
    fetch-registry: false   #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/     #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
客户端配置

eureka.client.service-url.defaultZone 需要把集群中的服务端添加进去

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #集群版
消费端配置
eureka:
  client:
    register-with-eureka: true #把自己注入到eureka
    fetchRegistry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #集群版

配置RestTemplate 添加注解@LoadBalanced以达到负载均衡效果

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

请求中 PAYMENT_URL 指定服务名 不再需要指定ip地址了

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";


    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment) {
        //写操作
        return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
        return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
    }
}

信息完善

  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
  <!--web场景启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
  <!--web图形化监控-->
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
主机名称:服务名称ip修改

注意修改后cloud-provider-payment8002的配置需要添加eureka.instance.instance-id 否则只能注册8001一个
-Dserver.port=8002 -Dmanagement.server.port=8082 -Deureka.instance.instance-id=payment8002

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  
  instance:
    instance-id: payment8001 #显示的名称
    prefer-ip-address: true  #访问路径可以显示ip地址

  • 修改后效果图

在这里插入图片描述

Eureka多网卡选择

注意注册后ip不正确 Eureka
解决链接:https://blog.csdn.net/m0_37556444/article/details/100561630

spring:
  application:
    name: cloud-payment-service
  cloud:
    inetutils:
      preferred-networks: 192.168  #首选网卡 指定ip地址段避免 使用虚拟机网卡导致eureka服务端ip地址不正确其他计算机无法访问

方式二:
禁用虚拟机的
在这里插入图片描述

服务发现Discovery

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
springboot主启动类加@EnableDiscoveryClient

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
    //服务发现
    @Resource
    private DiscoveryClient discoveryClient;
	//省略其他方法
	
    @GetMapping(value = "/payment/discovery")
    public Object discovery() {
        //获得全部示例名称
        List<String> services = discoveryClient.getServices();
        for (String element : services) {
            log.info("*****element:" + element);
        }

        //一个微服务名称下的全部示例
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for (ServiceInstance instance : instances) {
            log.info(instance.getServiceId() + "	" + instance.getHost() + "	" + instance.getPort() + "	" + instance.getUri());
        }
        return this.discoveryClient;
    }

}

保护机制

在这里插入图片描述

  • 为什么产生Eureka自我保护机制?

为了防止EurekaClient可以正常运行, 但是与EurekaServer网络不通情况下, EurekaServer不会立刻将EurekaClient服务剔除
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。
它的设计哲学就是宁可保留错误的服务注册信息,不盲目注销任何可能健康的服务实例。-句话讲解:好死不如赖活着
综上,自我保护模式是一种应对网络异常的安全保护措施。 它的架构哲学是宁可同时保留所有微服务(健 康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

  • 什么是自我保护模式?

默认情况下,如果EurekaServer在一定时间内没有 接收到某个微服务实例的心跳,EurekaServer将 会注销该实例(默认90秒)。但.
当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了一因为微务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过 “自我保护模式”来解决这个问题一一当EurekaServer节 点在时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。

在这里插入图片描述

怎么禁止自我保护(一般生产环境中不会禁止自我保护)

server:
  enable-self-preservation: false
  eviction-interval-timer-in-ms: 2000

配置发送心跳间隔 和等待时间上限
在这里插入图片描述

原文地址:https://www.cnblogs.com/idcode/p/14551385.html