2019-07-22 · spring-cloud

Spring Cloud Eureka 入门案例

Netflix Eureka 是由 Netflix 开源的一款基于 REST 的服务发现组件,该组件提供的服务发现可以为负载均衡、failover 等提供支持。Eureka 包括 Eureka Server 及 Eureka Client。
Eureka Server 端采用的是 P2P 的复制模式,但是它不保证复制一定能成功,因此它提供的是一个最终一致性的服务实例试图;Client 端在 Server 端的注册信息有一个带期限的租约,一旦 Server 端在指定期间没有收到 Client 端发送的心跳,则 Server 端会认为 Client 端注册的服务是不健康的,定时任务会将其从注册表中删除。

Spring Cloud Eureka 入门案例

  1. 创建 Maven 父级工程
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.example</groupId>
<artifactId>spring-cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-demo</name>
<packaging>pom</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>


<modules>
    <module>eureka-server</module>
    <module>eureka-client</module>
</modules>

<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>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  1. 创建 eureka-server 模块
<parent>
    <groupId>com.example</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>eureka-server</artifactId>
<name>eureka-server</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

然后配置启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

添加配置参数

server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    wait-time-in-ms-when-sync-empty: 0
    enable-self-preservation: false
  1. 创建 eureka-client 模块
    <parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>eureka-client</artifactId>
    <name>eureka-client</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

添加 eureka-client 的启动类注解

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}

配置 eureka-client 的配置参数

server:
  port: 8081
spring:
  application:
    name: client
management:
  endpoints:
    web:
      exposure:
        include: '*'
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  1. 分别启动 eureka-server 和 eureka-client 并访问 http://local:8761/ 将看见如下的画面

spring-cloud-eureka-introduction-case

在 sh 环境下(windows系统可以使用 git-bash)使用 curl 命令查询 eureka 的 api

curl -i http://localhost:8761/eureka/apps

将会有如下的信息返回

HTTP/1.1 200
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Mon, 22 Jul 2019 02:36:53 GMT

<applications>
  <versions__delta>1</versions__delta>
  <apps__hashcode>UP_1_</apps__hashcode>
  <application>
    <name>CLIENT</name>
    <instance>
      <instanceId>localhost:client:8081</instanceId>
      <hostName>localhost</hostName>
      <app>CLIENT</app>
      <ipAddr>192.168.145.1</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8081</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1563762633308</registrationTimestamp>
        <lastRenewalTimestamp>1563762933256</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1563762633309</serviceUpTimestamp>
      </leaseInfo>
      <metadata>
        <management.port>8081</management.port>
      </metadata>
      <homePageUrl>http://localhost:8081/</homePageUrl>
      <statusPageUrl>http://localhost:8081/actuator/info</statusPageUrl>
      <healthCheckUrl>http://localhost:8081/actuator/health</healthCheckUrl>
      <vipAddress>client</vipAddress>
      <secureVipAddress>client</secureVipAddress>
      <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1563762633309</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1563762633214</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
</applications>

Eureka Server 的 REST API 列表简介

Eureka Server 提供了 REST API,允许非 Java 语言的其他应用服务通过 HTTP REST 的方式接入 eureka 的服务发现中。下面使用 IDEA 的 HTTP Client 脚本测试 Eureka Server 的一些 REST API 的基本操作。

### 1.查询所有应用实例
#GET http://localhost:8761/eureka/apps
GET http://localhost:8761/eureka/apps

### 2.根据 appId 查询
#GET http://localhost:8761/eureka/apps/{appId}
GET http://localhost:8761/eureka/apps/client

### 3.根据 appId 和 instanceId 查询 (instanceId为上图中红色部分)
#GET http://localhost:8761/eureka/apps/{appId}/{instanceId}
GET http://localhost:8761/eureka/apps/client/localhost:client:8081

### 4.根据 instanceId 查询
#GET http://localhost:8761/eureka/instances/{instanceId}
GET http://localhost:8761/eureka/instances/localhost:client:8081

### 5.注册新应用实例
#POST http://localhost:8761/eureka/apps/{appId}
POST http://localhost:8761/eureka/apps/client2
Content-Type: application/json

{
  "instance": {
    "instanceId": "client2:8082",
    "app": "client2",
    "appGroupName": null,
    "ipAddr": "127.0.0.1",
    "sid": "na",
    "homePageUrl": null,
    "statusPageUrl": null,
    "healthCheckUrl": null,
    "secureHealthCheckUrl": null,
    "vipAddress": "client2",
    "secureVipAddress": "clients",
    "countryId": 1,
    "dataCenterInfo": {
      "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
      "name": "MyOwn"
    },
    "hostName": "127.0.0.1",
    "status": "UP",
    "leaseInfo": null,
    "isCoordinatingDiscoveryServer": false,
    "lastUpdatedTimestamp": 1529391461000,
    "lastDirtyTimestamp": 1529391461000,
    "actionType": null,
    "asgName": null,
    "overridden_status": "UNKNOWN",
    "port": {
      "$": 8082,
      "@enabled": "true"
    },
    "securePort": {
      "$": 7002,
      "@enabled": "false"
    },
    "metadata": {
      "@class": "java.util.Collections$EmptyMap"
    }
  }
}

### 6.注销应用实例
#DELETE http://localhost:8761/eureka/apps/{appId}/{instanceId}
DELETE http://localhost:8761/eureka/apps/client2/client2:8082

### 7.暂停/下线应用实例
#PUT http://localhost:8761/eureka/apps/{appId}/{instanceId}/status?value=OUT_OF_SERVICE
PUT http://localhost:8761/eureka/apps/client/localhost:client:8081/status?value=OUT_OF_SERVICE

### 8.恢复应用实例
#DELETE http://localhost:8761/eureka/apps/{appId}/{instanceId}/status?value=UP (value参数可以不传)
DELETE http://localhost:8761/eureka/apps/client/localhost:client:8081/status

### 9.应用实例发送心跳
#PUT http://localhost:8761/eureka/apps/{appId}/{instanceId}/
PUT http://localhost:8761/eureka/apps/client/localhost:client:8081/

### 10.修改应用实例元数据
#PUT http://localhost:8761/eureka/apps/{appId}/{instanceId}/metadata?key=value
PUT http://localhost:8761/eureka/apps/client/localhost:client:8081/metadata?profile=canary

###