0


Eureka服务注册与发现

文章目录

Eureka基础知识

什么是服务治理?

Spring Cloud 封装了Netflix公司开发的Eureka来实现服务治理

在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间的依赖关系,可以实现服务调用,负载均衡,容错等,实现服务发现与注册

什么是服务注册?

Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。

在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))

在这里插入图片描述
Eureka三大角色

Eureka Server:提供服务的注册与发现,类似Zookeeper
Service Provider:将自服务注册到Eureka中,从而使消费方能够找到
Service Consumer:服务消费方从Eureka中获取注册服务列表,从而找到消费服务

Eureka两大组件:Eureka Server和Eureka Client

Eureka Server提供服务注册服务

各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。

EurekaClient通过注册中心进行访问

是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

Spring cloud聚合父工程project添加链接描述

Eureka配置项

Eureka Server 配置项

参数名称说明默认值*eureka.server.enable-self-preservation *启用自我保护机制 trueeureka.server.eviction-interval-timer-in-ms*清除无效服务实例的时间间隔(ms)*60000eureka.server.delta-retention-timer-interval-in-ms清理无效增量信息的时间间隔(ms)30000eureka.server.disable-delta禁用增量获取服务实例信息falseeureka.server.log-identity-headers是否记录登录日志trueeureka.server.rate-limiter-burst-size限流大小10eureka.server.rate-limiter-enabled是否启用限流 falseeureka.server.rate-limiter-full-fetch-average-rate平均请求速率100eureka.server.rate-limiter-throttle-standard-clients是否对标准客户端进行限流falseeureka.server.rate-limiter-registry-fetch-average-rate服务注册与拉取的平均速率500eureka.server.rate-limiter-privileged-clients信任的客户端列表eureka.server.renewal-percent-threshold15分钟内续约服务的比例小于0.85,则开启自我保护机制,再此期间不会清除已注册的任何服务(即便是无效服务)0.85eureka.server.renewal-threshold-update-interval-ms更新续约阈值的间隔(分钟)15eureka.server.response-cache-auto-expiration-in-seconds注册信息缓存有效时长(s)180eureka.server.response-cache-auto-expiration-in-seconds注册信息缓存更新间隔(s)30eureka.server.retention-time-in-m-s-in-delta-queue保留增量信息时长(分钟)3eureka.server.sync-when-timestamp-differs当时间戳不一致时,是否进行同步trueeureka.server.use-read-only-response-cache是否使用只读缓存策略true

Eureka client配置项

