首页 > 请问需要频繁的调用一个不稳定的回应慢的接口应该怎么设计比较好?

请问需要频繁的调用一个不稳定的回应慢的接口应该怎么设计比较好?

现在小弟在做一个校验系统的流程,从本地获取到一个list的表单,然后需要遍历这个表单以NO号为参数从一个接口A获取原始数据然后来校验。 现在的情况是 1.这个接口A很不稳定,经常会挂掉 2.每天的数据量还蛮大的大概有3w左右的No需要调用。接口A返回数据很慢,处理完一条在1s左右。所以这个系统必须避开高峰在规定时间内完成,当然是越快越好。

想请问这种情况应该怎么设计比较好呢。 可以考虑多线程,和缓存(因为校验是一次性的,所以在校验完之后缓存是没多大意义的)。 再次感谢。


... 不太晓得,简单想了下。
“关卡1”和“关卡2”:源接口->关卡1->关卡2->应用。
关卡1作为一种“监听”的方式存在,不断或不间断的获取数据然后储存。
而关卡2作为快速响应的存在,当应用调用时快速直接的返回或返回为空。


一般要考虑的事情包括:

设计三种状态:待校验、校验中、校验完成。(也可能需要把校验完成掰成校验失败和校验正确两种,你自己看)

启动校验时,3W条list的同步状态初始化为“待校验”

激活一组并发的多线程,比如100个。每个进程的动作:

找到一条“待校验”的行、标记“校验中”状态、填如NO发起请求、处理请求结果

    如果超时,可以重试(适合于网络拥堵、服务器忙不过来100个的情况),也可以放弃该NO弄下一个(适合于对端3W个数据也不整齐的情况)

    如果没超时,则解析返回数据:

        格式解析失败,比如服务器来个 http 500,那肯定该次请求歇菜了。可以重试,也可以放弃该NO弄下一个。要不要记录状态你自己看

        解析成功:标记“校验完成”状态,然后循环下一个

如果没找到“待校验”的行,则该路处理线程结束

有一处负责处理各路进程的工作收尾

各路进程都完成以后,记录日志,收拾现场,打印报告

如果服务器端平均能支持到100个并发的话,则有望在几分钟完成


我有类似经历,我是这么做的: httpd接受订单以后记录在数据库的订单表,后台另起一个守护进程每5分钟刷一次订单表,若有,则使用巨慢无比而不稳定的smtp协议,合并订单后,尝试发送给我设置好的若干个邮箱之一,然后在邮箱之间设置邮件转发。 一切运转良好。


语文没学好,重新审查了一遍题目,和原来的理解有些不同。

现在仍不清楚题主的表述,你是要当场返回验证结果?或是离线批处理查询远程api?

举个栗子: 假设你在公司内网的订单系统里增加查询快递单号的功能,这时,你已经有了一个order表单,然后遍历快递单号,逐一查询远程接口。

我会先查看该api的文档,有没有批量查询的方法,比如发送一大串json数组。若没有,你只能逐条查询了,别无他法,不过,你可以用curl构造自己的http header,节省点包尺寸。除此之外,别无他法了。


只能考虑用到多线程吧。 先把数据取出来,然后在程序里分组,分完组按组做一个线程去调。

这不是你设计的问题了。那是a接口的问题。 a接口肯定是可以批量查询的。你问一下喽。 不然大部分时间都浪费在建立连接来回传信息了。


不想写那些“大长精”,这个就是典型的异步流程。类似于这样的形式:(伪代码 描述) 同步流程是这样的

L = GetList()
retOfA = List()
for no in L {
    retOfA.add(CheckFromA(no))  // 主要耗时在这里 CheckFromA的调用
}
doHandler(retOfA)

异步流程是这样的

L = GetList()
retOfA = List()
i = len(retOfA)
FromACallback = func(ret) {
    retOfA.add(ret)
    if(!i--) -> doHandler(retOfA)
} 
for no in L {
    CheckFromA(no, FromACallback)
}

函数立即返回,不会阻塞主进程了,A返回结果会调用FromACallback。


你的获取数据的服务比较慢,就可以用异步调用+多线程的方式的方式。

首先有一个线程池,大概5到10个线程,用来处理真正的获取数据的工作。 在调用的时候,用异步的方式,看你用什么框架,比如spring有async标签,或者就用java的future,在future里面把数据毁掉给之前的请求。

【热门文章】
【热门文章】