SpringCloud Eureka 简单使用


1 说明

因为 SpirngBoot, SpringCloud 的各个版本之间差异还是挺大的, 所以在参照本博客进行学习时, 有可能出现因为版本不一致, 而出现不同的问题。
如果可以和本项目使用的环境保持一致, 即使不一致, 也尽可能不要跨大版本。

环境清单

框架 版本
JDK 1.8
Spring Boot 2.1.4.RELEASE
Spring Cloud Greenwich.SR1

2 准备

  1. 先建立一个 Maven 的父模块, 也就是整个项目里面只有一个 pom 文件
  2. 在父 pom 里面添加一些共用的配置, 比如 SpringBoot, SpringCloud 的依赖
<?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>

    <!-- 手动引入 spring boot 版本依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>lcn29.github.io</groupId>
    <artifactId>spring-cloud-eureka</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencyManagement>
        <dependencies>
            <!-- 手动引入 spring cloud 对应的配置 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 手动 引入 spring cloud 的基础模块-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
    </dependencies>

    <!-- 省略一些打包相关的配置 -->
</project>

3 建立一个单机的 Eureka 服务端 (注册中心)

  1. 在父模块里面新建一个子模块, 模块名 eureka-server-one
  2. 在子模块引入 Eureka 服务端需要的依赖
<dependencies>
    <!-- eureka 服务端的依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>
  1. 在启动类上加上注解 @EnableEurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerOne {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerOne.class, args);
    }
}
  1. 项目这时会一直在报错, 因为当前应用会把自己当做一个服务注册到服务端, 此处需要停止它的这个行为, 在 SpringBoot 的配置文件 application.yml (Maven 模块是没有这个文件的, 需要在 src/main/ 下面建立一个 resources 文件夹, 然后在里面创建这个文件), 加上这 2 个配置
# 应用的名字
spring:
  application:
    name: eureka-server-one
eureka:
  client:
    # 禁止把自己注册到 eureka 的服务端
    register-with-eureka: false
    # 不从 eureka 服务端拉取节点信息
    fetch-registry: false
    # eureka 的服务端的注册地址, 告诉客户端服务的地址(让其知道去哪注册)
    service-url:
      defaultZone: http://localhost:8080/eureka/
  1. 通过浏览器访问 http://localhost:8080/, 就能看到 eureka 的管理页面

  2. 这时候虽然程序运行起来的, 但是如果你查看页面的 General Info 项里面的 unavailable-replicas 会发现我们的 eureka 服务端显示为不可用的, 但实际它是可用的。

自此, 我们的 Eureka 的服务端就可以了。

4 建立一个 Eureka 客户端

  1. 在父模块里面建立一个子模块, 模块名eureka-client-one
  2. 在子模块引入 Eureka 客户端需要的依赖
<!-- eureka 服务端的依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<!-- web 功能的支持, 没有这个 客户端就会启动完就结束程序 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 然后在启动类上加上注解 @EnableEurekaClient
@EnableEurekaClient
@SpringBootApplication
public class EurekaClientOne {
    public static void main(String[] args){
        SpringApplication.run(EurekaClientOne.class, args);
    }
}
  1. application.yml 中添加配置
spring:
  application:
    name: eureka-client-one
server:
  port: 9091

eureka:
  client:
    service-url:
      # 服务端的注册地址
      defaultZone: http://localhost:8080/eureka/
  1. 打开 eureka 的服务端界面, 可以看到 Instances currently registered with Eureka 项里面有刚刚启动的客户端的ApplicationName, 同时状态为 UP, 说明客户端已经注册到服务端了。

5 Eureka 客户端间服务调用

  1. 在父模块里面再建立一个子模块, 模块名eureka-client-two, 作为服务的调用方

  2. 依赖, 启动类, 配置和 eureka-client-one 一样。 记得把 application.yml 中的 applicationName 修改为 eureka-client-two, 端口修改为另一个没有使用的, 这样我们就有 2 个客户端了

  3. eureka-client-one 作为服务的提供方, 提供一个 Rest Api 接口

    @RestController
    public class MyServerController {
    
        @GetMapping("/server/{id}")
        public String server(@PathVariable("id") int id) {
            return "收到请求Id : " + id + ", 结束";
        }
    }
  4. 服务调用方 eureka-client-two 引入 Feign, 作为服务间调用的方式

