• 微服务注册中心:Eureka详解


    文章目录

    Eureka基础概念

    Eureka概述

    Eureka:服务注册与发现提供了一个服务注册中心、服务发现的客户端,还有一个方便查看所有注册的服务的界面。所有的服务使用Eureka的服务发现客户端来将自己注册到Eureka的服务器上。

    在这里插入图片描述

    Eureka架构图

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

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

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

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

    在这里插入图片描述

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

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

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

    在这里插入图片描述

    Eureka集群架构图

    在这里插入图片描述

    Eureka关键概念

    • 服务注册:register
    • 服务续约:renew, 客户端默认每隔30秒向服务器发送一次心跳进行续约,如果服务器90秒内没有收到心跳,则将该客户端剔除
    • 获取服务注册列表信息:fetch registries
    • 服务下线:cancel
    • 服务剔除eviction

    Eureka的自我保护模式

    • 默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将 会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通 信,这就可能变得非常危险了----因为微服务本身是健康的,此时本不应该注销这个微服务。
    • Eureka Server通过“自我保护模式”来解决这个问题- - -当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式, Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
    • 自我保护模式是一种对网络异常的安全保护措施。使用自我保护模式,可以让Eureka集群更加健壮、 稳定。
    • 在Spring Cloud中,可以使用eureka.server.enable-self-preservation=false来禁用自我保护模式(不建议禁用)
    • 简言之:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。

    创建Eureka服务端

    1.新建Module

    创建名为cloud-eureka-server7001的Maven工程。

    2.修改pom文件

    
    
        
            cloud-kernel
            com.kernel.springcloud
            1.0.0-SNAPSHOT
        
        4.0.0
    
        cloud-eureka-server7001
    
        
            8
            8
        
    
        
            
            
                com.kernel.springcloud
                cloud-api-common
                ${project.version}
            
    
            
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-server
            
    
            
                org.springframework.boot
                spring-boot-starter-web
            
            
                org.springframework.boot
                spring-boot-starter-actuator
            
    
        
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3.编写application.yml配置文件

    server:
      port: 7001
    
    eureka:
      instance:
        hostname: localhost # eureka服务端的实例名称
      client:
        # false表示不向注册中心注册自己。
        register-with-eureka: false
        # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        fetch-registry: false
        service-url:
          # 设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址。
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4.编写启动类

    @EnableEurekaServer注解 表示 Eureka服务端

    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaMainApplication {
    
        public static void main(String[] args) {
    
            SpringApplication.run(EurekaMainApplication.class,args);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.测试
    测试运行EurekaMainApplication,浏览器输入http://localhost:7001/回车,会查看到Spring Eureka服务主页。

    在这里插入图片描述

    服务提供者cloud-provider-8001入驻进EurekaServer

    EurekaClient端cloud-provider-8001将注册进EurekaServer成为服务提供者provider。

    1.修改cloud-provider-8001的pom文件

    添加spring-cloud-starter-netflix-eureka-client依赖

    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
    
    
    • 1
    • 2
    • 3
    • 4

    2.修改application.yml配置文件

    server:
      port: 8001
    
    spring:
      application:
        name: cloud-provider-service
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
        driver-class-name: com.mysql.jdbc.Driver                # mysql驱动包
        url: jdbc:mysql://localhost:3306/idata_baiir?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: ******
        password: ******
    
    mybatis:
      mapperLocations: classpath:mapper/*.xml
      type-aliases-package: com.kernel.entity    # 所有Entity别名类所在包
    
    eureka:
      client:
        # 表示是否将自己注册进Eurekaserver默认为true。
        register-with-eureka: true
        # 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://localhost:7001/eureka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.修改主启动类

    @SpringBootApplication
    @EnableEurekaClient //<-----添加该注解
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class,args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.测试
    启动cloud-provider-8001和cloud-eureka-server7001工程。

    浏览器输入 http://localhost:7001/ 主页内的Instances currently registered with Eureka会显示cloud-provider-8001的配置文件application.yml设置的应用名cloud-provider-service

    在这里插入图片描述

    消费者模块入驻进EurekaServer

    EurekaClient端cloud-consumer-80将注册进EurekaServer成为服务消费者consumer。

    1.修改cloud-consumer-80的pom文件

    添加spring-cloud-starter-netflix-eureka-client依赖

    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
    
    
    • 1
    • 2
    • 3
    • 4

    2.修改application.yml配置文件

    server:
      port: 80
    
    spring:
      application:
        name: cloud-consumer-service
        
    eureka:
      client:
        #表示是否将自己注册进Eurekaserver默认为true。
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://localhost:7001/eureka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.修改主启动类

    @SpringBootApplication
    @EnableEurekaClient//<--- 添加该注解
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class,args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.测试

    启动cloud-provider-8001、cloud-eureka-server7001和cloud-consumer-80这三工程。

    浏览器输入 http://localhost:7001 , 在主页的Instances currently registered with Eureka将会看到cloud-provider-8001、cloud-consumer-80两个工程名。

    在这里插入图片描述

    Eureka工作原理

    在这里插入图片描述

    Eureka集群环境构建

    Eureka server搭建集群不同与传统集群,每个server是互等的1在向23注册时1就相当于客户端,需要向23注册信息的同时还要获取信息。所以 defaultZone注册时如1需注册23的server地址(不能注册自己的地址)注册完123会在系统趋于平稳进行复制 达到信息共享统一

    在这里插入图片描述
    创建cloud-eureka-server7002工程 步骤同上

    hosts文件,修改映射配置添加进hosts文件

    127.0.0.1 eureka7001.com
    127.0.0.1 eureka7002.com
    
    • 1
    • 2

    修改cloud-eureka-server7001配置文件

    server:
      port: 7001
    
    eureka:
      instance:
        hostname: eureka7001.com #eureka服务端的实例名称
      client:
        register-with-eureka: false     #false表示不向注册中心注册自己。
        fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        service-url:
        #集群指向其它eureka
          defaultZone: http://eureka7002.com:7002/eureka/
        #单机就是7001自己
          #defaultZone: http://eureka7001.com:7001/eureka/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    修改cloud-eureka-server7002配置文件

    server:
      port: 7002
    
    eureka:
      instance:
        hostname: eureka7002.com #eureka服务端的实例名称
      client:
        register-with-eureka: false     #false表示不向注册中心注册自己。
        fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        service-url:
        #集群指向其它eureka
          defaultZone: http://eureka7001.com:7001/eureka/
        #单机就是7002自己
          #defaultZone: http://eureka7002.com:7002/eureka/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    将服务注册进Eureka集群

    将它们的配置文件的eureka.client.service-url.defaultZone进行修改

    eureka:
      client:
        #表示是否将自己注册进Eurekaserver默认为true。
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    服务提供端搭建集群

    前边已经将eureka注册中心搭建成集群,现在把我们的服务端也搭建为集群环境。

    参考cloud-provider-8001 新建 cloud-provider-8002

    1.新建cloud-provider-8002 模块
    2.修改POM
    3.写YML - 端口改为8002 (除了端口号其余全一样)

    server:
      port: 8002
    
    spring:
      application:
        name: cloud-provider-service
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
        driver-class-name: com.mysql.jdbc.Driver                # mysql驱动包
        url: jdbc:mysql://localhost:3306/idata_baiir?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: ******
        password: ******
    
    mybatis:
      mapperLocations: classpath:mapper/*.xml
      type-aliases-package: com.kernel.entity    # 所有Entity别名类所在包
    
    eureka:
      client:
        # 表示是否将自己注册进Eurekaserver默认为true。
        register-with-eureka: true
        # 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://localhost:7001/eureka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.编写主启动类
    5.编写业务代码

    为了测试,我们在代码里加入调用的端口号
    在这里插入图片描述

    可以看到 cloud-provider-service 下有俩个服务
    在这里插入图片描述
    负载均衡

    cloud-consumer-80服务访问地址不能写死

    在这里插入图片描述

    使用@LoadBalanced注解赋予RestTemplate负载均衡的能力

    @Configuration
    public class ApplicationContextConfig {
    
        @Bean
        @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试
    结果:负载均衡效果达到,8001/8002端口交替出现

    actuator微服务信息完善

    instance-id:主机名称:服务名称修改(也就是将IP地址,换成可读性高的名字)

    prefer-ip-address:访问信息有IP信息提示

    eureka:
      client:
        # 表示是否将自己注册进Eurekaserver默认为true。
        register-with-eureka: true
        # 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://localhost:7001/eureka
      instance:
        instance-id: ${spring.application.name}:${server.port}
        prefer-ip-address: true     #访问路径可以显示IP地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    服务发现Discovery

    对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息

    修改cloud-provider-8001的Controller

    @Api(tags = "用户管理接口")
    @RestController
    @Slf4j
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private IUserTestService userTestService;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
    
        @Value("${server.port}")
        private Integer serverPort;
    
        @ApiOperation(value = "服务发现Discovery")
        @GetMapping(value = "/get/discovery")
        public Object discovery() {
    
            List services = discoveryClient.getServices();
            for (String element : services) {
                log.info("*****element: " + element);
            }
    
            List instances = discoveryClient.getInstances("CLOUD-PROVIDER-SERVICE");
            for (ServiceInstance instance : instances) {
                log.info(instance.getServiceId() + "	" + instance.getHost() + "	" + instance.getPort() + "	" + instance.getUri());
            }
    
            return this.discoveryClient;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    修改主启动类

    @SpringBootApplication
    @EnableEurekaClient 
    @EnableDiscoveryClient//添加该注解
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class,args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    在这里插入图片描述

    禁用自我保护模式

    在eurekaServer端7001处设置关闭自我保护机制

    默认,自我保护机制是开启的
    使用eureka.server.enable-self-preservation = false可以禁用自我保护模式

    eureka:
      ...
      server:
        #关闭自我保护机制,保证不可用服务被及时踢除
        enable-self-preservation: false
        eviction-interval-timer-in-ms: 2000 # 清理间隔(单位毫秒,默认是60*1000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    生产者客户端eurekaClient端8001

    eureka:
      ...
      instance:
        instance-id:  ${spring.application.name}:${server.port}
        prefer-ip-address: true
        #心跳检测与续约时间
        #开发时没置小些,保证服务关闭后注册中心能即使剔除服务
        #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
        lease-renewal-interval-in-seconds: 1
        #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
        lease-expiration-duration-in-seconds: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结果:先关闭8001,马上被删除了

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    使用scp把另外一台服务器上的文件夹/文件拷贝到当前服务器
    Lodash初识
    第十三届蓝桥杯省赛C++组、Java组真题—— 求和 (AC)
    美创这款产品入选《2022年度浙江省首版次软件产品应用推广指导目录入围名单》
    在 Visual Studio 2022 中配置 OpenCV
    【网络奇遇记】那年我与计算机网络的浅相知
    c++访问修饰符与继承关系
    第三章《数组与循环》第3节:while循环
    用HTML+CSS+JS做一个漂亮简单的游戏网页——全屏游戏美术大赛作品(4个滚动页面)
    华为汪涛:5.5G时代UBB目标网,跃升数字生产力
  • 原文地址:https://blog.csdn.net/m0_67394002/article/details/126081210