zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Jira-dashboard
    SCQA 结构化表达案例:让开场白、讲故事精彩的结构
    outlook 2016 系列1--自动回复
    outlook 2016 系列1--如何将同一回复主题的邮件放在一起
    C++ 成员限定符
    TCP/IP 协议分层
    TCP之拥塞控制
    TCP之流量控制
    TCP之滑动窗口
    TCP中的定时器
  • 原文地址:https://www.cnblogs.com/whatlonelytear/p/10894106.html
Copyright © 2011-2022 走看看