参数名称说明默认值eureka.client.enabled用于指示Eureka客户端已启用的标志trueeureka.client.registry-fetch-interval-seconds指示从eureka服务器获取注册表信息的频率(s)30seureka.client.instance-info-replication-interval-seconds更新实例信息的变化到Eureka服务端的间隔时间(s)30seureka.client.initial-instance-info-replication-interval-seconds初始化实例信息到Eureka服务端的间隔时间(s)40seureka.client.eureka-service-url-poll-interval-seconds询问Eureka Server信息变化的时间间隔(s)300seureka.client.eureka-server-read-timeout-seconds读取Eureka Server 超时时间(s)8seureka.client.eureka-server-connect-timeout-seconds连接Eureka Server 超时时间(s)5seureka.client.eureka-server-total-connections获取从eureka客户端到所有eureka服务器的连接总数200个eureka.client.eureka-server-total-connections-per-host获取从eureka客户端到eureka服务器主机允许的连接总数50个eureka.client.eureka-connection-idle-timeout-seconds连接到 Eureka Server 空闲连接的超时时间(s)30eureka.client.registry-refresh-single-vip-address指示客户端是否仅对单个VIP的注册表信息感兴趣nulleureka.client.heartbeat-executor-thread-pool-size心跳保持线程池初始化线程数2个eureka.client.heartbeat-executor-exponential-back-off-bound心跳超时重试延迟时间的最大乘数值10eureka.client.serviceUrl.defaultZone****可用区域映射到与eureka服务器通信的完全限定URL列表。每个值可以是单个URL或逗号分隔的备用位置列表。eureka.client.use-dns-for-fetching-service-urls指示eureka客户端是否应使用DNS机制来获取要与之通信的eureka服务器列表。当DNS名称更新为具有其他服务器时,eureka客户端轮询eurekaServiceUrlPollIntervalSeconds中指定的信息后立即使用该信息。eureka.client.register-with-eureka指示此实例是否应将其信息注册到eureka服务器以供其他服务发现trueeureka.client.fetch-registry指示此实例是否从eureka中获取注册信息****trueeureka.client.prefer-same-zone-eureka实例是否使用同一zone里的eureka服务器,理想状态下,eureka客户端与服务端是在同一zone下trueeureka.client.log-delta-diff是否记录eureka服务器和客户端之间在注册表的信息方面的差异falseeureka.client.disable-delta指示eureka客户端是否禁用增量提取falseeureka.client.fetch-remote-regions-registry逗号分隔的区域列表,提取eureka注册表信息eureka.client.on-demand-update-status-change客户端的状态更新到远程服务器上trueeureka.client.allow-redirects指示服务器是否可以将客户端请求重定向到备份服务器/集群。如果设置为false,则服务器将直接处理请求。如果设置为true,则可以将HTTP重定向发送到具有新服务器位置的客户端。falseeureka.client.availability-zones.*获取此实例所在区域的可用区域列表(在AWS数据中心中使用)。更改在运行时在registryFetchIntervalSeconds指定的下一个注册表获取周期生效。eureka.client.backup-registry-impl获取实现BackupRegistry的实现的名称,该实现仅在eureka客户端启动时第一次作为后备选项获取注册表信息。 对于需要额外的注册表信息弹性的应用程序,可能需要这样做,否则它将无法运行。eureka.client.cache-refresh-executor-exponential-back-off-bound在发生一系列超时的情况下,它是重试延迟的最大乘数值。10eureka.client.cache-refresh-executor-thread-pool-size缓存刷新线程池初始化线程数量2eureka.client.client-data-accept客户端数据接收的名称fulleureka.client.decoder-name解码器名称eureka.client.dollar-replacement eureka服务器序列化/反序列化的信息中获取“$”符号的替换字符串。默认为“_-”eureka.client.encoder-name编码器名称eureka.client.escape-char-replacement eureka服务器序列化/反序列化的信息中获取“_”符号的的替换字符串。默认为“__“eureka.client.eureka-server-d-n-s-name获取要查询的DNS名称来获得eureka服务器,此配置只有在eureka服务器ip地址列表是在DNS中才会用到nulleureka.client.eureka-server-port获取eureka服务器的端口,此配置只有在eureka服务器ip地址列表是在DNS中才会用到nulleureka.client.eureka-server-u-r-l-context表示eureka注册中心的路径,如果配置为eureka,则为http://ip:port/eureka/,在eureka的配置文件中加入此配置表示eureka作为客户端向注册中心注册,从而构成eureka集群。此配置只有在eureka服务器ip地址列表是在DNS中才会用到nulleureka.client.filter-only-up-instances是否过滤掉非up实例trueeureka.client.g-zip-content当服务端支持压缩的情况下,是否支持从服务端获取的信息进行压缩trueeureka.client.property-resolver属性解析器eureka.client.proxy-host获取eureka server 的代理主机名nulleureka.client.proxy-password获取eureka server 的代理主机密码nulleureka.client.proxy-port获取eureka server 的代理主机端口nulleureka.client.proxy-user-name获取eureka server 的代理用户名nulleureka.client.region获取此实例所在的区域(在AWS数据中心中使用)。us-east-1eureka.client.should-enforce-registration-at-init client在初始化阶段是否强行注册到注册中心falseeureka.client.should-unregister-on-shutdown client在shutdown情况下,是否显示从注册中心注销true

服务实例配置项(eureka.instance.*)

