Eureka简述
Eureka采用了CS的设计架构,EurekaServer作为服务注册功能的服务器,它是服务注册中心,而系统中的其他微服务,使用EurekaClient客户端连接到EurekaServer并维持心跳连接,系统维护人员可以通过EurekaServer来监控系统中各个微服务是否正常运行。
EurekaServer提供服务注册服务:各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer的服务注册表中就会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
EurekaClient通过注册中心进行访问:用于简化客户端与EurekaServer的交互,同时具备一个内置的,使用轮训负载算法的负载均衡器。在应用启动后,将会向EurekaServer发送心跳包(默认周期30秒),如果EurekaServer在多个心跳周期内(默认90秒)没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除。
代码
Eureka注册中心(两个注册中心eureka7001和eureka7002,注册中心集群可以实现负载均衡和故障容错)
pom.xml
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
......
</dependencies>
eureka7001
application.yaml配置文件
server:
port: 7001
eureka:
client:
register-with-eureka: false #不将自己注册进自己
fetch-registry: false #不从eureka服务端抓取注册的服务的信息
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #只有自己这一eureka注册中心的话就填写自己的服务端的地址
defaultZone: http://eureka7002.com:7002/eureka/ #如果除了自己之外还有别的eureka注册中心,在需要填写除了自己之外的注册中心地址列表,多个地址用逗号隔开
instance:
hostname: eureka7001.com #eureka注册中心域名
ApplicationMain启动类
@SpringBootApplication
@EnableEurekaServer //开启eureka服务端
public class ApplicationContextMain7001 {
public static void main(String[] args) {
SpringApplication.run(ApplicationContextMain7001.class);
}
}
eureka7002
application.yaml配置文件
server:
port: 7002
eureka:
client:
register-with-eureka: false #不将自己注册进自己
fetch-registry: false #不从eureka服务端抓取注册的服务的信息
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #只有自己这一eureka注册中心的话就填写自己的服务端的地址
defaultZone: http://eureka7001.com:7001/eureka/ #如果除了自己之外还有别的eureka注册中心,在需要填写除了自己之外的注册中心地址列表,多个地址用逗号隔开
instance:
hostname: eureka7002.com #eureka注册中心域名
ApplicationMain启动类
@SpringBootApplication
@EnableEurekaServer //开启eureka服务端
public class ApplicationContextMain7002 {
public static void main(String[] args) {
SpringApplication.run(ApplicationContextMain7002.class);
}
}
支付微服务(一个支付微服务名称下注册了两个实例,payment8001和payment8002)
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
......
<dependencies>
payment8001
application.yaml配置文件
server:
port: 8001
spring:
application:
name: cloud-payment #注册到注册中心时使用的微服务名称
eureka:
client:
register-with-eureka: true #应用启动时将自己注册到注册中心
fetch-registry: true #从注册中心获取所有已注册的微服务信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #注册中心地址列表,多个地址用逗号隔开
instance:
instance-id: payment8001 #实例名
prefer-ip-address: true #在eureka界面里鼠标悬浮到实例名上时左下角显示ip
ApplicationMain启动类
@SpringBootApplication
@EnableEurekaClient //开启eureka客户端
public class ApplicationContextMain8001 {
public static void main(String[] args) {
SpringApplication.run(ApplicationContextMain8001.class);
}
}
payment8002
application.yaml配置文件
server:
port: 8002
spring:
application:
name: cloud-payment #注册到注册中心时使用的微服务名称
eureka:
client:
register-with-eureka: true #应用启动时将自己注册到注册中心
fetch-registry: true #从注册中心获取所有已注册的微服务信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #注册中心地址列表,多个地址用逗号隔开
instance:
instance-id: payment8002 #实例名
prefer-ip-address: true #在eureka界面里鼠标悬浮到实例名上时左下角显示ip
ApplicationMain启动类
@SpringBootApplication
@EnableEurekaClient //开启eureka客户端
public class ApplicationContextMain8002 {
public static void main(String[] args) {
SpringApplication.run(ApplicationContextMain8002.class);
}
}
业务代码
@RestController
public class PaymentController {
@Autowired
PaymentService paymentService;
//应用部署的端口号
@Value("${server.port}")
String port;
@GetMapping("/payment/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") int id){
Payment payment = paymentService.getPaymentById(id);
return new CommonResult(200, "success:" + port, payment);
}
}
订单微服务
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
......
<dependencies>
application.yaml配置文件
server:
port: 80
spring:
application:
name: cloud-order #注册到注册中心时使用的微服务名称
eureka:
client:
register-with-eureka: true #应用启动时将自己注册到注册中心
fetch-registry: true #从注册中心获取所有已注册的微服务信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #注册中心地址列表,多个地址用逗号隔开
instance:
instance-id: order #实例名
prefer-ip-address: true #在eureka界面里鼠标悬浮到实例名上时左下角显示ip
ApplicationMain启动类
@SpringBootApplication
@EnableEurekaClient //开启eureka客户端
@EnableDiscoveryClient //开启服务发现
public class ApplicationContextMain80 {
public static void main(String[] args) {
SpringApplication.run(ApplicationContextMain80.class);
}
}
业务代码
@Configuration
public class CustomizeConfiguration {
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@RestController
public class OrderController {
//远程调用的工具
@Autowired
RestTemplate restTemplate;
//获取已注册微服务信息的工具
@Autowired
DiscoveryClient discoveryClient;
//CLOUD-PAYMENT为微服务名称,应用先用该名称到注册中心获取调用地址,再远程调用该地址
public static final String url = "http://CLOUD-PAYMENT";
@GetMapping("/order/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") int index) {
return restTemplate.getForObject(url + "/payment/" + index, CommonResult.class, (Object) null);
}
@GetMapping("/infos")
public void getDiscoveryInfos(){
//获取所有已注册的微服务名称
List<String> services = discoveryClient.getServices();
System.out.println(services);
//获取指定微服务名称下的实例
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT");
for (ServiceInstance serviceInstance:instances){
//打印实例地址
System.out.println(serviceInstance.getUri());
}
}
}
Eureka注册中心主界面
以eureka7001为例,打开网址http://eureka7001.com:7001
修改EurekaClient发送心跳包的周期以及超时剔除的时间
eureka:
instance:
lease-renewal-interval-in-seconds: 30 #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认30秒)
lease-expiration-duration-in-seconds: 90 #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认90秒),超时将剔除服务
Eureka保护模式
保护模式作用
进入Eureka注册中的主页(上边创造了两个注册中心,我们以eureka7001为例,浏览器访问http://eureka7001.com:7001),可以看到这一行红字,表示已经进入保护模式
自我保护模式:默认情况下已注册的EurekaClient会定时(默认间隔30秒)向EurekaServer发送心跳包,告诉EurekaServer该微服务可用。如果EurekaServer在一定时间内(默认90秒)没有收到心跳包,便会直接从服务注册表中剔除该服务,但是如果在短时间(90秒)内丢失了大量的服务实例心跳,EurekaServer就会开启自我保护机制,不会剔除该服务(考虑到短时间大量丢实例心跳包很可能是由于网络不通而非EurekaClient不可用而造成误杀,核心理念是CAP中的AP)。
保护模式主要用于对一组客户端和EurekaServer之间存在网络分区场景下的保护,一旦进入保护模式,EurekaServer将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。
关闭保护模式
Eureka默认开启保护模式,我们也可以通过在EurekaServer端的配置文件中手动配置来关闭保护模式
eureka:
server:
enable-self-preservation: false #关闭保护模式
eureka界面显示这行红字表示已关闭自我保护模式