通过CompletableFuture对上游接口进行多次调用的优化

通过CompletableFuture对上游接口进行多次调用的优化

问题描述

我在开发设备列表页面时,需要向上游平台请求设备的在线离线状态,但是上游平台只有获取单个设备点位值的接口,并没有批量获取设备点位值的接口,这就导致我需要在for循环中调用上游接口,这样导致我的接口响应时长达到了30s以上。

原有代码

public void getDeviceStatus(List<String> deviceIds) {
    for (String deviceId : deviceIds) {
        // 调用上游平台接口
        Map<String, Integer> deviceStatusMap = queryDeviceParamValue(deviceId,"online_status");
		// 后续操作省略
    }
}

解决方案

  1. 让上游平台编写一个批量查询设备点位值的接口、
  2. 通过CompletableFuture异步多线程调用上游接口(注意:该方法要看上游平台接口能否负荷多线程的调用)

总结

方案一因为上游平台的源码并不在我们手中,等待乙方开发又太慢了,而且设备列表页设备不会超过100台,故最多同时调用100次上游平台的接口,经过测试上游平台可以承受,故采用方案二。

代码如下:

public void getDeviceStatus(List<String> deviceIds) {
	// 将deviceIds转换为CompletableFuture,
    // 每个 CompletableFuture 对象都会异步执行queryDeviceParamValuet方法,查询设备参在线状态
    List<CompletableFuture<Map<String, Integer>>> futures = iotDeviceIds.stream()
                .map(iotDeviceId -> CompletableFuture.supplyAsync(() -> {
                    // 调用上游平台接口
                    return queryDeviceParamValue(deviceId,"online_status");
                }))
                .collect(Collectors.toList());
    // 等待所有任务完成,并获取结果
    List<Map<String, Integer>> list = futures.stream().map(CompletableFuture::join)
            .collect(Collectors.toList());
    // 后续操作省略
}

这样我们接口的响应时长从30s降低为不到1s

FeignClient是Netflix开源的一款轻量级HTTP客户端库,它允许你在Spring Boot应用中声明式地调用RESTful API,简化了服务之间的集成。为了通过FeignClient快速定位到上游服务接口并进行远程调用,你可以按照以下步骤操作: 1. **添加依赖**:首先,你需要在你的Maven或Gradle构建文件中添加Feign和Spring Cloud Netflix的依赖。 Maven: ```xml <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-feign</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-spring</artifactId> </dependency> ``` Gradle: ```groovy implementation 'io.springfox:springfox-boot-starter' implementation 'com.netflix.feign:feign-core' implementation 'com.netflix.feign:feign-spring' ``` 2. **创建接口**:在你的项目中定义一个接口,这个接口将代表上游服务的API。例如,如果上游有`UserService`接口,你将在本地创建一个`UserFeignApi.java`。 ```java @ FeignClient(name = "upstream-service", url = "${upstream.service.url}") public interface UserFeignApi { @GetMapping("/users/{id}") User getUser(@PathVariable("id") Long id); } ``` `@FeignClient`注解用于指定服务名和URL,并可以从环境变量获取URL。 3. **使用接口**:现在你可以在需要调用上游服务的地方使用这个Feign接口,就像调用本地方法一样。例如,在控制器或业务层: ```java @Autowired private UserFeignApi userFeign; public User getUser(Long id) { return userFeign.getUser(id); } ``` 4. **配置启动项**:确保在Spring Boot的配置中启用Feign客户端,如添加@EnableFeignClients注解到启动类上。 ```java @SpringBootApplication @EnableFeignClients public class AppApplication { ... } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值