目录
本文导读
Eureka Client 创建流程
新建 Eureka-Client 应用
pom.xml 文件
application.yml
启动测试
Instances currently registered with Eureka
spring.application.name
IP 地址代替主机名注册
Changing the Eureka Instance ID
Using the 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
1、Include Eureka Client(导入 Eureka Client 组件):
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
2、Registering with Eureka(注册服务到 Server 端的注册表中):
1)导入 spring-cloud-starter-netflix-eureka-client 后,应用程序将自动向 Eureka 服务器注册,但是需要在配置文件中定位Eureka 服务器,application.yml:
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
2)eureka.client.serverUrl.defaultZone:Eureka Server 端也会配置这一项,这里只需要指向 Server 端提供的地址即可。
当客户端向 Eureka Server 注册时,客户端会提供关于自身的元数据——例如主机、端口、健康标志 URL、主页和其他详细信息。Eureka Server 接收服务注册表中所有实例的心跳消息,如果心跳超时,则实例会从注册表中删除。
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组件)。
1、应用生成之后 pom.xml 文件内容默认如下:
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
www.wmx.com
EurekaClient_cat
0.0.1-SNAPSHOT
EurekaClient_cat
Demo project for Spring Boot
1.8
Greenwich.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
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 实例了。
1、上面 Eureka Client 注册到了 Eureka Server 上,现在来开始研究细节,服务端的 Spring Eureka 主页截图如下:
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 就会显示设置好的应用名称
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。
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 主页如下:
1、可以使用 com.netflix.discovery.EurekaClient 对象来获取 Eureka 服务器上服务实例,官网:
https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RELEASE/single/spring-cloud-netflix.html#_using_the_eurekaclient
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 "请携带 applicationName 参数...
";
}
/**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 "" + applicationName + " 微服务名不存在...
";
}
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();
}
}
5、com.netflix.discovery.EurekaClient 除了获取 com.netflix.appinfo.InstanceInfo,还可以获取其它有用的对象,需要时自行查找,访问客户端 changSha-cat 测试结果如下: