SpringCloud-Alibaba学习(五):OpenFeign远程调用
目录
1、介绍
SpringCloud OpenFeign 是 SpringCloud 的子项目之一,不属于第三方公司,是一种声明式、模板化的 HTTP 客户端。在 SpringCloud 中使用 OpenFeign 时,可以做到像调用本地方法一样发起远程调用,优化了编码体验。同时 OpenFeign 通过集成 Ribbon 实现了客户端的负载均衡。
- Nacos-server:注册中心,解决服务注册与发现
- Ribbon:客户端负载均衡器,解决服务集群负载均衡调用问题
- OpenFeign:声明式 HTTP 客户端,代替 RestTemplate 实现远程调用。
2、使用示例
2.1 示例说明
服务:
- cloud-openfeign-points 积分服务为服务提供者
- cloud-openfeign-order 订单服务为服务消费者
2.2 服务搭建
2.2.1 cloud-openfeign-points 服务
参考:https://www.cnblogs.com/liuyiyuan/p/16421731.html#32-搭建工程
改改配置文件的这几个配置项:
# 服务端口
server.port=9004
server.servlet.context-path=/openfeign-points
# 服务名称 必须有 保证唯一性
spring.application.name=openfeign-points
crud 接口
@RestController
@RequestMapping("/points")
public class PointsController {
List<Points> db = new ArrayList<>();
@PostMapping("/save")
public HttpResponse<Void> save(@RequestBody Points points) {
System.out.println("添加积分 "+points);
db.add(points);
return HttpResponse.success();
}
@PutMapping("/update")
public HttpResponse<Void> update(@RequestBody Points points) {
System.out.println("更新积分 " + points);
db.stream()
.filter(e -> e.getPointsId().equals(points.getPointsId()))
.peek(e -> {
e.setType(points.getType());
e.setCount(points.getCount());
});
return HttpResponse.success();
}
@DeleteMapping("/delete")
public HttpResponse<Void> deleteById(Integer pointsId) {
System.out.println("删除id=" + pointsId);
db.removeIf(e -> e.getPointsId().equals(pointsId));
return HttpResponse.success();
}
@GetMapping("/{pointsId}")
public HttpResponse<Points> findById(@PathVariable("pointsId") Integer pointsId) {
Optional<Points> optional = db.stream().filter(e -> e.getPointsId().equals(pointsId)).findFirst();
return HttpResponse.success(optional.orElse(null));
}
@GetMapping("/search")
public HttpResponse<Points> search(Integer pointsId, String type) {
System.out.println("搜索条件:" + pointsId + " " + type);
Optional<Points> optional = db.stream()
.filter(e -> e.getPointsId().equals(pointsId) && e.getType().equals(type))
.findFirst();
return HttpResponse.success(optional.orElse(null));
}
@PostMapping("/searchByEntity")
public HttpResponse<List<Points>> searchByEntity(@RequestBody Points points) {
System.out.println("搜索条件 entity:" + points);
return HttpResponse.success(db);
}
}
2.2.2 cloud-openfeign-order 服务
服务消费方使用 OpenFeign 方式进行远程调用,不再注入 RestTemplate 对象
增加 OpenFeign 的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
OpenFeign 内部也已经引入了 Ribbon 不需要额外依赖
启动类添加注解 @EnableFeignClients
启用 OpenFeign
2.2.3 接口声明
创建一个单独的 api 模块 cloud-openfeign-api
,用于暴露服务提供者的接口,同时使用 OpenFeign 的注解标注接口
api 模块由服务提供方定义,作为公共包发布出去,可以供多个消费方使用。
依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>cc.yuanspace</groupId>
<artifactId>cloud-openfeign-entity</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
/**
* 积分接口声明
*/
// value 指定服务名 path指定路径前缀,如果服务有上下文路径时使用
@FeignClient(value = "openfeign-points", path = "/openfeign-points")
@RequestMapping("/points")
public interface PointsApi {
// 方法结构与服务接口一致,只是没有方法体
@PostMapping("/save")
HttpResponse<Void> save(@RequestBody Points points);
@PutMapping("/update")
HttpResponse<Void> update(@RequestBody Points points);
/**
* 使用url参数时,@RequestParam不可以省略,必须有,用于定义参数的key
* @param pointsId
* @return
*/
@DeleteMapping("/delete")
HttpResponse<Void> deleteById(@RequestParam("pointsId") Integer pointsId);
@GetMapping("/{pointsId}")
HttpResponse<Points> findById(@PathVariable("pointsId") Integer pointsId);
@GetMapping("/search")
HttpResponse<Points> search(@RequestParam("pointsId") Integer pointsId, @RequestParam("type") String type);
@PostMapping("/searchByEntity")
HttpResponse<List<Points>> searchByEntity(@RequestBody Points points);
}
2.2.4 接口调用
服务消费方的启动类上注解添加扫描路径,扫描 @FeignClient
注解的类
可以使用 @AutoWired
注入接口的代理实现
@RestController
public class OrderController {
@Autowired
private PointsApi pointsApi;
@RequestMapping("/test")
public HttpResponse<Void> test() {
Points points = new Points(1, 10, "2");
HttpResponse<Void> response = pointsApi.save(points);
return response;
}
}
3、常用配置
# openfeign 的常用配置
# false表示当第一次发请求时才去注册中心拉取服务列表 true表示项目启动立即拉取
ribbon.eager-load.enabled=true
# 指定哪些服务立即拉取服务列表
ribbon.eager-load.clients=openfeign-points
# 设置指定服务的连接超时时间,单位 ms
feign.client.config.openfeign-points.connect-timeout=1000
# 设置指定服务的响应超时时间,单位 ms
feign.client.config.openfeign-points.read-timeout=1000
# 设置默认超时时间,单位 ms
feign.client.config.default.connect-timeout=1000
feign.client.config.default.read-timeout=1000