<!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
package com.feign; import com.domain.Goods; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * * feign声明式接口:用于发起远程调用 * * 1. 定义接口 * 2. 接口上添加注解 @FeignClient,并设置 value 属性为服务提供者的应用名称 * 3. 编写调用接口,接口的声明规则和提供方接口保持一致(返回值和方法名可自定义) * 4. 注入该接口对象,调用接口方法完成远程调用(自动拼接value与接口URI) */ @FeignClient(value="eureka-provider") public interface GoodsFeignClient { @GetMapping("/goods/findOne/{id}") public Goods findGoodsById(@PathVariable("id") int id); }
package com.controller; import com.domain.Goods; import com.feign.GoodsFeignClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * 服务调用方 */ @RestController @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; @Autowired private GoodsFeignClient goodsFeignClient; // IDEA 提示报错也无需理会 @GetMapping("/goods/{id}") public Goods findOrderByGoodsId(@PathVariable("id") int id) { // // String url = String.format("http://eureka-provider/goods/findOne/%d", id); // Goods goods = restTemplate.getForObject(url, Goods.class); Goods goods = goodsFeignClient.findGoodsById(id); return goods; } }
package com; import com.config.MyRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient // 激活 DiscoveryClient @EnableEurekaClient @SpringBootApplication @RibbonClient(name="eureka-provider", configuration= MyRule.class) // 指定服务提供方并配置负载均衡策略 @EnableFeignClients // 开启 Feign 功能 public class ConsumerApp { public static void main(String[] args) { SpringApplication.run(ConsumerApp.class, args); } }
Ribbon默认 1 秒超时。
超时配置修改如下:
# 配置消费端 Ribbon 的超时时间 ribbon: ConnectTimeout: 1000 # 连接超时时间,默认 1s(默认单位毫秒) ReadTimeout: 3000 # 逻辑处理的超时时间,默认 1s(默认单位毫秒)
Feign 只能记录 debug 级别的日志信息。
消费端 application.yml:
# 设置当前的日志级别 debug(feign 只支持记录 debug 级别的日志) logging: level: com: debug # 指定包名或类名的日志级别
package com.consumer.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignLogConfig { /* NONE:不记录 BASIC:记录基本的请求行、响应状态码等日志信息 HEADERS:记录基本的请求行、响应状态码、响应头等日志信息 FULL:记录完整的请求、响应数据等日志信息 */ @Bean public Logger.Level level(){ return Logger.Level.FULL; } }
package com.feign; import com.domain.Goods; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * * feign声明式接口:用于发起远程调用 * * 1. 定义接口 * 2. 接口上添加注解 @FeignClient,并设置 value 属性为服务提供者的应用名称 * 3. 编写调用接口,接口的声明规则和提供方接口保持一致(返回值和方法名可自定义) * 4. 注入该接口对象,调用接口方法完成远程调用(自动拼接value与接口URI) */ @FeignClient(value="eureka-provider", configuration=FeignLogConfig.class) // 加入日志配置 public interface GoodsFeignClient { @GetMapping("/goods/findOne/{id}") public Goods findGoodsById(@PathVariable("id") int id); }