目录

本文导读

Eureka Client 创建流程

新建 Eureka-Client 应用

pom.xml 文件

application.yml 

启动测试

Instances currently registered with Eureka

spring.application.name

IP 地址代替主机名注册

Changing the Eureka Instance ID

EurekaClient 获取注册的服务实例


本文导读

1、《Spring Boot 搭建 Eureka Servrer · 单机模式》中已经搭建好了 Eureka Server(应用名为EurekaServer_shenZhen ),本文将创建 Eureka Client 端应用(EurekaServer_cat),然后让 EurekaServer_cat 将服务注册到 EurekaServer_shenZhen 上。

2、看本文的同时可以结合 Spring Cloud Netflix 官网文档:Service Discovery: Eureka Clients

Eureka Client 创建流程

1、Include Eureka Client导入 Eureka Client 组件):

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

2、Registering with Eureka注册服务到 Server 端的注册表中):

1)导入 spring-cloud-starter-netflix-eureka-client 后,应用程序将自动向 Eureka 服务器注册,但是需要在配置文件中定位Eureka 服务器,application.yml:

2)eureka.client.serverUrl.defaultZone:Eureka Server 端也会配置这一项,这里只需要指向 Server 端提供的地址即可。

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

当客户端向 Eureka Server 注册时,客户端会提供关于自身的元数据——例如主机、端口、健康标志 URL、主页和其他详细信息。Eureka Server 接收服务注册表中所有实例的心跳消息,如果心跳超时,则实例会从注册表中删除。

新建 Eureka-Client 应用

1、环境:Java JDK 1.8 + Spring Boot 2.1.3 + Spring Cloud(Greenwich.RELEASE) + Maven 3.5.2 + Eureka 2.1.0 + IDEA 14.

2、可以直接在 https://start.spring.io/ 网页上快速初始化应用进行创建,然后下载、解压,最后倒入到开发工具中。

3、也可以使用 IDEA 创建,如下所示选择 web 组件(因为创建 web应用)、Eureka Discovery(Eureka 发现组件,也就是 Client组件)。

pom.xml 文件

1、应用生成之后 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.3.RELEASE</version>
        <relativePath/>
        <!-- lookup parent from repository -->
    </parent>
    <groupId>www.wmx.com</groupId>
    <artifactId>EurekaClient_cat</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>EurekaClient_cat</name>
    <description>Demo project for Spring Boot</description>

    <!-- 使用的 Spring Cloud 版本为 Greenwich-->
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <!--web 组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <!-- spring boot 测试模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud 依赖管理-->
            <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>

application.yml 

1、根据官网“Registering with Eureka”指示,在全局配置文件中配置如下:

#配置 Eureka Client
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

1)defaultZone:其中的地址就是 Eureka Server 配置文件中提供的访问地址,这里连接的服务端是《《Spring Boot 搭建 Eureka Servrer · 单机模式》》中搭建好的 Eureka Server。

2)如果客户端与服务端不再同一台电脑上,客户端 defaultZone 地址中的 localhost 必须换成 Eureka Server 所在的 IP 地址或域名。

3)defaultZone 的值只是 Eureka Server 的连接地址,与 Eureka Client 应用关系不大,比如没有配置 server.port,所以服务器默认为 8080 端口,没有配置 server.servlet-context-path,所以应用上下文路径为空,于是访问自己的主页仍然是 localhost:8080。

启动测试

1、导入 spring-cloud-starter-netflix-eureka-client 后,配置 eureka.client.serverUrl.defaultZone,先就可以启动测试了

2、先开启《Spring Boot 搭建 Eureka Servrer · 单机模式》中的 Eureka Server 应用,如下所示启动 Eureka Server 成功,此时没有实例注册进来。

3、然后再启动本 Eureka Client 应用,如下所示,此时 Eureka Server 上可以看到注册的 Eureka Client 实例了。

Instances currently registered with Eureka

