一、定义
1)简介
Feign使得编写java http客户端变得更容易,它使用Jersey和CXF等工具为ReST或SOAP服务编写Java客户端。有了它我们就不用谢restTemplate、webClient 调用 HTTP APIs 规则的 ReSTful 接口。
Feign 10.x 需要jdk 8, 9 ,11 支持,如果是jdk 6 可以用 Feign 9.x 。
官方地址:https://github.com/OpenFeign/feign
2)原理
- 接口定义,添加@注解;
- 调用接口时,本质就是调用FeiFeignClientgn生成的动态代理;
- Feign动态代理根据接口上的@RequestMapping等注解,动态构造出调用服务的地址;
- 针对地址发起请求、解析响应;
3)Feign和Ribbon、Eureka整合
二、SpringCloud Feign的使用步骤
2.1、Eureka Service端(服务端)
1)pom文件
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2)配置文件
application.properties
#服务端端口
server.port=8761
#服务端禁用注册
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
3)启用 EurekaServer
@SpringBootApplication
//通过注解启用
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3) EurekaServer 启动成功
2.2、Eureka Clinet(服务提供端)
1)pom文件
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2)配置文件
application.properties
#服务端口
server.port=12345
bootstrap.properties
#应用名称
spring.application.name=waiter-service
3)启用 EurekaClient
@EnableDiscoveryClient 注解启用client
@SpringBootApplication
@EnableDiscoveryClient
public class WaiterServiceApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(WaiterServiceApplication.class, args);
}
}
注意:在本地启用EurekaServer,本地EurekaClient不需要配置注册地址,默认会注册上EurekaServer
4)验证启动结果
2.3、Eureka Clinet(服务消费端)
1)pom文件
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<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-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2)配置文件
application.properties
#服务端口0表示任意端口
server.port=0
#feig超时时间设置
feign.client.config.default.connect-timeout=500
feign.client.config.default.read-timeout=500
bootstrap.properties
#服务名称
spring.application.name=customer-service
3)启用Feign
@EnableFeignClients 表示启动Feign
@SpringBootApplication
@Slf4j
@EnableDiscoveryClient
@EnableFeignClients
public class CustomerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
/**
* 重新构造httpClient
* @return
*/
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.custom()
.setConnectionTimeToLive(30, TimeUnit.SECONDS)
.evictIdleConnections(30, TimeUnit.SECONDS)
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.disableAutomaticRetries()
.setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy())
.build();
}
}
4)定义interface 并加上服务提供方相关配置
@FeignClient(name = "waiter-service", contextId = "coffeeOrder")
public interface CoffeeOrderService {
@GetMapping("/order/{id}")
CoffeeOrder getOrder(@PathVariable("id") Long id);
@PostMapping(path = "/order/", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
CoffeeOrder create(@RequestBody NewOrderRequest newOrder);
}
- waiter-service 表示服务提供方服务名称;
- contextId = “coffeeOrder” 中表示 通过coffeeOrder区别服务提供方接口;
- 此interface 不需要有实现类,配置好以后直接调用;
5)调用远程接口
@Component
@Slf4j
public class CustomerRunner implements ApplicationRunner {
@Autowired
private CoffeeService coffeeService;
@Autowired
private CoffeeOrderService coffeeOrderService;
@Override
public void run(ApplicationArguments args) throws Exception {
readMenu();
}
}