如何高效的处理第三方接口数据?

很多公司业务都需要进行第三方接口的对接工作,特别是那种大部分数据都来自第三方的项目。比如亚马逊商家服务的saas系统,基本上所有的数据都来自亚马逊平台。

背景

像这种需要定期获取亚马逊接口数据,然后存储到本地数据库中的项目,一般就会涉及到数据转换过程。这边我将会给大家介绍一个实际项目案例,平台从亚马逊获取数据,进行解析的过程中,因为数据过大,导致内存溢出的场景。

接口说明

亚马逊平台返回的是json格式数据,然后通过jackson进行json解析,将最后的解析结果保存到我们自己的数据库中。但是json反序列也是需要技巧的,否则会因为使用不当导致内存溢出。

json解析

一开始我们通过jackson工具类,将json流解析为JsonNode,如下所示:

ObjectMapper mapper = new ObjectMapper();

JsonNode root = mapper.readTree((GZIPInputStream) reportMap.get(“data”));

但是当请求量过大的时候,内存中就会出现大量的LinkHashMap、Entry、HashMap、Node之类的集合对象,时间一长就OOM内存溢出了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解析改造

集合对象如果没有管理好,会很难被GC回收,所以一开始我们想到的办法是将JsonNode设置为null,后面发现这样做没起到任何作用,所以只能进行彻底的改造,直接用jackson解析成我们需要的对象,如下所示:

private List parseJsonIO(GZIPInputStream gzipInputStream) {

ObjectMapper mapper = new ObjectMapper();

List advertisementDtoList =new ArrayList<>();

try {

advertisementDtoList = mapper.readValue(gz
ipInputStream, new TypeReference<List>() {

});

} catch (IOException e) {

logger.error(“parseJsonIO转化异常,错误信息为:{}”, ExceptionUtil.formatException(e));

}

return advertisementDtoList;

}

修改完之后可以很明显的看到,LinkHashMap、Entry、HashMap、Node之类的对象数量大量减少,内存的占用率明显降低,大大的减少了内存OOM的风险。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

深入改造

写到这一步是不是就优化完毕了呢?不!!!一开始的时候我是将所有的字段全部设置为String,然后通过Long.value()和Integer.value()转换为数据库需要的字段类型,如下所示:

campaignSearchTermReport.setImpressions(Integer.valueOf(impressions));

campaignSearchTermReport.setTotalspend(Long.valueOf(cost));

campaignSearchTermReport.setSales(BigDecimal.valueOf(sales));

所以为了避免这种情况发生,我们需要将转换的对象字段提前设置好,数据库需要什么类型,我们就设置为同样的类型,这样的好处就是我们不需要进行转型,直接就可以set进去,如下所示:

@Data

@JsonIgnoreProperties(ignoreUnknown = true)

public class ReportAdvertisementDto {

private double cost;

private String attributedSales1d;

private int impressions;

private int clicks;

private long campaignId;

private String campaignName;

private String adGroupName;

private long adId;

private long adGroupId;

private String sku;

private String asin;

private long keywordId;

private String matchType;

private String query;

private String keywordText;

private int attributedConversions7d;

private double attributedSales7d;

private int attributedUnitsOrdered7d;

private int attributedConversions7dSameSKU;

private double attributedSales7dSameSKU;

}

总结

在数据量不大的情况下,代码就算效率不高,也不会出现什么问题,但是当数据量达到一定级别,代码问题就会被凸显出来。比如我们平时用Map来存储临时数据,但是map集合的大小要比对象更加占用内存,如果服务器硬件不高,很容易就发生内存溢出。

所以我们在处理接口数据的时候,一定要本着简单、适用。尽量不要将json数据解析为map等集合,对象字段尽量设置为和入库的的表字段类型一致,减少转型的发生。禁止出现大量对象和对象之间数据流转,尽量做到一个解析后的对象直接入库,不需要进行任何转型操作。
想学习分布式、微服务、JVM、多线程、架构、java、python的童鞋,千万不要扫码,否则后果自负~

林老师带你学编程https://wolzq.com

最后

小编这些年深知大多数初中级工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此我收集整理了一份《2024年Java全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你需要这些资料,⬅专栏获取
S0u5sAPe-1719684124748)]

[外链图片转存中…(img-VtQm0Uug-1719684124748)]

[外链图片转存中…(img-ESIy3uK6-1719684124748)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你需要这些资料,⬅专栏获取

  • 11
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值