springcloud-Feign 基于服务端的负载均衡(六)
简介
- Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端
- Feign默认集成了Ribbon
- 因为集成了Ribbon,所以Feign拥有Ribbon的一些功能,如负载均衡等。
- 利用Ribbon维护了服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
- Ribbon是通过微服务的名称进行访问的,Feign是通过接口进行访问的。
- Ribbon是在consumer消费方配置的,Feign是在provider服务提供方进行配置的。
下面我们将通过consumer访问在common模块配置的feign接口来访问provider资源接口。
springcloud-provider-8001 关键代码
- controller
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/dept/add")
public boolean addDept(@RequestBody Dept dept) {
return deptService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept getDept(@PathVariable("id") Long id) {
Dept dept = deptService.queryById(id);
if (dept == null) {
throw new RuntimeException("Fail");
}
return dept;
}
@GetMapping("/dept/list")
public List<Dept> queryAll() {
return deptService.queryAll();
}
}
- 需要注册到Eureka
修改子工程 springcloud-common 模块添加Feign 的service
- pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
- service 我们把服务提供方的feign调用写到common模块,这样多个consumer都可以从这访问
package com.dong.common.service;
import com.dong.common.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// @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 boolean addDept(Dept dept);
}
新建 springcloud-consumer-81 子模块
- pom.xml
<dependencies>
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.dong</groupId>
<artifactId>springcloud-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
- application
server:
port: 81
spring:
application:
name: consumer2
eureka:
client:
register-with-eureka: false # 不向 Eureka注册自己
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: consumer2 #用于修改eureka中实例的status描述(不写eureka会提供默认的描述)
- 启动类
package com.dong.consumer2;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.dong.common.service"})
public class ConsumerTwoApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerTwoApplication.class, args);
}
}
- controller
package com.dong.consumer2.controller;
import com.dong.common.pojo.Dept;
@RestController
public class DeptConsumerController {
@Autowired
private DeptClientService deptClientService;
/**
* 消费方添加部门信息
* @param dept
* @return
*/
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
return deptClientService.addDept(dept);
}
/**
* 消费方根据id查询部门信息
* @param id
* @return
*/
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return deptClientService.queryById(id);
}
/**
* 消费方查询部门信息列表
* @return
*/
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return deptClientService.queryAll();
}
}
测试
启动eureka7001,springcloud-consumer-81 ,springcloud-consumer-81
访问:http://localhost:81/consumer/dept/list
结果:
[{"deptno":1,"dname":"开发部","dbSource":"springcloud"},{"deptno":2,"dname":"人事部","dbSource":"springcloud"},{"deptno":3,"dname":"财务部","dbSource":"springcloud"},{"deptno":4,"dname":"市场部","dbSource":"springcloud"},{"deptno":5,"dname":"运维部","dbSource":"springcloud"},{"deptno":6,"dname":"“管理部”","dbSource":"springcloud"},{"deptno":7,"dname":"销售部","dbSource":"springcloud"}]
访问:http://localhost:81/consumer/dept/get/2
结果:{"deptno":2,"dname":"人事部","dbSource":"springcloud"}