本项目将使用伪集群方式部署 eureka-server 。

创建注册中心

  1. 模块名称 eureka-server (s1 表示 step1)
  2. pom 文件中添加依赖

    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      </dependency>
    </dependencies>
  3. 创建启动类 ..EurekaServer

    //1. @SpringBootApplication
    //spring-boot 注解,相当于 @Configuration + @EnableAutoConfiguration + @ComponentScan
    //@EnableAutoConfiguration -> AutoConfigurationImportSelector  会加载 META-INF/spring.factories 中指定的组件
    //这里应用了 SPI 协议
    
    //2. @EnableEurekaServer
    //完成注册中心功能
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServer {
      public static void main(String[] args) {
        /*
        启动参数一定要加 `args` ,以后命令行传参就是靠这个变量
         */
        SpringApplication.run(EurekaServer.class, args);
      }
    }
  4. 添加配置文件

    eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳(因此可以在内存中完成),在默认情况下erureka server也是一个eureka client ,必须要指定一个 server。
    bootstrap.yml 为最先加载的配置文件,当前配置文件内容只指定了 profile

    server:
      port: 34001 # 当前服务启动绑定的端口
    spring:
      profiles:
        active: dev # 指定当前环境,对于配置文件,会用 application-dev.yml 中有的值覆盖 application.yml 的值

    application.yml

    spring:
      application:
        name: eureka-server # 服务名
    eureka:
      server:
        enable-self-preservation: false # 是否开启自我保护
        eviction-interval-timer-in-ms: 10000 # 剔除心跳超时的节点阀值,默认 60000, 单位是 ms
      client: # 客户端设置
        register-with-eureka: false # 是否注册到 eureka-server
        fetch-registry: false # 是否从  eureka-server 下载服务列表
      instance: # 实例设置
        hostname: eureka-server-1 # 实例主机名,显示在UI注册列表中
        instance-id: ${spring.cloud.client.ip-address}:${server.port} # 实例名,UI注册列表中实例名对应的actuator的url
        prefer-ip-address: true # 调用服务的时候使用 IP,UI服务实例地址为 IP

    application-dev.yml

    eureka:
      client: # eureka client 设置
        serviceUrl:
          defaultZone: http://eureka-server-1:34001/eureka/ # 注册中心集群地址
      environment: dev # 当前环境,可现实在UI
      datacenter: personal-computer  # 当前数据中心,可现实在UI

    application-perf.yml , performance 环境,性能测试需要完备的部署,所以该环境使用集群模式部署 eureka-server

    eureka:
      client:
        serviceUrl:
          defaultZone: http://eureka-server-1:34001/eureka/,http://eureka-server-2:34002/eureka/,http://eureka-server-3:34003/eureka/
      environment: perf
      datacenter: personal-computer  

    通过 eureka.client.registerWithEureka: false 不向服务中心注册 和 eureka.client.fetchRegistry: false 不获取服务列表。作为 eureka-server , eureka-server 集群之间可以同步服务列表,没有必要对外暴露 eureka-server 的服务,也不需要显示的设置下载服务列表。

    eureka.client.serviceUrl.defaultZone 不要写成 default-zone , EurekaClientConfigBean#getEurekaServerServiceUrls 生成 service url 时会有问题。

    关于 yml 文件,他对格式的要求非常严格:

    1. 缩进标准必须一致
    2. 缩进层级必须依次递增
    3. 缩进必须对齐
    4. : 后必须有空格
    5. value 再长也不能回行
    6. value 如果是由 , 分隔的,可使用 - 数组形式替代使其单行内容缩短
    因为默认使用主机名访问,并且为了在伪集群换进各种区分出不同的实例,需要更改honst文件,设置如下
    # eureka-server
    127.0.0.1 eureka-server-1
    127.0.0.1 eureka-server-2
    127.0.0.1 eureka-server-3
  5. 启动工程

    运行 EurekaServer 的 main 函数。

    启动 eureka-server 的控制台信息

    • eureka-server 的注册地址 url 。
    • eureka-server 的监控信息地址,/actuator 需要添加 actuator 的依赖才能访问。
    • eureka-server 的启动端口 34001。
  6. 访问

    访问 http://localhost:34001/

    可不是 http://localhost:34001/eureka

    eureka-server-ui-1
    eureka-server-ui-2

    • System Status.Environment :通过 bootstrap.yml 指定了当前 profile 为 dev ,application-dev.yml 将被选用,该配置文件指定了 eureka.environment=dev
    • System Status.Data center :与上同理
    • System Status.Lease expiration enabled :是否采用失联剔除方案。当前值为是,当一个 eureka-client 上次的心跳时间距现在的时间间隔超过阀值,将被 eureka-server 从服务列表中剔除。
    • System Status.Renews threshold :心跳阀值
    • System Status.Renews (last min) :前一分钟整点 至 前两分钟整点 之间的心跳总数
    • DS Replicas :eureka-server 集群中的成员
    • Instances currently registered with Eureka :注册到 eureka-server 上的 eureka-client , 会按配置文件中设置的 spring.application.name 进行分组。当前还没有 eureka-client 进行注册,所以为空。
    • General Info
    • Instance Info

provider 向 eureka-server 进行注册

服务提供者、服务消费者,都是 eureka-client。
当 eureka-client 向 eureka-server 注册时,它会提供一些元数据,例如主机和端口,URL,主页等。
eureka-server 从每个 eureka-client 实例接收心跳消息。
如果心跳超时,则通常将该实例从服务列表中删除,当然也不有删的情况,后面会专门聊。