参数名称说明默认值eureka.instance.appname注册到注册中心的应用名称unknowneureka.instance.a-s-g-name注册到注册中心的应用所属分组名称(AWS服务器)nulleureka.instance.app-group-name注册到注册中心的应用所属分组名称nulleureka.instance.data-center-info指定服务实例所属数据中心eureka.instance.instance-enabled-onit指示是否应在eureka注册后立即启用实例以获取流量falseeureka.instance.non-secure-porthttp通信端口80eureka.instance.non-secure-port-enabled是否启用HTTP通信端口trueeureka.instance.secure-portHTTPS通信端口443eureka.instance.secure-port-enabled是否启用HTTPS通信端口falseeureka.instance.secure-virtual-host-name服务实例安全主机名称(HTTPS)unknowneureka.instance.virtual-host-name该服务实例非安全注解名称(HTTP)unknowneureka.instance.secure-health-check-url该服务实例安全健康检查地址(URL)绝对地址eureka.instance.lease-renewal-interval-in-seconds该服务实例向注册中心发送心跳间隔(s)30eureka.instance.lease-expiration-duration-in-seconds指示eureka服务器在删除此实例之前收到最后一次心跳之后等待的时间(s)** 90*eureka.instance.metadata-map.自定义元数据,符合KEY/VALUE的存储格式。这 些元数据可以在远程客户端中访问。eureka.instance.ip-address该服务实例的IP地址nulleureka.instance.prefer-ip-address是否优先使用服务实例的IP地址,相较于hostnamefalseeureka.instance.status-page-url该服务实例的状态检查地址(url),绝对地址nulleureka.instance.status-page-url-path该服务实例的状态检查地址,相对地址/actuator/infoeureka.instance.home-page-url该服务实例的主页地址(url),绝对地址eureka.instance.home-page-url-path该服务实例的主页地址,相对地址/eureka.instance.health-check-url该服务实例的健康检查地址(url),绝对地址nulleureka.instance.health-check-url-path该服务实例的健康检查地址,相对地址/actuator/healtheureka.instance.instance-id该服务实例在注册中心的唯一实例ID****eureka.instance.hostname ****该服务实例所在主机名 **eureka.instance.namespace获取用于查找属性的命名空间。 在Spring Cloud中被忽略。eurekaeureka.instance.environment该服务实例环境配置eureka.instance.default-address-resolution-order默认地址解析顺序eureka.instance.initial-status该服务实例注册到Eureka Server 的初始状态upeureka.instance.registry.default-open-for-traffic-count【Eureka Server 端属性】默认开启通信的数量1eureka.instance.registry.expected-number-of-renews-per-min【Eureka Server 端属性】每分钟续约次数1

Eureka Server 集群配置(eureka.server.*)

参数说明默认值eureka.server.enable-replicated-request-compression复制数据请求时,数据是否压缩falseeureka.server.batch-replication节点之间数据复制是否采用批处理falseeureka.server.max-elements-in-peer-replication-pool备份池最大备份事件数量1000eureka.server.max-elements-in-status-replication-pool状态备份池最大备份事件数量1000eureka.server.max-idle-thread-age-in-minutes-for-peer-replication节点之间信息同步线程最大空闲时间(分钟)15eureka.server.max-idle-thread-age-in-minutes-for-peer-replication节点之间状态同步线程最大空闲时间(分钟)10eureka.server.max-threads-for-peer-replication节点之间信息同步最大线程数量20eureka.server.max-threads-for-status-replication节点之间状态同步最大线程数量1eureka.server.max-time-for-replication节点之间信息复制最大通信时长(ms)3000eureka.server.min-available-instances-for-peer-replication集群中服务实例最小数量,-1 表示单节点-1eureka.server.min-threads-for-peer-replication节点之间信息复制最小线程数量5eureka.server.min-threads-for-status-replication节点之间信息状态同步最小线程数量1eureka.server.number-of-replication-retries节点之间数据复制时,可重试次数5eureka.server.peer-eureka-nodes-update-interval-ms节点更新数据间隔时长(分钟)10eureka.server.peer-eureka-status-refresh-time-interval-ms节点之间状态刷新间隔时长(ms)30000eureka.server.peer-node-connect-timeout-ms节点之间连接超时时长(ms)200eureka.server.peer-node-connection-idle-timeout-seconds节点之间连接后,空闲时长(s)30eureka.server.peer-node-read-timeout-ms几点之间数据读取超时时间(ms)200eureka.server.peer-node-total-connections集群中节点连接总数1000eureka.server.peer-node-total-connections-per-host节点之间连接,单机最大连接数量500eureka.server.registry-sync-retries节点启动时,尝试获取注册信息的次数500eureka.server.registry-sync-retry-wait-ms节点启动时,尝试获取注册信息的间隔时长(ms)30000eureka.server.wait-time-in-ms-when-sync-empty在Eureka服务器获取不到集群里对等服务器上的实例时,需要等待的时间(分钟)5

单机Eureka构建步骤

Eureka Server服务注册中心

新建Module:cloud-eureka-server7001

在这里插入图片描述

2、引入pom依赖

<?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>cloud2024</artifactId><groupId>com.my.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-eureka-server7001</artifactId><dependencies><!--eureka-server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!--boot web actuator--><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><!--一devtools热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies></project>

3、创建application.yml配置文件

spring:
  application:
    name: Eureka-Service7001

server:
  port: 7001