<!--远程调用-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 服务的调用方 (这里为 eureka-client-two), 创建一个接口
// name 是服务提供方的应用名
@FeignClient(name = "eureka-client-one")
public interface RemoteServer {

    // 调用的 Rest api, 入参, 出参, 请求路径方式和远程的 Rest Api 一样
    @GetMapping("/server/{id}")
    String server(@PathVariable("id")int id);
}
  1. 在调用方 eureka-client-two 的实例中, 注入刚声明的接口
@RestController
public class FeignController {

    @Resource
    private RemoteServer remoteServer;

    @GetMapping("/feign/{id}")
    public String feign(@PathVariable("id")int id) {
        String result = remoteServer.server(id);
        return result;
    }
}
  1. 在调用方 eureka-client-two 的启动类上加上注解 @EnableFeignClients
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class EurekaClientTwo {
    public static void main(String[] args){
        SpringApplication.run(EurekaClientTwo.class, args);
    }
}
  1. 依次启动 eureka-server, eureka-client-one, eureka-client-two, 然后在浏览器输入http://localhost:{eureka-client-two设置的端口}/feign/123, 可以看到收到请求Id : 123, 结束就是成功了

6 Eureka 服务端集群配置

Eureka 作为注册中心, 一旦挂了, 基本整个系统就可能无法使用了 (如果 Eureka 是在运行过一段时间后才挂的, 同时各个客户端之间都有其他客户端的缓存, 还是能通信的, 就是无法加入新节点), 所以无特殊情况, Eureka 服务端都是以集群的形式部署的。

  1. 同样的依照 eureka-server-one, 新建一个 eureka-server-two Maven 模块, 启动类, 配置, 依赖都一样。

  2. 修改 eureka-server-oneeureka-server-two 的配置

# 这个是 eureka-server-one 的配置
spring:
  application:
    name: eureka-server
server:
  port: 8081
eureka:
  client:
    service-url:
      # 向另外一个服务端注册自己, 如果有多个服务端, 通过逗号分隔就行了
      defaultZone: http://localhost:8082/eureka/


# 这个是 eureka-server-two 的配置
spring:
  application:
    name: eureka-server
server:
  port: 8082
eureka:
  client:
    service-url:
      # 向另外一个服务端注册自己, 如果有多个服务端, 通过逗号分隔就行了
      defaultZone: http://localhost:8081/eureka/      

因为是集群配置, 所以 2 个服务端的应用名都是一样的

  1. 启动项目 (第一个启动的会报错, 因为找不到需要的注册中心, 但你把第二个注册中心启动了, 就不会报错了) 依次访问 http://localhost:8081http://localhost:8082 都可以访问, 但是你会发现你的服务端都是 unavailable-replicas 的。 这是因为 eureka.client.serviceUrl.defaultZone 配置项的地址, 不能使用 localhost, 要使用域名

  2. 如果要解决服务端的 unavailable-replicas 状态, 可以临时通过修改 hosts 处理, 在电脑的 hosts 文件里面添加这 2 行

127.0.0.1 eureka-8081.com
127.0.0.1 eureka-8082.com
  1. 修改配置文件的 defaultZone 项, 同时增加 Instances的配置, 其他的都不用修改
# 这个是 eureka-server-one 的配置
eureka:
  instance:
    # 当前服务的域名
    hostname: eureka-8081.com
    # 实例的名字, 上面的applicationName可以看出一个组, 而这里是说明当前的服务是组中的哪一个
    instance-id: ${spring.application.name}:${server.port}
  client:
    service-url:
      # 向另外一个服务端注册自己, 如果有多个服务端, 通过逗号分隔就行了
      defaultZone: http://eureka-8082.com:8082/eureka/

# 这个是 eureka-server-two 的配置
eureka:
  instance:
    # 当前服务的域名
    hostname: eureka-8082.com
    # 实例的名字, 上面的applicationName可以看出一个组, 而这里是说明当前的服务是组中的哪一个
    instance-id: ${spring.application.name}:${server.port}
  client:
    service-url:
      # 向另外一个服务端注册自己, 如果有多个服务端, 通过逗号分隔就行了
      defaultZone: http://eureka-8081.com:8082/eureka/
  1. 最终的效果

Alt 'Eureka 集群配置结果'


  目录