eureka注册续约流程
- 启动注册中心
- 服务提供者生产服务并注册到服务中心中
- 消费者从服务中心中获取服务并执行
服务提供
1.在spring-cloud-manage下创建一个子项目producer-service
pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>producer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<finalName>producer-service</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.创建启动类
Finchley版本已经不需要添加@EnableDiscoveryClient注解,Spring Cloud会自动识别。
@SpringBootApplication
public class ProducerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerServiceApplication.class, args);
}
}
3.配置文件
spring.application.name=producer-service
server.port=9001
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
spring.application.name=producer-service
server.port=9001
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
- spring.application.name 服务提供者的名字
- server.por 服务端口号
- eureka.client.serviceUrl.defaultZone eureka的服务注册地址,如果eureka是多节点,多个地址逗号分隔,具体可以看上一篇博客:服务注册与发现。
多节点eureka服务注册如下:
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/,http://localhost:8002/eureka/
4.Action or Controller类
@RestController
@RequestMapping(value = "/test")
public class ProducerAction {
@RequestMapping(value = "", method = RequestMethod.GET)
public String test(String param) {
return "param is " + param;
}
}
@RestController
@RequestMapping(value = "/test")
public class ProducerAction {
@RequestMapping(value = "", method = RequestMethod.GET)
public String test(String param) {
return "param is " + param;
}
}
5.启动服务
服务启动后,访问eureka主页http://localhost:8001/,即可看到如下页面,说明服务已经注册到eureka上了
6.调用下试试
访问http://localhost:9001/test?param=test,看到返回结果如下
param is test
服务消费 ribbon
Ribbon 了,它是一个基于 HTTP 和 TCP 的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList 来设置服务端列表去轮询访问以达到均衡负载的作用。
当 Ribbon 与 Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务实例列表。同时它也会用 NIWSDiscoveryPing 来取代 IPing,它将职责委托给 Eureka 来确定服务端是否已经启动。
1.在spring-cloud-manage下创建一个子项目consumer-service
pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring-cloud-starter-netflix-eureka-client中已经引用了ribbon先关的jar,所需不需要再引入了
2.创建启动类
@SpringBootApplication
public class ConsumerServiceApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
@SpringBootApplication
public class ConsumerServiceApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
3.配置文件
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
4.Action or Controller类
这里注入restTemplate,Spring Cloud Ribbon 自己有拦截器会对 服务名producer-service做解析,自动的去选取服务实例负载均衡调用,并将服务名替换成实际要请求的IP地址和端口
@RestController
@RequestMapping(value = "/ribbon/test")
public class ConsumerAction {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "", method = RequestMethod.GET)
public String test(String param) {
String url = "http://producer-service/test/?param=" + param;
return restTemplate.getForObject(url, String.class);
}
}
5.启动服务
消费端服务启动成功后,可以看到erueka时已经显示注册成功了
5.调用消费端服务
访问http://localhost:9002/ribbon/test?param=ribbon-test ,可以看到如下结果,说明消费端服务接收到参数后,通过ribbon负载均衡,调用到producer-service的接口。
param is ribbon-test
控制台日志
2018-08-28 16:25:23.397 INFO 3791 --- [nio-9002-exec-1] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-08-28 16:25:23.414 INFO 3791 --- [nio-9002-exec-1] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-producer-service
2018-08-28 16:25:23.433 INFO 3791 --- [nio-9002-exec-1] c.netflix.loadbalancer.BaseLoadBalancer : Client: producer-service instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=producer-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2018-08-28 16:25:23.440 INFO 3791 --- [nio-9002-exec-1] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2018-08-28 16:25:23.462 INFO 3791 --- [nio-9002-exec-1] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-08-28 16:25:23.463 INFO 3791 --- [nio-9002-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client producer-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=producer-service,current list of Servers=[192.168.101.238:9001],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:192.168.101.238:9001; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@12e48993
2018-08-28 16:25:24.447 INFO 3791 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
可以启动多个producer-service服务测试下实际的负载均衡效果。
服务消费 feign
Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码和解码。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
在实际工作中,我们基本上都是使用Feign来完成调用的。我们通过一个例子来展现 Feign 如何方便的声明对 eureka-producer 服务的定义和调用。
1.consumer-service添加对feign的依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.启动类上加上feign所需注解
@EnableFeignClients
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
@EnableFeignClients
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
3.配置文件
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
#开启Hystrix断路器
feign.hystrix.enabled=true
#断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试,缺省为1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
#开启Hystrix断路器
feign.hystrix.enabled=true
#断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试,缺省为1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
4.feign 调用
创建feign客户端调用类,其中name为所需调用的服务名,fallback使用Hystrix,当producer-service不可用时,对服务做降级,并返回友好提示
@FeignClient(name = "producer-service", fallback = ProducerServiceFeignClientHystrix.class)
public interface ProducerServiceFeignClient {
@RequestMapping(value = "/test", method = RequestMethod.GET)
String test(@RequestParam("param") String param);
}
==注意@RequestParam("param")中name必须要和producer-service服务中的参数名一致==
@Component
public class ProducerServiceFeignClientHystrix implements ProducerServiceFeignClient {
@Override
public String test(String param) {
return "服务[producer-service]无法访问";
}
}
访问http://localhost:9002/feign/test?param=feign-test,可以看到如下结果
param is feign-test
停止producer-service,再次访问http://localhost:9002/feign/test?param=feign-test,可以看到如下结果,说明fallback已经生效了
服务[producer-service]无法访问