1、上面 Eureka Client 注册到了 Eureka Server 上,现在来开始研究细节,服务端的 Spring Eureka 主页截图如下:

spring.application.name

1、Application:默认显示为 UNKNOWN(未知),这可以通过 spring.application.name 进行配置 spring 应用名(官网

2、spring.application.name 用于配置 spring 应用名,通常只是用于标识 spring 应用,而 server.servlet.context-path 是指定 web 服务器访问的应用上下文。

3、在原来的基础上追加修改 applicatiom.yml 文件如下:

#web 服务器配置
server:
  servlet:
    context-path: /EurekaClient_cat  #应用上下文路径
  port: 8080  #服务器端口

#sping 配置
spring:
  application:
    name: eureka-client-cat     #建议 spring.application.name 值全部用小写

#配置 Eureka Client
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

4、重启 Eureka Client,然后 Eureka Server 主页的 Application 就会显示设置好的应用名称

IP 地址代替主机名注册

1、默认情况下 Eureka Client 使用主机名进行注册, 如上图所示。在某些情况下,Eureka Client 最好公布服务(自己)的 IP 地址,而不是主机名。

2、设置 eureka.instance.preferIpAddress 为 true,当应用程序向 eureka 注册时,客户端会使用IP地址而不是主机名。在原基础上追加如下:

#配置 Eureka Client
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    preferIpAddress: true

3、此时再次重启 Eureka Client,Eureka Server 主页变化如下:

4、默认情况下,如果程序无法确定主机名,也会将 IP 地址发送给 Eureka Server 进行注册。如果不想使用 IP注册,而就想要使用主机名进行注册,可以明确指定主机名,配置 eureka.instance.hostname:

eureka.instance.hostname=192.168.1.20   #直接输入主机名称指定
eureka.instance.hostname=${HOST_NAME}   #使用环境变量在运行时设置主机名

5、注意:这里介绍的是 “使用主机名还是使用IP地址进行服务注册”,主机名或者IP并不是注册后的服务实例的ID(Instance ID),Status 列下的绿色字表示 Instance ID。

Changing the Eureka Instance ID

1、一个普通的 Netflix Eureka 实例注册的后的 ID 等于它的主机名(此时spring.application.name、server.port 等都未配置),形如:SC-201707281232,于是默认情况下每个主机只有一个服务。

2、Spring Cloud Eureka 提供了一个合理的默认值,其定义如下:

${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}

也就是说默认情况下使用 “主机名:spring应用名:服务器端口” 作为注册的服务实例 ID 值。如:myhost:myappname:8080

3、如果自己想指定实例 ID值,则覆盖配置:eureka.instance.instanceId 即可,在原基础上修改如下,手动写死实例ID:

#配置 Eureka Client
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    preferIpAddress: true
    instanceId: wangMaoXiong

此时重启 Eureka Client 后,Eureka Server 主页如下:

4、此外官方还介绍了一种方式,就是 Eureka Client 每次向服务端进行注册的时候使用一串随机值(UUID),这样每次注册完成后 Instance ID 的都会不一样。application.yml:

eureka:
  instance:
    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

随机值来自后面的 vcap,如上所示生成的实例 ID 就是 spring应用民:UUID随机值,当然前面的 spring应用名可以缓存其它的值。

将如上这一行替换 application.yml 中的旧值,然后重启 Eureka Client ,此时 Eureka Server 主页如下:

EurekaClient 获取注册的服务实例

1、可以使用 com.netflix.discovery.EurekaClient对象来获取 Eureka 服务器上服务实例,官网:Spring Cloud Netflix

InstanceInfo EurekaClient.getNextServerFromEureka(String virtualHostname, boolean secure)

1、获取下一个可能的服务实例,以处理从eureka接收的注册表信息中的请求。
2、注意:如果服务是多实例,下一个服务是以循环方式选择的,默认情况下,此方法只返回当前使用的服务器。
3、virtualHostname:虚拟主机名称,Eureka 服务端主页中 application 选项下的服务名称
    如果没有找到指定的 virtualHostname,则抛出异常:java.lang.RuntimeException: No matches for the virtual host name
4、secure:表示是否为 https 方式

Applications EurekaClient.getApplications():获取注册中心全部的应用/服务信息。
Application Applications.getRegisteredApplications(String appName):获取给定应用程序名称的所有已注册应用程序的列表。
List<Application> Applications.getRegisteredApplications():从eureka获取所有注册的<em>应用程序</em>的列表。
List<InstanceInfo> Application.getInstances(): 获取与此特定应用程序关联的实例列表。

2、Eureka 客户端 changSha-cat 配置如下:

server:
  port: 9394

spring:
  application:
    name: eureka-client-cat

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9502/eureka/
  instance:
    prefer-ip-address: true
    instance-id: changSha-cat

3、此时启动 Eureka 客户端连接成功后,Eureka 服务器仪表盘中显示如下,可以看到注册中心注册了若干个微服务实例:

4、假如现在需要获取注册中心这些 Eureka 客户端的实例信息,则可以使用 com.netflix.discovery.EurekaClient API。 在客户端 changSha-cat 中新建一个 SystemController ,从浏览器发起请求或者指定微服务实例信息。

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
public class SystemController {
    @Resource
    private EurekaClient eurekaClient;
    /**
     * 根据指定的微服务名称,获取它的实例信息
     *
     * @param applicationName :在 Eureka 服务器上注册的微服务名称
     * @return
     */
    @GetMapping("eureka-instance")
    public String getEurekaInstance(String applicationName) {
        if (applicationName == null || "".equals(applicationName)) {
            return "<p style='color:red'>请携带 applicationName 参数...</p>";
        }
        /**InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secure) 根据虚拟主机名获取 eureka 实例信息
         * virtualHostname:虚拟主机名称,Eureka 服务端主页中 application 选项下的服务名称
         * 如果没有找到指定的 virtualHostname,则抛出异常:java.lang.RuntimeException: No matches for the virtual host name
         * secure:表示是否为 https 方式
         */
        InstanceInfo instanceInfo;
        try {
            instanceInfo = eurekaClient.getNextServerFromEureka(applicationName, false);
        } catch (Exception e) {
            return "<p style='color:red'>" + applicationName + " 微服务名不存在...</p>";
        }
        String actionTypeName = instanceInfo.getActionType().name();
        String appGroupName = instanceInfo.getAppGroupName();
        String hostName = instanceInfo.getHostName();
        String id = instanceInfo.getId();
        String instanceId = instanceInfo.getInstanceId();
        String ipAddr = instanceInfo.getIPAddr();
        String healthCheckUrl = instanceInfo.getHealthCheckUrl();
        String homePageUrl = instanceInfo.getHomePageUrl();//返回如:http://172.27.35.7:8000/

        //将所有数据封装成 json 格式返回,这样网页上看起来会更加清晰
        JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
        ObjectNode objectNode = nodeFactory.objectNode();
        objectNode.put("actionTypeName", actionTypeName);
        objectNode.put("appGroupName", appGroupName);
        objectNode.put("hostName", hostName);
        objectNode.put("id", id);
        objectNode.put("instanceId", instanceId);
        objectNode.put("ipAddr", ipAddr);
        objectNode.put("healthCheckUrl", healthCheckUrl);
        objectNode.put("homePageUrl", homePageUrl);

        return objectNode.toString();
    }
}

https://gitee.com/wangmx1993/eureka_client2020/blob/master/src/main/java/com/wmx/eureka_client2020/controller/SystemController.java

5、com.netflix.discovery.EurekaClient 除了获取 com.netflix.appinfo.InstanceInfo,还可以获取其它有用的对象,需要时自行查找,访问客户端 changSha-cat 测试结果如下:

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