eureka:
  client:
    register-with-eureka: true     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
    #单机就是7001自己
      defaultZone: http://eureka7001.com:7001/eureka/
      #集群指向其它eureka
      #defaultZone: http://eureka7002.com:7002/eureka/
  instance:
    #向注册中心注册服务ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true     #显示IP地址
  server:
    #Eureka自我保护机制,(默认是开启的)
    enable-self-preservation: true
    # 设置心跳时间(eureka默认心跳时间是30秒)
    eviction-interval-timer-in-ms: 30000

4、主启动类上加注解 @EnableEurekaServer

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServer//eureka server 注册中心publicclassEurekaMain7001{publicstaticvoidmain(String[] args){SpringApplication.run(EurekaMain7001.class, args);}}

测试访问 http://localhost:7001

在这里插入图片描述

到这里服务注册中心就基本搭建完成了,现在我们需要将其他模块中的服务注册进来

Eureka client客户端

cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider

1.新建模块cloud-provider-payment8001

在这里插入图片描述

2、在cloud-provider-payment8001服务中引入依赖

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

3、application.yml配置文件

server:
  port:8001
spring:
  application:
    name: cloud-payment-service

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka:true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry:true
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: payment8001
    prefer-ip-address:true #访问路径可以显示IP地址

4、主启动类加注解@EnableEurekaClient

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.client.discovery.EnableDiscoveryClient;importorg.springframework.cloud.netflix.eureka.EnableEurekaClient;/**
 *
 */@SpringBootApplication@EnableEurekaClient//代表Eureka客户端publicclassPaymentMain8001{publicstaticvoidmain(String[] args){SpringApplication.run(PaymentMain8001.class, args);}}

5、测试

先要启动EurekaServer,然后启动cloud-provider-payment8001模块,最后访问http://localhost:7001/
在这里插入图片描述

集群Eureka搭建步骤

微服务RPC远程服务调用最核心的是什么?

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

解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错

集群实现方式:多台Eureka Server互相注册

Eureka集群原理说明

在这里插入图片描述

Eureka Server集群

注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。

在生产中我们可能需要三台或者大于三台的注册中心来保证服务的稳定性,配置的原理其实都一样,将注册中心分别指向其它的注册中心。这里只介绍三台集群的配置情况,其实和双节点的注册中心类似,每台注册中心分别又指向其它两个节点即可,使用application.yml来配置。

Eureka Server 集群环境构建步骤

参考cloud-eureka-server7001微服务

1.新建cloud-eureka-server7002微服务

2、引入pom依赖

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

3、修改映射配置

找到C:\Windows\System32\drivers\etc路径下的hosts文件,添加如下配置

在这里插入图片描述不添加这个使用端口号访问的方式也是可以的,做这个由于咱是在一台机器上面模拟的

4、修改7001和7002的application.yml配置

7001:

spring:
  application:
    name:Eureka-Service7001

server:
  port:7001

eureka:
  client:
    register-with-eureka:false   #false表示不向注册中心注册自己
    fetch-registry:false  #false表示自己就是注册中心,我的职责就是维护服务实例,不需要去检索服务
    service-url:
    #单机就是7001自己
      #defaultZone: http://eureka7001.com:7001/eureka/
      #集群指向其它eureka
      defaultZone: http://eureka7002.com:7002/eureka/
  instance:
    #向注册中心注册服务ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address:true     #显示IP地址
  server:
    #Eureka自我保护机制,(默认是开启的)
    enable-self-preservation:true
    # 清除无效服务实例的时间间隔(默认60000 ms)
    eviction-interval-timer-in-ms:60000

7002:

spring:
  application:
    name:Eureka-Service7002
server:
  port:7002

eureka:
  client:
    register-with-eureka:true     #false表示不向注册中心注册自己。
    fetch-registry:false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      #单机就是7002自己
    #defaultZone: http://eureka7002.com:7002/eureka/
      #集群指向其它eureka
      defaultZone: http://eureka7001.com:7001/eureka/
  instance:
    #向注册中心注册服务ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address:true     #显示IP地址
  server:
    #Eureka自我保护机制,(默认是开启的)
    enable-self-preservation:true
    # 清除无效服务实例的时间间隔(默认60000 ms)
    eviction-interval-timer-in-ms:60000

5、测试微服务是否注册成功

集群搭建好之后,查看这两台注册中心是否已经户向注册

在这里插入图片描述
可以看到,两台节点互相注册成功,一般集群最少也要搭建三个节点,这里为了方便就两个

