Feign:负载均衡(基于客户端)
# 4. Feign:负载均衡 (基于客户端)
# 4.1 Feign 简介
Feign 是声明式 Web Service 客户端,它让微服务之间的调用变得更简单,类似 controller 调用 service。SpringCloud 集成了 Ribbon 和 Eureka,可以使用 Feigin 提供负载均衡的 http 客户端
Feign,主要是社区版,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务访问两种方法
- 微服务名字 【ribbon】
- 接口和注解 【feign】
feign 和 ribbon 是 Spring Cloud 的 Netflix 中提供的两个实现软负载均衡的组件,Ribbon 和 Feign 都是用于调用其他服务的,方式不同。Feign 则是在 Ribbon 的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建 http 请求。不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。
# 4.2 Feign 使用
- 改造 springcloud-api 模块代码
添加依赖
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
1
2
3
4
5
6
2
3
4
5
6
新建 service 包,并新建 DeptClientService.java 接口
@Component
// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {
@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id") Long id);
@GetMapping("/dept/list")
public Dept queryAll();
@GetMapping("/dept/add")
public Dept addDept(Dept dept);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 创建 springcloud-consumer-dept-feign 模块
拷贝 springcloud-consumer-dept-80 模块下的 pom.xml,resource,以及 java 代码到 springcloud-consumer-feign 模块,并添加 feign 依赖。
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
1
2
3
4
5
6
2
3
4
5
6
启动类上添加注解开启 Feign
@SpringBootApplication
@EnableEurekaClient
// feign客户端注解,并指定要扫描的包以及配置接口DeptClientService
@EnableFeignClients(basePackages = {"com.kuang.springcloud"})
// 切记不要加这个注解,不然会出现404访问不到
//@ComponentScan("com.kuang.springcloud")
public class FeignConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeignConsumer_80.class,args);
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Feign:修改 controller
@RestController
public class DeptConsumerController {
@Autowired
private DeptClientService deptClientService;
@PostMapping("/consumer/dept/add")
public boolean add(Dept dept){
return deptClientService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept getById(@PathVariable("id") Long id){
return deptClientService.queryById(id);
}
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return deptClientService.queryAll();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Ribbon
@RestController
public class DeptConsumerController {
@Autowired
private RestTemplate restTemplate;
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
// postForObject(服务提供方地址(接口),参数实体,返回类型.class)
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
// getForObject(服务提供方地址(接口),返回类型.class)
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Feign 和 Ribbon 二者对比,前者显现出面向接口编程特点,代码看起来更清爽,而且 Feign 调用方式更符合我们之前在做 SSM 或者 SprngBoot 项目时,Controller 层调用 Service 层的编程习惯!
# 4.3 Feign 和 Ribbon 选择
根据个人习惯而定,如果喜欢 REST 风格使用 Ribbon;如果喜欢社区版的面向接口风格使用 Feign。
Feign 本质上也是实现了 Ribbon,只不过后者是在调用方式上,为了满足一些开发者习惯的接口调用习惯!
编辑 (opens new window)
上次更新: 2024/06/09, 21:19:54