• SpringBoot Cloud eureka 注册中心


    SpringBoot Cloud是什么

    Spring Cloud是一个分布式的整体解决方案。 Spring Cloud 为开发者提供了在
    分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全局琐, leader选举,分布式session,集群状态)中快速构建的工具,
    使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。

    SpringCloud分布式开发五大常用组件

    • 服务发现——Netflix Eureka (发现了 英 [,jʊ(ə)'riːkə] )
    • 客服端负载均衡——Netflix Ribbon (缎带  英 ['rɪbən] )
    • 断路器——Netflix Hystrix (断路器)
    • 服务网关——Netflix Zuul (路由网关)
    • 分布式配置——Spring Cloud Config (配置)

    .

    https://www.processon.com/diagraming/5cef1a48e4b05d5b38bdb090

    特别强调: springboot和springcloud如果版本不兼容会报异常java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Class;)V

    springcloud中eureka搭建

    建一个空项目springboot-07-cloud,内有三个子模块

    1. eureka-server (注册中心)
    2. cloud-provider (服务提供者)
    3. cloud-consumer  (消费者)

    三个子模块文件结构如下

    springboot-07-cloud base分支中三个子模块如下

    springboot-07-cloud中三个子模块 eureka-server (注册中心)

    cloud-provider (服务提供者)

    cloud-consumer  (消费者)

         
     pom.xml区别
    <?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">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.21.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>eureka-server</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-server</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.SR6</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            
    <!-- starter-netflix-eureka-server自动依赖starter-actuator --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
    <?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">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.21.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>cloud-provider</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-provider</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.SR6</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    <?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">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.21.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>cloud-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cloud-consumer</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.SR6</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    application.yml区别
    server:
      port: 8761
    eureka:
      instance:
        hostname: eureka-server # eureka实例主机名
      client:
        register-with-eureka: false # 不把自己注册到eureka上, 因为自己本来就是注册中心
        fetch-registry: false # 不从eureka上获取服务的注册信息
        service-url:
          defaultZone: http://localhost:8761/eureka/
          #defaultZone 是注册中心服务注册的地址

    默认eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,将register-with-eureka置为false

    若未禁用eureka服务注册中心的客户端注册行为,需提供service-url注册中心地址

    server:
      port: 8001
    spring:
      application:
        name: provider
    eureka:
      instance:
        prefer-ip-address: true # 注册服务时使用服务的ip地址
      client:
        register-with-eureka: true # 把自己注册到eureka上
        fetch-registry: true # 从eureka上获取服务的注册信息
        service-url:
          defaultZone: http://localhost:8761/eureka/
          #defaultZone 是注册中心服务注册的地址
    server:
      port: 8002
    spring:
      application:
        name: consumer
    eureka:
      instance:
        prefer-ip-address: true # 注册服务时使用服务的ip地址
      client:
        register-with-eureka: true # 把自己注册到eureka上
        fetch-registry: true # 从eureka上获取服务的注册信息
        service-url:
          defaultZone: http://localhost:8761/eureka/
          #defaultZone 是注册中心服务注册的地址

    特别注意: springboot和springcloud的版本有对应要求, 本样例用的是

    springboot <version>1.5.21.RELEASE</version> 对应 springbloud <spring-cloud.version>Edgware.SR6</spring-cloud.version>

    在实际开发过程中,我们需要更详细的版本对应:以伦敦地铁站命名

    spring-boot-starter-parentspring-cloud-dependencies
    版本号发布日期 版本号发布日期 
    1.5.2.RELEASE 2017年3月 稳定版 Dalston.RC1 2017年未知月  
    1.5.9.RELEASE 2017年11月 稳定版 Edgware.RELEASE 2017年11月 稳定版
    1.5.16.RELEASE     Edgware.SR5    
    1.5.20.RELEASE     Edgware.SR5    
    2.0.2.RELEASE 2018年5月   Finchley.BUILD-SNAPSHOT 2018年未知月  
    2.0.6.RELEASE     Finchley.SR2    
    2.1.4.RELEASE     Greenwich.SR1    
    2.2.2.RELEASE     Hoxton.SR1 2019年  
     待更新...          

    eureka-server (注册中心)

    EurekaServerApplication.java

    注册中心启动入口 , 注意需要@EnableEurekaServer注解支持

    package com.example.eurekaserver;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    /**
     * 使用注册中心步骤
     * 1. application.yml配置
     * 2. @EnableEurekaServer注解添加
     */
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    
    }

    cloud-provider (服务提供者)

    CloudProviderApplication.java

     生产者启动类, 不需要额外注解, 因为做了注册到eureka上的配置, 就可以直接把@RestController注解的所有接口自动注册到eureka注册中心 , 供消费者调用.

    package com.example.cloud.provider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class CloudProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CloudProviderApplication.class, args);
        }
    
    }

    CloudProviderController.java

    package com.example.cloud.provider.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class CloudProviderController {
        static int number;
    
        @GetMapping("/buyTicket")
        public String buyTicker(){
            return "ticker "+ ++number;
        }
    }

    cloud-consumer (消费者)

    CloudConsumerApplication.java

    消费者启动入口 , 注意需要开启@EnableDiscoveryClient注解

    package com.example.cloud.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * cloud 客户端调用时需要引入 @EnableDiscoveryClient 注解
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    public class CloudConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CloudConsumerApplication.class, args);
        }
    
    }

    MyConfiguration.java

    需要把RestTemplate类组装到springboot容器中, 专门用于调用eureka上发现的服务

    package com.example.cloud.consumer.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class MyConfiguration {
    
        @LoadBalanced//负载均衡
        @Bean//需要把RestTemplate装配进来,专门用于调用Eureka上发现的服务
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

    CloudConsumberController.java

    使用 http://localhost:8002/buyTicket 访问

    package com.example.cloud.consumer.controller;
    
    import com.netflix.discovery.converters.Auto;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class CloudConsumberController {
    
        @Autowired
        RestTemplate restTemplate;
    
        //http://localhost:8002/buyTicket
        @GetMapping("/buyTicket")
        public String buyTicker(){
            String retData = restTemplate.getForObject("http://PROVIDER/buyTicket",String.class);//
            retData = "成功购买" + retData;
            return retData;
        }
    
    }

     访问

     访问springcloud的eureka-server 注册中心 http://localhost:8761/

    访问cloud-consumer消费者提供的controller接口  http://localhost:8002/buyTicket 后,浏览器显示如下

    成功购买ticker 1

    注意Status一栏显示的是服务实例名, 默认取名规则为${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}   ,  最后的写法意为如果spring.application.instance_id没有定义,则取server.port, 如果已定义了则舍掉server.port取spring.application.instance_id

    遇见异常

     Error creating bean with name 'gsonBuilder' defined in class path resource 

    异常详情如下:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gsonBuilder' defined in class path resource [org/springframework/boot/autoconfigure/gson/GsonAutoConfiguration.class]:Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.gson.GsonBuilder]: Factory method 'gsonBuilder' threw exception; nested exception is java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder

    那是因为整个项目没有引入parent依赖 , 添加如下<parent>即可

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>

     

    Eureka服务心跳检测(健康检测机制)

    1.Eureka服务端

    在某一些时候注册在Eureka的服务已经挂掉了,但是服务却还留在Eureka的服务列表的情况。

    Eureka服务端的配置application.yml:

    server:
      port: 9501
    
    eureka:
      instance:
        hostname: 127.0.0.1
      client:
        registerWithEureka: false
        fetchRegistry: false
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      server:
        # 关闭自我保护机制
        enable-self-preservation: false
        # 每隔10s扫描服务列表,移除失效服务
        eviction-interval-timer-in-ms: 10000

    默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。

    自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。

    自我保护机制的工作机制是如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:

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

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

    3、当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。

    因此Eureka Server可以很好的应对因网络故障导致部分节点失联的情况,而不会像ZK那样如果有一半不可用的情况会导致整个集群不可用而变成瘫痪。

    # 该配置可以移除这种自我保护机制,防止失效的服务也被一直访问 (Spring Cloud默认该配置是 true)
    eureka.server.enable-self-preservation: false
    
    # 该配置可以修改检查失效服务的时间,每隔10s检查失效服务,并移除列表 (Spring Cloud默认该配置是 60s)
    eureka.server.eviction-interval-timer-in-ms: 10

    2.Eureka客户端

    Eureka客户端的配置application.yml:

    eureka:
      instance:
        # 每隔10s发送一次心跳
        lease-renewal-interval-in-seconds: 10
        # 告知服务端30秒还未收到心跳的话,就将该服务移除列表
        lease-expiration-duration-in-seconds: 30
      client:
        serviceUrl:
          defaultZone: http://localhost:9501/eureka/
    
    server:
      port: 9502
    spring:
      application:
        name: service-hi
    # 该配置指示eureka客户端需要向eureka服务器发送心跳的频率  (Spring Cloud默认该配置是 30s)
    eureka.instance.lease-renewal-interval-in-seconds: 10
    
    # 该配置指示eureka服务器在接收到最后一个心跳之后等待的时间,然后才能从列表中删除此实例 (Spring Cloud默认该配置是 90s)
    eureka.instance.lease-expiration-duration-in-seconds: 30

    SpringCloud:Eureka的健康检测机制==>https://blog.csdn.net/akaks0/article/details/79512680

    遗留问题

    defaultZone 需要添加/eureka后缀? 是的默认就这样.

    我的git项目地址

    https://gitee.com/KingBoBo/springboot-07-cloud  base分支

     入门篇

    Eureka 服务的注册和发现==>https://www.cnblogs.com/fangwu/p/8975990.html

    进阶篇

    SpringBoot SpringCloud集群==>https://www.cnblogs.com/whatlonelytear/p/10894161.html

  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/whatlonelytear/p/10894106.html
Copyright © 2020-2023  润新知