服务间的调用
-
现有的服务调用方式
Erueka:http://ip:port/path
Ribbon:http://serviceName/path -
Feign解决了什么问题:简化远程调用
-
Feign的调用方式:@FeignClient(“service-name”)
创建Feign的消费实列
1.创建项目feign-consumer
修改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-demo</artifactId>
<groupId>com.imooc</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>feign-consumer</artifactId>
<packaging>jar</packaging>
<name>feign-consumer</name>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
2.启动类
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class FeignConsumerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(FeignConsumerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
3.配置文件
spring.application.name=feign-consumer
server.port=40001
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
- 其他相关类
@RestController
public class Controller {
@Autowired
private IService service;
@GetMapping("/sayHi")
public String sayHi() {
return service.sayHi();
}
}
@FeignClient("eureka-client")
public interface IService {
@GetMapping("/sayHi")
String sayHi();
}
在Controller 类中我可以看见直接通过方法就可以访问了!!!
启动注册中心,服务提供项目(具体代码看eureka章节),本项目,通过访问地址就可以访问到了!!!
理想的Feign风格项目结构
- 我们学习了Feign的使用方法,不知道大家有没有这样的感觉,Feign虽然简化了编写代码时调用服务的过程,但是声明接口的地方却一点也不省事。作为服务调用方,不仅需要自己创建一个接口类,还需要知道调用服务的路径和参数。在服务提供方的Controller和服务调用方的接口这两个地方,我们都需要提供同一套配置,未免有些画蛇添足了
- 理想结构
服务调用的超时重试
feign-service-provider.ribbon.OkToRetryOnAllOperations=true
feign-service-provider.ribbon.ConnectTimeout=1000
feign-service-provider.ribbon.ReadTimeout=2000
feign-service-provider.ribbon.MaxAutoRetries=2
feign-service-provider.ribbon.MaxAutoRetriesNextServer=2
以上参数设置了对feign-service-provider这个微服务的超时重试策略,我们从上往下看极值函数的给定参数。
OkToRetryOnAllOperations:这个参数指定了什么HTTP Method可以进行Retry,这里为了演示方便才设置为true,表示不管GET还是POST什么都能重试。真实的生产环境往往只是GET请求可以重试,或者实现了幂等性的其他类型请求。
ConnectTimeout:超时判定的第一个参数(单位ms),创建会话的连接时间。注意,这个不是服务的响应时间,而是本机和服务建立一个Connection所花费的时间,如果连接超时则直接进行重试。
ReadTimeout:超时判定的第二个参数,服务响应时间。当连接建立好之后,如果对方服务没有在规定时间内返回,则直接进行重试
MaxAutoRetries:求极限关键参数之一,当前节点重试次数。这里重试次数为2,那么在首次调用超时以后,会再次向同一个服务节点发起最多2次重试(总共向当前节点1+2=3次请求)。
MaxAutoRetriesNextServer:求极限关键参数之二,换N个节点重试。这里N=2,就是说在当前机器调用超时后,Feign将最多换N台机器发起调用(注意,这里将和第一个参数共同作用,也就是说,在新机器上超时后,会继续重试MaxAutoRetries+1次)。