SpringCloud服务注册与发现:Eureka

0.Eureka的介绍

Eureka用于服务注册,目前官网已经停止更新

Eureka服务管理有3种概念:(仔细辨别)

  • 服务治理服务器Eureka server Eureka服务端:本例7001或7002):服务注册中心,负责服务列表的注册、维护和查询等功能,也就是Eureka服务器。
  • 服务注册代理Eureka Client Eureka客户端 8001/8002微服务提供者):如果一个微服务是一个服务提供者,那么可以通过服务注册代理将服务配置信息注册到治理服务器上。服务注册代理可以理解为一个Eureka客户端,负责将微服务所提供的服务向Eureka服务器执行注册、续约和注销等操作,以使服务消费者可以发现并进行消费。在服务注册时需要向服务治理服务器提供服务名称、宿主服务器IP地址、服务端口号、域名等主要数据。
  • 服务发现客户端Eureka Client Eureka客户端 80微服务消费者):也是一个Eureka客户端。它在启动时会默认从所服务治理服务器中获取所有的服务注册表信息,通过所获取到的服务注册列表信息来消费相应的服务。
    在这里插入图片描述
    总的来说,Eureka有2个组件
    在这里插入图片描述

1. 单机版配置:eureka

1.1 创建Eureka Server服务注册中心(7001这个服务器)

1.引入cloud-eureka-server7001的pom依赖

​ eurka最新的依赖变了
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-eureka-server7001</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
         //公共代码重复的依赖cloud-api-commons:entities
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

2. 配置7001的application.yml配置文件

一定要注意yaml文件这里的对齐格式,首行缩进和冒号缩进,否则启动会报错。

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

3. 7001主启动类

创建主启动类,注意这里要带上@EnableEurekaServer注解,表示这个服务器是一个服务注册中心。

package com.atguigu.springcloud;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 
@SpringBootApplication
@EnableEurekaServer//一定要加上这个注解,表示7001这个服务器是一个服务注册中心(7001是Eureka服务端)
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class, args);
    }
}

启动服务,访问http://localhost:7001/测试,可以看到Spring Eureka的界面即为成功。
在这里插入图片描述

1.2 其他服务客户端Eureka Client(80或8001)注册到Eureka Server(7001)

1.把EurekaClient端(cloud-provider-payment8001)注册到EurekaServer,作为服务提供者

8001主启动类上,加注解,表示当前是eureka客户端
在这里插入图片描述

2. 修改8001服务 pom.xml

修改cloud-provider-payment8001模块的pom.xml,添加Eureka-Client的坐标。
在这里插入图片描述

3. 修改8001服务配置文件yaml:

改cloud-provider-payment8001的yml配置文件,添加Eureka相关的配置。

spring:
  application:
    name: cloud-payment-service # 应用名称,这个和80名字不一样,这个名字就是存入服务注册中心的名字
eureka:
  client:
    register-with-eureka: true # 表示将自己注册进EurekaServer
    # 表示是否从Eureka抓取已有的注册信息,默认为true,单点无所谓,集群时候,必须设置成true,才能配合Ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

给cloud-provider-payment8001主启动类上添加@EnableEurekaClient注解。先启动EurekaServer,后启动EurekaClient,测试注册是否成功,在Eureka后台的Instances currently registered with Eureka,可以看到Application里的CLOUD-PAYMENT-SERVICE(这个名称对应cloud-provider-payment8001模块中yml配置文件的spring.application.name),它的Status是UP,表示注册成功了。
在这里插入图片描述
在这里插入图片描述

4. 把EurekaClient端(cloud-consumer-order80)注册到EurekaServer,作为服务消费者

修改cloud-consumer-order80模块的pom.xml,添加Eureka-Client的坐标。

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

修改cloud-consumer-order80的yml配置文件,添加Eureka相关的配置。

eureka:
  client:
    register-with-eureka: true # 表示将自己注册进EurekaServer
    # 表示是否从Eureka抓取已有的注册信息,默认为true,单点无所谓,集群时候,必须设置成true,才能配合Ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka
spring:
  application:
    name: cloud-order-service #应用名称,这个和8001不一样,这个名字就是存入服务注册中心的名字

给cloud-consumer-order80主启动类上添加@EnableEurekaClient注解。

@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

先启动EurekaService,后启动EurekaClient,正常情况下,在Eureka后台的Application中,应该可以看到两个微服务,此时说明服务注册成功了。
在这里插入图片描述

2. 集群版eureka:(解决单个eureka出现故障)

集群版eureka提高负载均衡能力和故障容错能力,并且集群中每一个eureka都要有其他的eureka信息,形成交互。

2.1 集群原理

在这里插入图片描述

1,就是payment生产者服务启动时(8001/8002),注册自己,并且自身信息也放入eureka7001(存key和value)
2.order消费者服务80,首先也注册自己,放入信息(存key和value)7001,当要调用payment生产者服务时,order消费者服务先从eureka拿到payment的调用地址(调用value)
3.order消费者服务通过HttpClient调用,实现RPC远程服务调用
4.order消费者服务并且还会缓存一份 payment调用的地址 到本地jvm内存,30秒更新一次

