美文网首页
SpringCloud 2.x Eureka 服务端

SpringCloud 2.x Eureka 服务端

作者: 单v纯微笑 | 来源:发表于2019-02-20 15:42 被阅读0次

    说明:SpringBoot 版本-2.1.2.RELEASE,Eureka版本-2.1.0.RELEASE。

    以下内容纯属个人见解,不一定正确,如有发现理解错误地方,望不吝指教,不胜感激。

    一、Eureka服务端注意事项
    1. 添加Eureka服务端依赖:
    <!-- eureka 服务端依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
    1. 必须在启动类上添加 @EnableEurekaServer 注解,否则在浏览器上访问不到Eureka管理页面,并且客户端也不会注册成功。

    二、Eureka单机配置

    单机版须在配置文件中指定配置:

    eureka:
         client:
            # 是否在Eureka注册。没有该配置,则单机版启动会报错。
            register-with-eureka: false
            # 是否从Eureka中获取注册信息。没有该配置,则单机版启动会报错。
            fetch-registry: false
            # 可选配置
            service-url:
                # 默认注册地址,注意不能写成default-zone,否则将不生效。
                # 原因是Eureka有默认的defaultZone配置,端口为8761。
                # 详情参见:org.springframework.cloud.netflix.eureka.EurekaClientConfigBean类的serviceUrl属性初始化代码块
                defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    

    三、Eureka集群配置

    以3个节点集群为例,端口分别为8080、8081、8082,样例如下:

    1. eureka-server-01节点配置:
    # eureka-server-01 配置
    spring:
        application:
            # 应用名称。
            # 为了便于管理和维护,需要将集群内的所有节点都设置为一样的应用名称。
            name: spring-cloud-eureka-server
    server:
        # 端口
        port: 8080
    eureka:
         client:
            service-url:
                # 默认注册地址,注意不能写成default-zone,否则将不生效。
                # 原因是Eureka有默认的defaultZone配置,端口为8761。
                # 详情参见:org.springframework.cloud.netflix.eureka.EurekaClientConfigBean类的serviceUrl属性初始化代码块
                defaultZone: http://localhost:8081/eureka/,http://localhost:8082/eureka/
    
    1. eureka-server-02节点配置:
    # eureka-server-02 配置
    spring:
        application:
            # 为了便于管理和维护,需要将集群内的所有节点都设置为一样的应用名称。
            name: spring-cloud-eureka-server
    server:
        # 端口
        port: 8081
    eureka:
         client:
            service-url:
                # 这里必须将所有非本节点都列出来。
                defaultZone: http://localhost:8080/eureka/,http://localhost:8082/eureka/
    
    1. eureka-server-03节点配置:
      同上

    三、Eureka服务端安全认证
    1. 添加security安全认证依赖:
    <!-- security安全认证依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    1. 配置文件添加用户名和密码配置:
    spring:
        ......
        security:
            user:
                # 用户名。集群时候可以分别对多个Eureka Server配置不同的用户名,不推荐。
                name: admin
                # 密码。集群时候可以分别对多个Eureka Server配置不同的用户名,不推荐。
                password: admin
    eureka:
        client:
            ......
            service-url:
                # > 这段注释很重要 <
                # > 这段注释很重要 <
                # > 这段注释很重要 <
                # 重要的事情说3遍
                # --------------------------------------------------------
                # defaultZone改为"http://[user:password@]localhost:8080/eureka/"格式。
                # 其中:
                # "user"为用户名,可自定义。
                # "password"为密码,可自定义。
                # "@"为连接符,固定格式。
                # --------------------------------------------------------
                # 在SpringBoot(版本:2.1.2.RELEASE) + SpringCloud(版本:Greenwich.RELEASE)中(别的版本没试过):
                # []包裹的内容在单机模式下为可选配置(不配置好像没有什么影响)。
                # 但是,在集群中则必须配置为别的Eureka Server的用户名和密码。
                # 单机如果要配置的话,配置的是本Eureka Server的用户名密码。
                # 集群模式配置的是对方的用户名密码,有可能和自己不一样。
                defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@localhost:8081/eureka/
    
    1. 关闭csrf检验(不关闭则客户端将不能正常注册到服务端)。

    新版的security默认启用了csrf检验
    解决步骤:

    1. 在 Eureka Server 项目中,增加存放配置的专用包目录;
    2. 添加一个继承 WebSecurityConfigurerAdapter 的类;
    3. 在类上添加 @EnableWebSecurity 注解;
    4. 覆盖父类的 configure(HttpSecurity http) 方法,关闭掉 csrf,至此大工告成。
    /**
     * 关闭csrf检验
     * @author liangdl
     *
     */
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
            super.configure(http);
        }
    }
    

    四、自我保护

    默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。

    Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

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

    开发环境为了调试方便,可以关闭,生产环境不建议关闭。

    1. Eureka 服务端配置
    ......
    # Eureka 服务端配置
    eureka:
        server:
            # 关闭保护机制,以确保注册中心将不可用的实例正确剔除
            enable-self-preservation: false
            # (代表是5秒,单位是毫秒,清理失效服务的间隔 )
            eviction-interval-timer-in-ms: 5000
    ......
    
    1. Eureka 客户端配置
    ......
    eureka:
        instance:
            # 每间隔10s,向服务端发送一次心跳,证明自己依然"存活"
            lease-renewal-interval-in-seconds: 10
            # 告诉服务端,如果我20s之内没有给你发心跳,就代表我"死"了,将我踢出掉。
            lease-expiration-duration-in-seconds: 20
    ......
    

    五、健康检查

    健康检查在服务端和客户端均可配置

    1. 添加健康检查依赖
    <!-- 健康检查 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    1. 添加配置
      SpringCloud 默认开启info和health两项,可以手动配置多个。
    # 开启健康检查项
    management:
        endpoints:
            web:
                exposure:
                    # "*"表示开启所有健康检查项,也可以指定具体类型,多个用逗号分割。
                    include: "*"
    

    部分可选配置项:
    info: 显示任意的应用信息
    health: 展示应用的健康信息
    metrics: 展示当前应用的指标信息 true
    mappings: 显示所有@RequestMapping路径的整理列表
    trace: 显示trace信息(默认为最新的一些HTTP请求)
    beans: 显示一个应用中所有Spring Beans的完整列表

    1. 访问

    SpringCloud 2.x中,在访问地址中加了"/actuator",目的是方便安全控制。

    // 应用信息
    http://localhost:8080/actuator/info
    // 健康信息
    http://localhost:8080/actuator/health
    ......
    

    六. 安全控制

    健康检查的信息里面包含很多敏感信息,如果没有访问权限的控制,那么应用程序也有很大的风险。
    默认情况下,安全认证不只是针对健康检查,而是针对整个系统。

    1. 添加安全认证依赖
    <!-- 安全认证 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    1. 添加配置
    spring:
        security:
            user:
                # 用户名
                name: admin
                # 密码
                password: admin
    
    1. 对部分url做安全认证
      添加以上配置后,访问所有请求都将经过安全认证(登录)。那么就会导致服务注册也需要安全认证,可以过滤部分地址需要安全认证。
    /**
     * 认证Web路径配置<br>
     * 参考:http://www.mamicode.com/info-detail-2375708.html
     * @author liangdl
     *
     */
    @Configuration
    @EnableWebSecurity
    public class ActuatorWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                // 特定请求需要认证(健康检查)
                .antMatchers("/actuator/*")
                .authenticated()
                // 剩余请求不需要认证,如果不设置这个,那么所有调用的url都需要认证。
                .antMatchers("/*")
                .permitAll()
                .and()
                .formLogin();
        }
    }
    

    提示: 可能需要web依赖(未测试)

     <!-- spring-web依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

    七、附录
    • 完整的Eureka 服务端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>2.1.2.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.vvlin</groupId>
        <artifactId>sc-eureka</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>sc-eureka</name>
        <description>Spring Cloud Eureka Demo</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <!-- eureka 服务端依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            
            <!-- security安全认证依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</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>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
            </repository>
        </repositories>
    
    </project>
    
    

    • 完整的Eureka 服务端application.yml

    笔者的测试代码没有在服务器端做健康检查配置,所以不包含健康检查配置

    spring:
      application:
        # 应用名称
        name: sc-eureka-server
      security:
        user:
          name: admin
          password: admin
        
    server:
      # 端口
      port: 8080
    
    eureka:
    #  instance:
    #    # 使用ip地址访问
    #    prefer-ip-address: true
      server:
        # 关闭保护机制,以确保注册中心将不可用的实例正确剔除
        enable-self-preservation: false
        # (代表是5秒,单位是毫秒,清理失效服务的间隔 )
        eviction-interval-timer-in-ms: 5000
      client:
        # 是否在Eureka注册。没有该配置,则单机版启动会报错。
        register-with-eureka: false
        # 是否从Eureka中获取注册信息。没有该配置,则单机版启动会报错。
        fetch-registry: false
        # 可选配置
        service-url:
          # 默认注册地址,注意不能写成default-zone,否则将不生效。
          # 原因是Eureka有默认的defaultZone配置,端口为8761。
          # 详情参见:org.springframework.cloud.netflix.eureka.EurekaClientConfigBean类的serviceUrl属性初始化代码块
          # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          defaultZone: http://localhost:8080/eureka/
          # defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@localhost:8081/eureka/
    

    相关文章

      网友评论

          本文标题:SpringCloud 2.x Eureka 服务端

          本文链接:https://www.haomeiwen.com/subject/vcuhyqtx.html