首先要知道一点Feign的负载均衡是Ribbon来实现的。
Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(Hystrix熔断保护机制),可以让我们不再需要显式地使用这两个组件。
Feign具有如下特性:
可插拔的注解支持,包括Feign注解和JAX-RS注解;
支持可插拔的HTTP编码器和解码器;
支持Hystrix和它的Fallback;
支持Ribbon的负载均衡;
支持HTTP请求和响应的压缩。
Feign的使用
举个栗子:我有一个orders-server服务,和一个user-server-3000服务,user-server-3000服务做了集群user-server-3001,
orders-server服务要访问user-server服务。这时就需要Ribbon来实现权重均衡。轮询user-server-3000和user-server-3001服务
1.在orders-server的pom.xml导包spring-cloud-starter-openfeign
<!-- feign依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.在order-server的配置类中添加@EnableFeignClients("接口包的全限定名")注解
/** * @EnableFeignClients * 开启feign的客户端 * * ("cn.itsorce.spring.feignclient") * 接口的权限定包名,不是必要的 * 因为: * @EnableFeignClients扫描所有使用注解@FeignClient定义的feign客户端 */ @SpringBootApplication @EnableFeignClients("cn.itsorce.spring.feignclient") public class OrdersServerApplication { public static void main(String[] args) { SpringApplication.run(OrdersServerApplication.class); } }
3.在cn.itsorce.spring.feignclient包下创建个接口
/** * @FeignClient(value="user-server")负载均衡客户端的名字 * */ @FeignClient(value = "user-server") public interface UserFeignClient {
/**
*
* 这个方法是和user-server的controller的方法
* 方法名要和user-server的controller的方法,(返回值,方法名,参数,,requestMapping)一样
*
* @param id
* @return
*/
@GetMapping("/user/{id}") User getUserById(@PathVariable("id")Long id); }
4.在orders-server的controller注入接口,在方法中调用接口的方法实现负载均衡(黄色背景的是主要代码)
@RestController public class OrderConsumerController { /** * 注入feign的接口 */ @Autowired private UserFeignClient feignClient; /** * 该方法是浏览器来调用 * @param id * @return */ @GetMapping("/order/user/{id}") public User getUserById(@PathVariable("id") Long id){ User user = feignClient.getUserById(id); return user; } }
5.重启服务,就行了。
修改负载均衡的机制:
如果要把轮询机制改成随机机制
在orders-server配置类中添加代码
@Bean public IRule ribbonRule() { // 负载均衡规则,改为随机 return new RandomRule(); }
重启服务,就行了。