feign和ribbon是Spring
Cloud的Netflix中提供的两个实现软负载均衡的组件,Ribbon和Feign都是用于调用其他服务的,方式不同。Feign则是在Ribbon的基础上进行了一次改进,采用接口的方式。
pom文件
<!--ribbon-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<!--eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
1.启动类使用的注解不同,Ribbon 用的是@RibbonClient,Feign 用的是@EnableFeignClients
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "SPRINGCLOUD-PRIOVIDER-DEPT", configuration = myRule.class)
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {
"com.gjf.springcloud"})
2.服务的指定位置不同,Ribbon 是在@RibbonClient 注解上声明,Feign 则是在定义抽象方法的接口中使用@FeignClient 声明
@Configuration
public class ConfigBean {
//配置负载均衡实现RestTemplate
//IRule
// RoundRobinRule 轮询
//RetryRule 先按照轮询获取服务,失败,则在指定时间重式
@Bean
@LoadBalanced //Ribbon开启负载均衡的功能
public RestTemplate getRestTemplate() {
return new RestTemplate(); }}
@Component
@FeignClient(value = "SPRINGCLOUD-PRIOVIDER-DEPT")
public interface DeptClientService {
@PostMapping("/dept/add")
public boolean addDept(Dept dept);
@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id")Long id);
@GetMapping("/dept/all")
public List<Dept> queryAll();
}
3.调用方式不同,Ribbon 需要自己构建 http 请求,模拟 http 请求然后使用 RestTemplate 发送给其他服务,步骤相当繁琐。
Ribbon 创建RestTemplate
@RestController
public class DeptConsumerController {
//消费者无service层
@Autowired
private RestTemplate restTemplate;
// private static final String REST_URL_PREFIX = "http://localhost:8001";
//Ribbon地址是个变量
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PRIOVIDER-DEPT";
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
@RequestMapping("/consumer/dept/all")
public List<Dept> deptList() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/all", List.class);
}
}
Feign使用抽象方法的接口注入
@Autowired
private DeptClientService deptClientService;
@Component
@FeignClient(value = "SPRINGCLOUD-PRIOVIDER-DEPT")
public interface DeptClientService {
@PostMapping("/dept/add")
public boolean addDept(Dept dept);
@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id")Long id);
@GetMapping("/dept/all")
public List<Dept> queryAll();
}
@RestController
public class DeptConsumerController {
//消费者无service层
@Autowired
private RestTemplate restTemplate;
// private static final String REST_URL_PREFIX = "http://localhost:8001";
//Ribbon地址是个变量
/* private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PRIOVIDER-DEPT";*/
@Autowired
private DeptClientService deptClientService;
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
/* return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);*/
return this.deptClientService.queryById(id);
}
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
/* return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);*/
return deptClientService.addDept(dept);
}
@RequestMapping("/consumer/dept/all")
public List<Dept> deptList() {
/*return restTemplate.getForObject(REST_URL_PREFIX + "/dept/all", List.class);*/
return deptClientService.queryAll();
}
}