什么是Spring Cloud Eureka?
- Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责实现微服务架构中的服务治理功能。
- Spring Cloud Eureka 是一个基于 REST 的服务,并且提供了基于 Java 的客户端组件,能够非常方便地将服务注册到 Spring Cloud Eureka 中进行统一管理。
为什么需要注册中心
注册中心的作用
微服务应用和机器越来越多,调用方需要知道接口的网络地址,如果靠配置文件的方式去控制网络地址,对于动态新增机器,url地址维护带来很大问题
注册中心提供服务注册与发现功能,对服务的url地址进行统一管理.
服务提供者Provider的作用
启动的时候向注册中心上报自己的网络信息
服务消费者Consumer的作用
启动的时候向注册中心上报自己的网络信息,拉取provider的相关网络信息
主流的注册中心
这四款注册中心都支持和SpringCloud集成
- zookeeper
- Eureka
- consul
- etcd
Eureka服务注册中心
创建一个SpringBoot Initialize项目,选择Cloud Discover->Eureka Server
pom,加上spring-cloud-starter-netflix-eureka-server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
eureka服务端配置:
把application.properties修改成application.yml,配置都要用yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动项目,访问:http://localhost:8761
SpringCloud Eureka 自我保护机制
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。
我们在单机测试的时候很容易满足心跳失败比例在 15 分钟之内低于 85%,这个时候就会触发 Eureka 的保护机制,一旦开启了保护机制,则服务注册中心维护的服务实例就不是那么准确了,此时我们可以使用eureka.server.enable-self-preservation=false来关闭保护机制,这样可以确保注册中心中不可用的实例被及时的剔除(不推荐)
Eureka服务提供者
在Eureka中,服务提供者和服务消费者是Eureka client提供的,使用注解@EnableEurekaClient
标明
新建SpringBoot Initializer项目选择Cloud Discover->Eureka Discover
配置
server:
port: 8081
spring:
application:
name: eureka-service-provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: true
fetch-registry: true
@EnableEurekaClient
指定eureka client,部署后,注册信息发布到eureka server
提示:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
SpringCloud警告(Eureka):EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
警告!Eureka可能存在维护了错误的实例列表(当它们没有启动的时候,Eureka却把它当成启动的了);Renews值小于Threshold值,因此剩下未过期的都是安全的。
具体可以进行配置,配置成eureka server的ip,加上actuator
eureka:
instance:
status-page-url-path: http://localhost:8761/actuator/info
health-check-url-path: http://localhost:8761/actuator/health
Eureka服务消费者
Spring cloud有两种最常用的服务调用方式,一种是ribbon+restTemplate,另一种是feign
ribbon+resttemplate方式,Spring Cloud Hoxton.SR6版本不需要引入spring-cloud-starter-netflix-ribbon,已经默认集成
微服务调用方式Ribbon
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
引入web既可,主要是想调restTemplate
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
yml配置
server:
port: 8082
spring:
application:
name: eureka-service-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
register-with-eureka: false
fetch-registry: true 消费者必须改成true
微服务调用方式Feign
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@FeignClient
指定服务名称,@RequestMapping
指定要调用的接口
@FeignClient(name = "product-server")
public interface ProductFeignApi {
@RequestMapping("/api/v1/product/find")
Product find(@RequestParam("id") Long id);
}
@RestController
public class ProductFeignClient implements ProductFeignApi {
@Autowired
private IProductService productService;
@Value("${server.port}")
private String port;
@Override
public Product find(Long id) {
Product product = productService.get(id);
Product result = new Product();
BeanUtils.copyProperties(product,result);
result.setName(result.getName()+",data from "+port);
return result;
}
}
Feign超时时间设置
源码中默认options中配置的是6000毫秒,但是Feign默认加入了Hystrix,此时默认是1秒超时。我们可以通过修改配置,修改默认超时时间。
配置
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
Feign超时重试次数设置
Max number of retries on the same server (excluding the first try)
sample-client.ribbon.MaxAutoRetries=0
Max number of next servers to retry (excluding the first server)
sample-client.ribbon.MaxAutoRetriesNextServer=1
PRODUCT-SERVER:
ribbon:
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 0