Servce provider 服务的提供者

服务的提供者,将服务注册到Eureka当中

1. 新建cloud-provider-payment8001微服务

在这里插入图片描述

2. 引入pom依赖

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

3.application.yml配置:

server:
  # 服务器的HTTP端口
  port:8001

# Spring配置
spring:
  application:
    name: cloud-payment-service   #微服务名称

#配置数据源
  datasource:
    type:com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driverClassName:com.mysql.cj.jdbc.Driver              # mysql驱动包 com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password:123456

#eureka配置
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 # 集群版
  instance:
    #向注册中心注册服务ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address:true #访问路径可以显示IP地址
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds:30
    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
    lease-expiration-duration-in-seconds:90

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

4 .主启动动类上添加@EnableEurekaClient注解

packagecom.my.springcloud;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.client.discovery.EnableDiscoveryClient;importorg.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication@EnableEurekaClient//服务的提供者,将服务注册到Eureka当中publicclassPaymentMain8001{publicstaticvoidmain(String[] args){SpringApplication.run(PaymentMain8001.class, args);}}

5.新建相关业务类

mapper接口

importcom.my.springcloud.entities.Payment;importorg.apache.ibatis.annotations.Mapper;importorg.apache.ibatis.annotations.Param;@MapperpublicinterfacePaymentDao{publicintcreate(Payment payment);publicPaymentgetPaymentById(@Param("id")Long id);}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.my.springcloud.dao.PaymentDao"><resultMap id="BaseResultMap" type="com.my.springcloud.entities.Payment"><id column="id" property="id" jdbcType="BIGINT"/><id column="serial" property="serial" jdbcType="VARCHAR"/></resultMap><select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select *
        from payment
        where id = #{id};</select><insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial)
        values (#{serial});</insert></mapper>

service接口

importcom.my.springcloud.entities.Payment;importorg.apache.ibatis.annotations.Param;publicinterfacePaymentService{publicintcreate(Payment payment);publicPaymentgetPaymentById(@Param("id")Long id);}

service接口实现类

importcom.my.springcloud.dao.PaymentDao;importcom.my.springcloud.entities.Payment;importcom.my.springcloud.service.PaymentService;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;@ServicepublicclassPaymentServiceImplimplementsPaymentService{@ResourceprivatePaymentDao paymentDao;publicintcreate(Payment payment){return paymentDao.create(payment);}publicPaymentgetPaymentById(Long id){return paymentDao.getPaymentById(id);}}

Controller

importcom.my.springcloud.utils.RestResponse;importcom.my.springcloud.entities.Payment;importcom.my.springcloud.service.PaymentService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.cloud.client.ServiceInstance;importorg.springframework.cloud.client.discovery.DiscoveryClient;importorg.springframework.web.bind.annotation.*;importjavax.annotation.Resource;importjava.util.List;importjava.util.concurrent.TimeUnit;@RestController@Slf4jpublicclassPaymentController{@ResourceprivatePaymentService paymentService;@Value("${server.port}")privateString serverPort;@GetMapping(value ="/payment/get/{id}")publicRestResponse<Payment>getPaymentById(@PathVariable("id")Long id){Payment payment = paymentService.getPaymentById(id);if(payment !=null){returnRestResponse.success(200,"查询成功,serverPort:  "+ serverPort, payment);}else{returnRestResponse.fail(444,"没有对应记录,查询ID: "+ id,null);}}@PostMapping(value ="/payment/create")publicRestResponsecreate(@RequestBodyPayment payment){int result = paymentService.create(payment);
        log.info("*****插入结果:"+ result);if(result >0){returnRestResponse.success(200,"插入数据库成功,serverPort: "+ serverPort, result);}else{returnRestResponse.fail(444,"插入数据库失败",null);}}}

6. 测试

先启动EurekaServer:7001和7002服务

再启动服务提供者 cloud-provider-payment8001查看服务注册情况
在这里插入图片描述cloud-provider-payment8001服务已经注册成功

测试服务是否正常: 访问 http://localhost/payment/get/1

在这里插入图片描述

Servce consumer 服务消费者

1.新建 cloud-consumer-order80微服务**

在这里插入图片描述

2、引入pom依赖:

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

3、application.yml配置

server:
  port:80

spring:
    application:
        name: cloud-order-service

#eureka配置
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 # 集群版
  instance:
    #向注册中心注册服务ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address:true #访问路径可以显示IP地址
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds:30
    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
    lease-expiration-duration-in-seconds:90

4、创建负载均衡配置类

Ribbon搭配Eureka实现负载均衡,在RestTemplate上添加@LoadBalanced注解

importorg.springframework.cloud.client.loadbalancer.LoadBalanced;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.client.RestTemplate;/**
 * @auther
 * @desc Ribbon负载均衡配置类(Ribbon默认使用的是RoundRobinRule 轮询策略)
 */@ConfigurationpublicclassLoadConfig{@Bean@LoadBalancedpublicRestTemplategetRestTemplate(){returnnewRestTemplate();}}

5、主启动上添加@EnableEurekaClient

packagecom.my.springcloud;importcom.my.myrule.MyLoadConfig;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.netflix.eureka.EnableEurekaClient;importorg.springframework.cloud.netflix.ribbon.RibbonClient;@SpringBootApplication@EnableEurekaClientpublicclassOrderConsumer80{publicstaticvoidmain(String[] args){SpringApplication.run(OrderConsumer80.class, args);}}

6、编写controller

@RestController@Slf4jpublicclassOrderController{publicstaticfinalStringINVOKE_URL="http://cloud-provider-payment";@ResourceprivateRestTemplate restTemplate;@GetMapping("/consumer/payment/get/{id}")publicRestResponse<Payment>getPayment(@PathVariable("id")Long id){return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+ id,RestResponse.class);}}

