Spring Cloud Eureka 注册中心
序
服务发现对于微服务和基于云的应用程序至关重要,主要有两个原因。
- 它为应用团队提供了快速地在环境中运行的服务实例数量进行水平伸缩。
- 它有助于提高应用程序的弹性,当微服务实例变得不健康或不可用时,服务发现引擎从内部可用服务列表中移除该实例。
构建Spring Eureka 服务
- 添加依赖项到pom.xml
......
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
......
- 在application.yml 文件中创建Eureka配置
......
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 5
......
registerWithEureka 属性会告知服务,在Spring Boot Eureka 应用程序启动时不要通过Eureka服务注册,因为它本身就是Eureka服务。
fetchRegistry属性设置为false,以便Eureka服务启动时,它不会尝试在本地缓存注册表信息。
每次服务注册需要30s的时间才能显示在Eureka服务中,因为Eureka需要从服务接收3次连续心跳包ping,每次心跳包ping间隔10s,然后才能使用这个服务。在部署和测试时要牢记这一点。
- 标注引导类以启用Eureka服务器
......
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication{
public static void main(String[] args){
SpringApplication.run(EurekaServerApplication.class,args);
}
}
......
通过Spring Eureka 注册服务
使用SpringBoot构建服务消费者
- 添加Spring Eureka依赖项到服务消费客户端pom.xml文件中
......
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
......
- 修改服务发现客户端的application.yml文件以便与Eureka通信
spring:
application:
name: userService
profiles:
active:
default
cloud:
config:
enabled: true
eureka:
instance:
preferIpAddress: true
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
使用服务发现来查找服务
1. 使用Spring DiscoveryClient 来查找服务实例
Spring DiscoveryClient 提供了对Ribbon和Ribbon中缓存的注册服务的最低层次访问。使用Spring DiscoveryClient, 可以查询通过Ribbon注册的所有服务以及这些服务对应的Url。
- 创建引导类以使用Spring Discovery Client
@SpringBootApplication
@EnableDiscoveryClient
public class Application{
public static void main(Sting[] args){
SpringApplication.run(Application.class, args);
}
}
- 使用DiscoveryClient查找信息
@Component
public class DiscoveryClient {
@Autowired
private DiscoveryClient discoveryClient; // 被自动注入
public User getUser(String userId){
RestTemplate restTemplate = new RestTemplate();
List<ServiceInstance> instances = discoveryClient.getInstances("userService");
if(instances.size()==0) return null;
String serviceUri = String.format("%s/v1/user/%s"), instances.get(0).getUri().toString(), userId);
ResponseEntiy<User> restExchange = restTemplate.exchange(
serviceUri,
HttpMethod.GET,
null, User.class, userId
);
return restExhange.getBody();
}
}
2. 使用带有Ribbon 功能的 Spring RestTemplate
这是通过Spring与Ribbon进行交互的更为常见的机制之一。
- 标注和定义RestTemplate构造方法
......
@SpringBootApplication
@EnableDiscoveryClient
public class Application{
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
......
- 使用支持Ribbon的RestTemplate来调用服务
@Component
public class UserRestTemplateClient {
@Autowired
RestTemplate restTemplate;
public User getUser(String userId){
ResponseEntity<User> restExchange = restTemplate.exchange(
"http://userService/v1/users/{userId}",
HttpMethod.GET,
null, User.class, userId
);
}
}
3. 使用Netflix Feign 客户端调用服务
Netflix Feign 客户端库是Spring启用Ribbon的RestTemplate类的替代方案。
- 在服务消费客户端中启用Spring Cloud/Netflix Feign客户端
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application{
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
- 定义用于调用组织服务的Feign接口
@FeignClient("userService")
public interface UserFeignClient{
@RequestMapping(
method = Request.GET,
value = "v1/users/{userId}",
consumes = "application/json"
)
User getUser(@PathVariable("userId") String userId);
}