使用前面准备的 album-service-impl 模块进行注册,该项目数据结构简单,专注 eureka 部分。

  1. 修改 album-service-impl
  2. pom 文件中添加依赖

    <dependencies>
      <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-web</artifactId>
      </dependency>
    </dependencies>
    • album-service-impl 既是 provider 也是 eureka-client,需要添加 eureka-client 的依赖。
    • 引入了 web 功能,因为基于 spring cloud 的微服务就是建立在 http 协议上的,也可以提供一个触发程序的入口。
  3. 创建启动类 ..AlbumProvider,开启 eureka-client

    /*
    @EnableEurekaClient 启用 eureka-client 功能
     */
    @SpringBootApplication
    @EnableEurekaClient
    public class AlbumProvider {
      public static void main(String[] args) {
        SpringApplication.run(AlbumProvider.class, args);
      }
    }
  4. 创建配置文件,指定注册中心地址
    bootstrap.yml

    server:
      port: 33001
    spring:
      profiles:
        active: dev

    application.yml

     spring:
     application:
       name: album-provider
     eureka:
     client:
       service-url:
         defaultZone: http://localhost:35001/eureka
     instance:
       instance-id: ${spring.cloud.client.ip-address}:${server.port} # 代表了一个启动示例的标识,自定义,可以显示在控制台上,
       prefer-ip-address: true # 调用服务的时候使用 IP 优先,而不是使用域名。鼠标放到应用列表的实例上,状态类中的地址信息指定为 ip。
       lease-renewal-interval-in-seconds: 30 # 表示 eureka client 发送心跳给server端的频率。这个值决定了服务注册的快慢,太快消耗资源。默认30秒。
       lease-expiration-duration-in-seconds: 90 # 表示 eureka server 至上一次收到 client 的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该 instance。默认90秒

    application-dev.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://eureka-server-1:34001/eureka/
      environment: dev
      datacenter: personal-computer

    application-perf.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://eureka-server-1:34001/eureka/,http://eureka-server-2:34002/eureka/,http://eureka-server-3:34003/eureka/
      environment: perf
      datacenter: personal-computer
    spring.application.name 的设置是为了让 "Application" 处可以正常显示应用名,而不是 UNKNOWN。多个相同服务名的实例将形成负载。
    eureka.instance.instance-id 的设置是让 "Status" 处可以正常显示,用来区分相同服务下不同的节点。
    eureka.instance.prefer-ip-address 的设置可以让 "Status" 的链接以 IP 显示,而不是 localhost。
  5. 启动 provider
    运行 AlbumProvider 的 main 函数。
  6. 再次访问 eureka-server 的 UI http://localhost:34001/
    eureka-server的服务列表
    可以看到, album-provider 这类服务有一个实例已经注册到 eureka-server 。

服务提供者已经就绪了,下面就是如何消费服务。spring cloud 提供了强大的客户端帮助简化消费过程。接下来说一下 Ribbon+RestTemplate 和 Feign 。

添加 actuator 使服务实例的链接可用

目前在 eureka-server UI 界面上点击服务实例 URL 是 404, 现在来完善这个服务实例的信息。这个链接的信息是由 eureka-client 自己提供的,现在的情况下,也就是作为 provider 的 album-service-impl 来提供。这些信息由 actuator 组件提供,该组件主要为监控提供支持。

actuator 官网文档

  1. pom 文件中添加依赖

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  2. application.yml 文件中添加信息

    info:
      app.name: album-provider
      compony.name: me.xhy
      build.artifactId: $project.artifactId$
      build.modelVersion: $project.modelVersion$

    此处的 $ 暂时无法识别,会被当成普通字符串处理,添加一个 maven 插件来处理

  3. 修改根项目 pom 文件,<build> 标签下添加插件

    <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
              <delimiters>
                <delimiter>$</delimiter>
              </delimiters>
            </configuration>
          </plugin>
        </plugins>
    </build>

    重新运行,再访问 eureka-server UI 上的服务实例,会提示下载文件,因为返回的是个流,使用 google 浏览器可适配。也可以将该文件下载后,用文本编辑器打开,显示的内容是有一样的。

以后的项目里,默认都是添加 actuator 组件的。

eureka-server 用户认证

目前主要指导 eureka-server 的地址就可以访问、获取注册信息,现在来加上用户认证。

  1. 在 eureka-server 的 pom 中添加依赖

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
  2. 给 eureka-server 配置登录信息
    不同环境应该有不同的用户名和密码,这里只给出 dev 的配置文件, perf 的也需要设置。
    application-dev.yml

    spring:
      security:
        user:
          name: user
          password: 123123
  3. 访问 http://localhost:34001/ 这次被挡在了登录界面。输入用户名、密码可进入。
  4. 客户端认证链接,修改 album-provider 配置文件

    eureka:
      client:
        service-url:
          defaultZone: http://admin:123123@eureka-server-1:34001/eureka/

    此时启动会报错 com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server 。关闭 eureka-server 的 csrf 即可。

  5. 关闭 eureka-server 的 csrf 校验,给 eureka-server 添加一个配置类 ..WebSecurityConfig

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      @Override
      public void configure(HttpSecurity http) throws Exception {
        // 关闭 csrf
        http.csrf().disable();
        // 开启认证, URL 格式登录时,需要为 httpBasic
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
      }
    }
    

    依次重启 eureka-server 、 album-provider 。

项目依赖了 security 组件的情况下,如果不在配置文件中设置用户名和密码,security 会生成默认的用户名 user 和 一串随机密码,这串密码会打印到 eureka-server 的控制台,密码每次启动都会改变。所以,只要项目依赖了 security ,就要在各个 profile 里都设置认证信息。

eureka-server UI 页面上的存疑

  1. 红色提示信息

    • 信息内容 : RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
    • eureka-server 环境 : enable-self-preservation: false 的自我保护模式为关闭

wowxhycoming
0 声望1 粉丝

引用和评论

0 条评论