Java 小白,刚入门 SpringBoot 项目练手,现有一个需求要将本地数据库中的设备信息表批量发送给第三方 API 接口,本地设备信息表由用户导入,表结构如下:
id 为主键,device_ip 为设备 IP 地址信息,host_id 为第三方系统 API 返回的设备 ID 值,其他列为设备的相关属性参数。
[td]id[/td]
[td]device_ip[/td]
[td]host_id[/td]
[td]device_attr_1[/td]
[td]……[/td]
1
x.x.x.x
1359652
aaaaaa
……
2
y.y.y.y
8496143
bbbbb
……
当用户点击“插入”操作后,需要将表中所有的数据,按照规定的 JSON 格式,将其发送给第三方系统的 API 接口。
如果执行成功,第三方系统 API 接口会返回设备 ID 值,将其保存到表中对应设备条目的 host_id 值中。
如果执行失败,第三方系统 API 接口会返回 error 消息,需要记录未成功添加的设备清单,供用户核查。
目前是写了一个异步方法,读取全表的设备信息为放入一个 List ,根据要求构造 JSON 数据,一条一条发送,每次 API 请求预计消耗 0.1-0.2s ,当数据量达到万级以上时,整个添加过程会达到半小时,时间太长。
现在想缩短整个添加过程的时长,目前在认知范围内考虑两种改进方向:
方案一
将这个 List 通过多线程的方式访问 API 接口传送数据,但因为对于多线程模式不是很了解,不知道会不会造成数据不一致的问题,因为需要记录 API 返回的 host_id 值。虽然初步查了一下资料,但是还是没有很清楚的概念具体应该如何实现。
方案二
该第三方 API 接口,允许一次传入多个设备的数据,但一次最多只能传 100 条左右的数据。考虑将整个 List 拆成 100 个一组,每组里面包含 100 个设备信息的 JSON 数据,将这 100 个数据给 API 发送一次。
但是这 100 条信息如果其中有任意一台添加失败,会导致所有这 100 台全都添加失败,API 只会返回添加失败信息,并不会指明哪一条数据添加异常,所以考虑此方法还需要在发生 API 请求失败时,切换成一条一条添加,这样就可以判断出哪一条数据添加异常,以便将无法添加的条目反馈供用户核验,这样也能保证无异常的设备都可以被添加进第三方系统中。这种方法时间起来感觉逻辑较复杂。
求助
因为新手没什么项目经验,不知道那种方案比较合适,或者是否有其他更优的解决方案,谢谢!
目前 Service 的部分逻辑代码如下:
import ...
@EnableAsync
@Service
public class MonitorServiceImpl implements IMonitorService
{
@Autowired
private MonitorInfoMapper monitorInfoMapper;
@Async
@Override
public void startMonitor()
{
List equipmentList = monitorInfoMapper.selectEquipmentList();//获取数据表中所有设备清单
for (Equipment equip : equipmentList) {
//..............
//处理数据,构造 JSON 数据格式,最后将一台设备信息放入 hostInfoJSON 变量
//iApiService 写的第三方访问接口
String creatHostResp = iApiService.insertHostList(authToken, hostInfoJSON);
String hostid;
if (creatHostResp.contains("error")) {
hostid = "-1";
JSONObject resposeJson = JSONObject.parseObject(creatHostResp);
String errorString = resposeJson.getJSONObject("error").getString("data");
log.info("添加失败!错误信息:" + errorString);
} else {
JSONObject resposeJson = JSONObject.parseObject(creatHostResp);
List hostIdList = new ArrayList();
JSONArray resposeHostIdList = resposeJson.getJSONObject("result").getJSONArray("hostids").getString(0);
log.info("添加成功,hostid:" + hostIdList);
}
equip.setHostId(hostid);
monitorInfoMapper.updateEquipment(equip);
}
//......
}