7、测试调用服务提供者

查看服务是否注册成功, 访问 http://localhost:7001/

在这里插入图片描述

8、验证下服务是否能被消费

生产环境部署都是多台实例,这里为了演示方便:模拟下多节点

在service中复制一个进程,指定不同端口
在这里插入图片描述

指定端口号
-Dserver.port=8002
在这里插入图片描述
启动刚才复制8003服务

查看服务是否注册成功, 访问 http://localhost:7001/

在这里插入图片描述8003服务已经注册到eureka中

测试调用服务提供者,是否能成功消费

(1)启动eureka 7001和7002,服务提供者8001和8002,服务消费者 consumer-order80
(2)访问 http://localhost/consumer/payment/get/1

在这里插入图片描述
在次发起请求

在这里插入图片描述端口号变成8003说明负载均衡成功

Eureka的自我保护机制

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。

简单一句话:(好死不如赖活着)

用电视剧新三国中,曹操说的:“宁可天下人负我,我不负天下人”即:Eureka服务端,进入自我保护模式,就算所有的微服务真的都出问题了,也不会里面删除它们的

为什么会出现自我保护机制?

一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该服务的信息进行保存。属于CAP里面的AP分支,也即是:保证可用性、分区容错性。
PS:CAP原则:分布式系统中,C:一致性;A:可用性;P:分区容错性。
我们来看看百度百科对CAP原则的详细介绍,如下图:

在这里插入图片描述综上,自我保护是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的、不健康的微服务都会保留),也不盲目注销任何健康的微服务。
职用自我保护模式,可以让Eureka集群更加的健壮和稳定

怎么禁止Eureka的自我保护?

1.在Eureka Service7001关闭自我保护机制

修改Eureka Service7001application.yml配置文件:
(1)关闭自我保护
(2)清除无效服务实例的时间间隔修改成2秒

eureka:
  server:
    #Eureka自我保护机制,(默认是开启的)
    enable-self-preservation:false
    # 清除无效服务实例的时间间隔修改成2秒
    eviction-interval-timer-in-ms:2000

启动7001,访问 http://localhost:7001/

在这里插入图片描述
这句话的意思是: 关闭自我保护模式,在网络/其他问题的情况下,这可能无法保护实例过期。

2. Eureka client8001

修改Eureka client8001application.yml配置文件:
(1)修改eureka客户端向服务端发送心跳的时间间隔
(2)修改Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务

#eureka配置
eureka:
  instance:
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds:1
    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
    lease-expiration-duration-in-seconds:2

测试服务

启动7001和8001 ,访问 http://localhost:7001/

在这里插入图片描述
假如8001出现宕机

我这里直接模拟8001服务宕机:关闭8001服务

在这里插入图片描述

此时访问 http://localhost:7001/ 发现8001服务被剔除了

在这里插入图片描述

标签: eureka 云原生

本文转载自: https://blog.csdn.net/qq_40428665/article/details/135447467
版权归原作者 人生就像一场戏! 所有, 如有侵权,请联系我们删除。

“Eureka服务注册与发现”的评论:

还没有评论