集群构建原理:

​ 互相注册
在这里插入图片描述

2.2 建新的服务注册中心eureka-server7002(与7001构成集群)

新建一个服务注册中心模块,命名为cloud-eureka-server7002,类比cloud-eureka-server7001做一下基本配置,下面修改集群配置。修改两个模块application.yml里的配置信息,将hostname改成eureka7001.com和eureka7002.com,并通过修改hosts文件,将它们都指向localhost,port对应修改成7001和7002。

1. pom文件

​ 粘贴7001的即可

2. 配置hosts文件映射(这步重要)

​ 在写配置文件前,修改一下C:\windows\system32\drivers\etc路径下的hosts文件

127.0.0.1 eureka7001.com  //host就是127.0.0.1
127.0.0.1 eureka7002.com

在这里插入图片描述

3. 配置7002yaml文件

因为前面提到了“相互注册”,那么defaultZone就要表达出来相互的意思,7001的defaultZone设置成http://eureka7002.com:7002/eureka/,7002的defaultZone设置成http://eureka7001.com:7001/eureka/,这就完成了相互注册的意思,如果有3个注册中心,那么需要满足1注册2和3,2注册1和3,3注册1和2这种样子,注册地址写在defaultZone中,用英文逗号分隔开。

# cloud-eureka-server7001配置文件
server:
  port: 7001 # 端口号
eureka:
  instance:
    hostname: eureka7001.com # Eureka服务端实例名称,IP地址
  client:
    register-with-eureka: false # 表示不向容器中心注册自己
    fetch-registry: false # 表示自己就是注册中心,职责是维护服务实例,不需要去检索服务
    service-url:
    # 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
    #按照这个url地址访问,会在7002服务注册中心看到“eureka7001.com”这个Eureka服务端实例名称
      defaultZone: http://eureka7002.com:7002/eureka/
# cloud-eureka-server7002配置文件
server:
  port: 7002 # 端口号
eureka:
  instance:
    hostname: eureka7002.com # Eureka服务端实例名称,IP地址
  client:
    register-with-eureka: false # 表示不向容器中心注册自己
    fetch-registry: false # 表示自己就是注册中心,职责是维护服务实例,不需要去检索服务
    service-url:
    # 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
    #按照这个url地址访问,会在7001服务注册中心看到“eureka7002.com”这个Eureka服务端实例名称
      defaultZone: http://eureka7001.com:7001/eureka/

先后启动7001,7002注册中心,在浏览器访问http://localhost:7001/http://localhost:7002/都可以访问到正确的Eureka页面,因为我们做过hosts映射,所以访问http://eureka7001.com:7001/和http://eureka7002.com:7002/同样也能访问到。观察DS Replicas中的内容,如果7001中指向7002,7002中指向7001,那么就完成了相互注册,此时集群搭建成功。
在这里插入图片描述

2.3 将payment(8001),order(80)模块注册到eureka集群中(7001和7002)

只需要修改微服务的注册地址即可,之前只注册了一个注册中心,现在需要将yml中的defaultZone的值换成集群的即可,修改为http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka。先启动注册中心集群,再启动服务生产者,最后启动服务消费者,都启动之后,可以在Eureka注册中心集群的后台看到服务生产者和消费者已经注册进来了。

1. 只需要修改配置文件即可:

在这里插入图片描述

2. 两个模块都修改上面的都一样即可

8001提供者微服务(yaml含数据库等信息)

server:
  port: 8001
datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
spring:
  application:
    name: cloud-payment-service # 应用名称,这个和80名字不一样,这个名字就是存入服务注册中心的名字
eureka:
  client:
    register-with-eureka: true # 表示将自己注册进EurekaServer
    # 表示是否从Eureka抓取已有的注册信息,默认为true,单点无所谓,集群时候,必须设置成true,才能配合Ribbon使用负载均衡
    fetch-registry: true
    service-url:
    #单机
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包  
  

80消费者微服务

server:
  port: 80
spring:
    application:
        name: cloud-order-service
eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      #单机
      #defaultZone: http://localhost:7001/eureka
      # 集群
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  # 集群版

​ 然后启动两个模块

​ 要先启动7001,7002,然后是pay模块8001,然后是order(80)

2.4 将payment生产者服务也配置为集群模式(8001,8002)

创建新模块,cloud-provider-payment8002

​ 名称: cloud_pay_8002

pom.xml文件,复制8001的

yaml配置文件复制8001的

​ --端口修改一下,改为8002

​ --服务名称不用改,用一样的

主启动类,复制8001的

mapper,service,controller都复制一份

​ 然后就启动服务即可

​ 此时访问order模块,发现并没有负载均衡到两个payment模块中,而是只访问8001(因为先前将地址写死成8001)

​ 虽然我们是使用RestTemplate访问的微服务,但是也可以负载均衡的

