Eureka是什么
Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于Rest的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册于发现对于微服务架构来说是非常重要的。有了服务注册与发现,只需要使用服务的标识符,就可以访问到个服务,而不需要修改服务调用的配置文件爱你了,功能类似于dubbo的注册中心,比如:zookeeper
Eureka基本架构
Eureka采用了C-S的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。
而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。SpringCloud的一些其他模块(比如:zuul)就可以通过Eureka Server来发现系统中其他的微服务。并执行相关的逻辑。
Eureka Server提供服务注册
各个节点启动后,会在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息。服务节点的信息可以再界面中直观的看到
Eureka Client是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-join)负载算法的负载均衡器。应用启动后,将会向Eureka Server发送心跳(默认是30s),如果Eureka Server在多个心跳周期内没有接受到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90s)
Eureka配置,基于这章Rest微服务案例做的把端口8001的提供者注册到7001的Eureka中
新建一个maven module 端口7001
<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>com.gcxzflgl.spring</groupId>
<artifactId>springCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springCloud-eureka-7001</artifactId>
<dependencies>
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
在resources下添加application.yml
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
编写主类测试,注意加上一个注解代表开启Eureka Server
package com.gcxzflgl.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App
{
public static void main(String[] args)
{
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
出现以上界面代表启动成功,但是发现并没有实例,我们把端口8001的提供者注册上去
修改原有的8001端口的pom.xml添加以下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
在8001的application.yml中添加eureka客户端配置
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
在8001主程序加上@EnableEurekaClient注解,服务一启动注册到Eureka服务上
我们看到应用的名字为提供者8001上提供的配置
以下有三个Status小细节的问题:
1、在企业开发中别人想看看服务都有哪些以及信息,这个Status默认的服务名字,可能让用户产生疑问,我们可以自己自定义修改服务名称
在8001端口中修改如下配置,再次运行7001:
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id:gcxzflgl
2、鼠标悬浮上地址左下角地址想要显示成ip+端口的方式,方便在多Server情况下故障分析
默认的情况下
修改8001的application.yml,再次查看运行结果
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: gcxzflgl-dept8001
prefer-ip-address: true #访问路径可以显示IP地址
3.微服务info的详细信息和说明,点击超链接后默认是Error的页面,有强迫症的程序员看到这个页面一定会非常不爽,springCloud提供了解决方案
修改8001中的pom.xml添加依赖
<!-- actuator监控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改8001中的application.yml,在最后添加
info:
app.name: springCloud
company.name: www.gcxzflgl.com
build.artifactId: $project.artifactId$
build.version: $project.version$
在父工程springCloud pom.xml添加build信息,意思是读取src/main/resources下一$开头和$结尾的配置信息
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
再次访问超链接就是自定义的info信息
当我们在进行配置修改时,可能会出现以下界面
这是Eureka的自我保护机制,什么是自我保护机制?
默认的情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90s)
但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了----因为微服务本身其实是健康的,此时不应该注销这个微服务。Eureka 通过自我保护模式来解决这个问题------当EurekaServer节点在短时间内丢失过多客户端是(可能是网络分区发生了故障),那么节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不在删除服务注册表中的数据(就是不注销改服务)。当网络故障恢复后,该EurekaServer节点会自动退出自我保护机制。
在自我保护模式中,EurekaServer会保护注册表中的系想你,不在注销任何服务实例。当他收到的心跳数重新恢复到阈值以上时,该EurekaServer节点就会自动退出自我保护模式,它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
综上,自我保护模式是一种应该网络异常的安全保护措施。可以让Eureka集群更加健壮、稳定。
服务已经注册到Eureka,下面从注册的服务中通过服务发现来获取服务信息
修改提供者DeptController,添加服务发现的代码逻辑,并且修改主类开启服务发现
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery()
{
//获取所有的服务
List<String> list = client.getServices();
System.out.println("**********" + list);
//寻找服务名称为MICROSERVICECLOUD-DEPT,打印一些相关信息
List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}
修改消费者接口80端口,从EurekaServer上调取服务
// 测试@EnableDiscoveryClient,消费端可以调用服务发现
@RequestMapping(value = "/consumer/dept/discovery")
public Object discovery()
{
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
}
自测试结果
以上是EurekaServer基本的服务注册和调用过程,也可以参考开源社区