SpringCloud之Feign(声明式服务调用)

tech2026-03-09  4

SpringCloud之Feign(声明式服务调用)

​ 前面已经介绍了Ribbon和Hystrix了,可以发现的是:他俩作为基础工具类框架广泛地应用在各个微服务的实现中。我们会发现对这两个框架的使用几乎是同时出现的,并且使用RestTemplate还是不方便,我们每次都要使用RestTemplate进行远程调用

​ 为了简化我们的开发,Spring Cloud Feign出现了!它基于 Netflix Feign 实现,整合了 Spring Cloud Ribbon 与 Spring Cloud Hystrix, 除了整合这两者的强大功能之外,它还提供了声明式的服务调用(不用RestTemplate)。

1.Feign是一种声明式、模板化的HTTP客户端。 2.在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验, 开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。

一.使用feign实现服务间的调用

cloud-provider-product8080服务
@RestController @Slf4j public class ProductFeignClient implements IProductFeignApi { @Autowired private IProductService productService; @Override public Product get(Long id) { log.info("ProductFeignClient..get..."); Product product = productService.get(id); //模拟网络延迟 /* try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }*/ //演示异常后,走降级操作 //int i = 1 / 0; return product; } }
cloud-product-api接口
//接口 //重要注解name--->指定调用哪个服务器 fallback--->降级操作 @FeignClient(name = "PRODUCT-SERVER", fallback =ProductFeignHystrix.class) public interface IProductFeignApi { @GetMapping("/products/get/{id}") Product get(@PathVariable("id") Long id); } -------------------------------------------------------------------------------------- //使用feign方式降级 //该类用于product-server服务对外提供接口进行降级保护 //实现IProductFeignApi 接口 目的是为类指定哪些方法需要进行降级处理 @Component public class ProductFeignHystrix implements IProductFeignApi { //IProductFeignApi 接口里面的get方法的降级方法 @Override public Product get(Long id) { System.out.println("走降级方法了..ProductFeignHystrix.."); return new Product();; } }

cloud-consumer-order8090调用product服务
@Service @Slf4j public class OrderServiceImpl implements IOrderService { @Autowired private IProductFeignApi productFeignApi; @Override public Order save(Long userId, Long productId) { log.info("OrderServiceImpl.save...."); //使用feign方式调用服务 Product product = productFeignApi.get(productId); return new Order(); } }
通过上面可以看出Feign优雅地实现了远程调用,并且集成了 Hystrix和Ribbon ,默认轮询方式
依赖pom.xml
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
yml
server: port: 8090 spring: application: name: order-server eureka: client: #是否将自己注册进去eureka,false为不注册,true注册 registerWithEureka: true #是否从eureka抓取注册信息,单点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: #eureka客户端向服务端发送心跳的时间间隔,单位为秒,默认是30 lease-renewal-interval-in-seconds: 1 #eureka服务端收到最后一次心跳等待的时间上限,单位为秒,默认是90,超时剔除 lease-expiration-duration-in-seconds: 2 feign: client: config: default: connectTimeout: 4000 readTimeout: 4000 #开启hystrix,记得一定要开启,默认关闭 hystrix: enabled: true
启动类
@SpringBootApplication @EnableEurekaClient @EnableFeignClients //用于告诉框架扫描所有通过注解@FeignClient定义的feign客户端 @EnableCircuitBreaker //@EnableHystrix继承了@EnableCricuitBreaker public class OrderMain8090 { public static void main(String[] args) { SpringApplication.run(OrderMain8090.class, args); } }

二.feign的实现原理(底层还是通过ribbon实现远程调用)

三.Feign超时概念

1.源码中默认options中配置的是6000毫秒,但是Feign默认加入了Hystrix,此时默认是1秒超时, 我们可以通过修改配置,修改默认超时时间 2.feign的默认超时时间1,如果超时,默认会再发一次请求 3.这个默认重试一次操作,开发中需要慎重设置 假设请求是查询操作,可以配置重试 假设请求是添加操作,不能配置重试操作,如果硬要配置,需要让接口变为幂等函数
1.模拟网络延迟,超时后重试机制

2.当超时后会默认再发起一次请求

3.yml超时设置
#设置5秒 feign: client: config: default: #请求连接超时时间 connectTimeout: 4000 #请求处理的超时时间 readTimeout: 4000
4.Feign超时重试次数设置
# Max number of retries on the same server (excluding the first try) #超时重试次数,0表示不重试 sample-client.ribbon.MaxAutoRetries=0 # Max number of next servers to retry (excluding the first server) #集群中重试几个服务器 sample-client.ribbon.MaxAutoRetriesNextServer=1
5.超时时间调整
现在组件有ribbon feign hystrix 都有超时控制,该如何选择? 推荐方案: feign或者hystrix > 调用正常业务耗时 hystrix > feign //hystrix的超时时间应该最大

四.小结

1.Feign是一种声明式、模板化的HTTP客户端 2.Feign集成了ribbon和Hystrix,并且提供了声明式的服务调用,使远程服务调用更加方便 3.Feign中集成的Hystrix默认是关闭的,我们需要在yml配置文件中将其设置为true,则开启 4.feign中有超时重试机制,我们也可以通过修改配置文件来控制重试 5.启动类中需要贴@EnableFeignClients 注解,表示开启feign; 接口上需要贴@FeignClient注解,并指定调用服务名和降级方法; 降级方法需要实现接口 6.具体步骤: 在Spring cloud应用中,当我们要使用feign客户端时,一般要做以下三件事情 : 1.启动类中使用注解@EnableFeignClients启用feign客户端 2.使用注解@FeignClient 定义feign客户端 ,将远程服务http:/xxx映射为一个本地Java方法调用 3.使用注解@Autowired注入使用上面所定义feign的客户端

最新回复(0)