1.ribbon与feign的区别
- feign是在ribbon上封装的
- ribbon请求需要自己拼接 而 Feign 是一个使用起来更加方便的 HTTP 客戶端,使用起来就像是调用自身工程的方法,而感觉不到是调用远程方法。
- feign封装了负载均衡功能
- 可以统一管理 方便复用
- 极简整合hystrix
2.spring boot使用feign+hystrix
1.修改application类
@SpringBootApplication(scanBasePackages = "com.vanpeng.cms") @ComponentScan("com.vanpeng.cms.*") @EnableCaching @EnableEurekaClient @EnableSwagger2 @EnableFeignClients #开启feign @EnableCircuitBreaker #开启hystrix //@EnableApolloConfig public class CmsApplication { public static void main(String[] args) { SpringApplication.run(CmsApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
2.修改application.yml
feign: hystrix: enabled: true #hystrix默认关闭需要 开启 ribbon: ConnectTimeout: 5000 # 请求连接的超时时间 默认的时间为 1 秒 ReadTimeout: 5000 # 请求处理的超时时间 hystrix: command: default: #default全局有效,service id指定应用有效 execution: timeout: #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据 enabled: true isolation: strategy: SEMAPHORE thread: timeoutInMilliseconds: 5000 #断路器超时时间,默认1000ms circuitBreaker: enabled: true requestVolumeThreshold: 10 #默认20 ,熔断的阈值,如何user服务报错满足3次,熔断器就会打开,就算order之后请求正确的数据也不行。 sleepWindowInMilliseconds: 8000 #默认5S , 等5S之后熔断器会处于半开状态,然后下一次请求的正确和错误讲决定熔断器是否真的关闭和是否继续打开 errorThresholdPercentage: 0.5
3.服务间调用
@FeignClient(name = "data-service", fallback = DataFallBack.class) //表明是feign接口 name为被调用服务在erueka上的服务名 public interface DataServiceFeign { @PostMapping("/selectDataSetId") //对应着被调用服务的路径 post表明为post请求 请求参数为@RequestBody ResultCatalog resultCatalog Result<Object> selectByDataSetId(@RequestBody ResultCatalog resultCatalog); @GetMapping("/resourceMenu/selectFeignService/{lecturerUserNo}") //表明为get请求 参数为 @PathVariable(value = "lecturerUserNo") Long lecturerUserNo Result<List<ResultCatalog>> selectService(@PathVariable(value = "lecturerUserNo") Long lecturerUserNo); }
4.熔断hystrix
@Component public class DataFallBack implements DataServiceFeign { //需要实现feign接口 每个方法对应着每个feign调用的服务 @Override public Result<Object> selectByDataSetId(ResultCatalog resultCatalog) { Result<Object> result = new Result<Object>(); String error = "调用系统失败。"; result.setCode(506); result.setMessage(error); return result; } @Override public Result<List<ResultCatalog>> selectServicel(Long lecturerUserNo) { Result<List<ResultCatalog>> result = new Result<>(); String error = "调用系统失败。"; result.setCode(506); result.setMessage(error); return result; } }
使用依赖注入调用即可.
public class DataServiceController { @Autowired DataServiceFeign dataServiceFeign; @Autowired SystemPortalFeign systemPortalFeign; /** * ajax数据服务 * * @param resultMapResourceCatalog * @return */ @PostMapping("/DataService") public Result DataService(@RequestBody ResultCatalog resultCatalog) { Result<Object> resultObj = dataServiceFeign.selectByDataSetId(resultCatalog); } }