目录
什么是OpenFeign
OpenFeign的官方解释是一种声明式、模板化的HTTP客户端。提供HTTP远程调用的方法,让远程调用更简单。
OpenFeign底层内置了Ribbon,所以其调用也是负载均衡的。
未使用OpenFeign
Controller使用RestTemplate进行第三方调用,比较繁琐
使用了OpenFeign
OpenFeign基础使用
新建一个项目用于测试openFeign
一、pom依赖
之前在父项目已经引入了spring-cloud,现在在父项目再引入OpenFegin的依赖,子项目就可以都使用了
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
二、yml配置文件
server:
port: 8086
spring:
application:
name: openfeign-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: '*'
三、启动类添加注解
@SpringBootApplication
@EnableDiscoveryClient
// openFeign注解,添加该注解后,该服务就可以使用openFeign
@EnableFeignClients
public class OpenfeignConsumer8086Application {
public static void main(String[] args) {
SpringApplication.run(OpenfeignConsumer8086Application.class, args);
}
}
四、Service层
package com.cloud.openfeignconsumer8086.service;
import com.cloud.cloudalibabacommons.entity.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 此接口就是配合使用OpenFeign的接口,
* 在此接口中添加@FeignClient接口,
* 同时标注要调用的服务端名称,
* 使用与服务提供者方法签名一致的抽象方法来表示远程调用的具体内容
*/
@Service
// 远程调用的服务名称
@FeignClient("nacos-provider")
public interface OpenFeignService {
/**
* 此方法表示远程调用demo/info/{id}接口
*/
@GetMapping("data/info/{id}")
public JsonResult<String> info(@PathVariable("id") Long id);
}
五、Controller层
@RestController
@RequestMapping("demo")
public class DemoController {
@Autowired
private OpenFeignService openFeignService;
@GetMapping("getInfo/{id}")
public JsonResult<String> getInfo(@PathVariable("id") Long id){
return openFeignService.info(id);
}
}
控制超时时间
OpenFeign 客户端默认等待1秒钟,但是如果服务端业务超过1秒,则会报错。可以通过自定义配置来设置OpenFeign的请求过时时间。
由于OpenFeign 底层是ribbon 。所以超时控制由ribbon来控制。在yml文件中配置:
#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
日志打印
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节
日志级别
-
NONE:默认的,不显示任何日志;
-
BASIC:仅记录请求方法、URL、响应状态码及执行时间;
-
HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
-
FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
具体使用
启动类
@SpringBootApplication
@EnableDiscoveryClient
// openFeign注解,添加该注解后,该服务就可以使用openFeign
@EnableFeignClients
public class OpenfeignConsumer8086Application {
public static void main(String[] args) {
SpringApplication.run(OpenfeignConsumer8086Application.class, args);
}
@Bean
Logger.Level feignLoggerLevel(){
//开启详细日志
return Logger.Level.FULL;
}
}
配置文件
logging:
level:
# openfeign日志以什么级别监控哪个接口
com.cloud.openfeignconsumer8086.service.OpenFeignService: debug
访问时可以看到日志记录:
Sentinel整合OpenFeign
pom依赖
<!-- sentinel依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- openFeign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
yml配置
# 激活Sentinel对openFeign的支持
feign:
sentinel:
enabled: true
# 方便查看日志
logging:
level:
com.cloud.cloudalibabacustomer8084.service.FeignService: debug
Service接口
// 注入到Spring容器
@Service
/**
* value属性定义访问服务的名称
* fallback属性定义异常的处理,在调用第三方服务时,一旦抛出了异常(例如网络异常、超时异常等),
* 由fallback定义的对应接口实现方法来处理具体逻辑
*/
@FeignClient(value="nacos-provider",fallback = FeignServiceImpl.class)
public interface FeignService {
@GetMapping("/data/info/{id}")
public JsonResult<String> info(@PathVariable("id") Long id);
}
Service实习类——处理Feign调用的异常
// 注入到Spring容器
@Component
/**
* fallback对应写了该类,该类也需要去实现使用Feign的接口,
* 保持一致的对应关系
*/
public class FeignServiceImpl implements FeignService {
/**
* 此处重写的方法可以理解为服务降级
* 当服务消费者无法远程调用时,进入该方法处理,
* 此时可以通过fallback给出另一套解决方案,
* 例如:调用2.0接口出问题了,那么此时可以去调用1.0接口
* @param id
* @return
*/
@Override
public JsonResult<String> info(Long id) {
return new JsonResult<String>(446,"网络调用异常,请联系系统管理员");
}
}
控制器类
@Autowired
private FeignService feignService;
@GetMapping("getInfo/{id}")
public JsonResult<String> getInfo(@PathVariable("id") Long id){
return feignService.info(id);
}