​ (Controller层)设置微服务的名称,不要写死
在这里插入图片描述
访问http://localhost/consumer/payment/get/1,发现报错了,这是因为通过服务名查找服务地址的时候,一个服务名http://CLOUD-PAYMENT-SERVICE可能对应多个服务地址,我们需要指定访问策略,在RestTemplate的bean上添加@LoadBalanced注解,此时的访问策略就是轮询策略,再次访问http://localhost/consumer/payment/get/1,通过打印信息,可以验证这一点。

注意这样还不可以,需要在ApplicationContextConfig类中让RestTemplate开启负载均衡注解,还可以指定负载均衡算法,默认轮询

这里的@LoadBalanced注解赋予了RestTemplate负载均衡的能力,类似于Ribbon,后面Ribbon和Eureka整合后,消费者可以直接调用服务,而无需关心地址和端口号,负载均衡由Ribbon来完成。
在这里插入图片描述
测试结果:
在这里插入图片描述
在这里插入图片描述

2.5 Actuator微服务信息完善(显示ip和自定义的访问路径)

(1)主机名称:服务名称修改。instance-id: payment8001

(2)访问信息有IP信息提示:将原先的localhost用IP地址表示,p-address:true(显示127.0.0.1)

在Eureka注册中心的Instance currently registered with Eureka的Status里,主机名有的是ip,有的是localhost,这里不规范,我们需要做一下完善。在8001和8002的yml配置文件中加入如下内容即可,注意缩进,instance结点和client结点是同级别的。

修改配置文件:
在这里插入图片描述
再次刷新服务注册中心,此时status里,看到的就是我们指定的instance-id服务名称,payment8001;ip-address:true,将鼠标放在上面,可以在浏览器左下角看到ip地址。

3. eureka服务发现

对外提供每一个微服务的信息(比如主机名称、端口号、IP地址等信息)

以payment8001为例

3.1 在主启动类上添加一个注解@EnableDiscoveryClient注解

在这里插入图片描述

3.2 再添加一个注解,在controller中

在这里插入图片描述
在这里插入图片描述
然后重启8001.访问/payment/discovery

3.3 显示结果

下面这个代码是得出服务注册中心所有的微服务名称

List<String> services = discoveryClient.getServices();
    for (String service : services) {//得出所有的注册的微服务的信息
        System.out.println("Eureka中的服务:" + service);
    }

在这里插入图片描述
在这里插入图片描述
后台打印输出某一个微服务信息的结果

List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    for (ServiceInstance instance : instances) {//打印某一个微服务下面的服务信息
        //本例中payment提供者服务有8001和8002这两个微服务,但是服务名称相同,端口号不同
        System.out.println(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
    }

在这里插入图片描述

4. Eureka自我保护

4.1 Eureka默认开启自我保护

保护模式是用于一组客户端和Eureka Server之间存在网络分区场景下的保护功能,一旦进入了保护模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册数据,也就是不注销任何微服务。某时刻,某个微服务不可用了(可能是网络不稳定,心跳包丢失等情况),Eureka注册中心并不会立刻清理,依旧会对服务信息进行保存。属于CAP里面的AP分支。

默认情况下,Eureka Server发现某服务不可用了,会延迟90s,如果90s后,依旧没有接收到微服务的心跳包,此时,才会进行注销在短时间内,当出现丢失大量服务实例心跳包的时候,Eureka Server会开启自我保护机制。

如果在Eureka Server看到EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE,说明开启了保护模式,默认情况下,是开启的。

设计哲学:宁可保留错误的服务注册信息,也不盲目的注销任何可能健康的服务实例。

4.2 Eureka关闭自我保护(一般不要这么做)

如果要关掉自我保护,可以在7001模块上的application.yml里添加如下配置,注意缩进,和client是同一级别的。

eureka:
  server:
    enable-self-preservation: false # 关闭自我保护机制,   默认true开启
    eviction-interval-timer-in-ms: 2000 # 清理微服务间隔时间,单位为毫秒,    默认90秒

启动Eureka Server 7001模块,访问http://eureka7001.com:7001/可以看到THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.信息。

修改8001模块的yml文件,配置心跳包发送频率,注意缩进,结点位于eureka.instance下,同时,临时将这里的defaultZone改成单机,只访问7001,启动8001项目后,手动关闭,立刻去刷新Eureka Server,随着不断的刷新,2秒后,8001服务被移除。

eureka:
  instance:
    # Eureka客户端向服务端发送心跳时间间隔,单位为秒,默认为30秒发送一次心跳包
    lease-renewal-interval-in-seconds: 1 #这里设置为1秒发送一次心跳包
    # Eureka服务端在接收到最后一次心跳后等待的时间上限,单位为秒,默认是90秒(客户端这里设置的功能和服务端效果一样),超过后,微服务将被剔除
    lease-expiration-duration-in-seconds: 2 #这里设置为最后一次心跳后等待的时间上限是2秒,超过2秒Eureka Server 7001服务注册中心将会剔除8001这个客户端服务的注册者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值