密集多次 http 请求外部接口怎么操作比较好?

2022-04-21 10:02:18 +08:00
 Dogod37
先行感谢各位大佬解答。背景如下:
#1 本人 Java 菜鸡一枚。所以有些问题可能有些白痴。
#2 一个 Spring Boot 的 Web 应用,一台阿里金融云 ECS ( 2 core 8GB ),后接一台阿里金融云 RDS ,无 redis 等中间件。
#3 目标场景是用户从页面提交业务数据后,后端要将业务数据写入 MySQL ,并组装 Xml 报文后 http 发往第三方接口,从第三方接口获取返回数据后,再返回给 Web 页面,也就是说这个过程中,Web 页面是一直在等待后端同步返回结果的(有进度条样式一直在转)。而这个场景有 10%的部分是要拆分成最多 30 份,对应地去请求外部接口 30 次的( 30 份数据来自一次页面提交)。
#4 外部接口性能较差,一次请求耗时平均为 5s 左右,请求高峰期可能会达到 20s 。

因为业务的特性,会倾向于用户在页面点击提交按钮后很快( 30s 内)得到后端返回的处理结果。所以如果 30 份数据用串行的方式去请求外部接口,那最理想情况也是 5 * 30s=150s 了。所以问题是:
#1 能不能通过 CompletableFuture ,注入自定义的线程池(而非 JVM 的线程池),同时开启 30 个线程去并行执行这些外部请求。简单测试过外部接口对于并发请求的表现,100 个并发请求,1/10 响应用时 5s ,1/10 响应用时 10 几 s...最后 1/10 响应用时需要 40s (可接受)。
#2 上述方案一个 Web 提交就可能要开启 30 个线程,虽然这种需要开启 30 个线程的页面提交基本上不会一下子进来两个。但是!如果真的就有两个或者三个客户在同时触发了这个场景,需要考虑些什么吗?避免带来不可预料的异常或者崩溃。
#3 上述方案如果不可行的话,有没有更合理的解决方案?期望是用户页面同步得到结果,不要异步的....会增加复杂性,搞不动了...

多谢各位,帮忙孩子...
3751 次点击
所在节点    Java
24 条回复
biubiuF
2022-04-21 13:33:28 +08:00
加个 kafka 异步吧,然后用户请求的时候加个 actionId ,这个 id 1 分钟刷新一次,不然有的用户转圈等待的时候会一直刷新(比如我),可能直接打满 fd
dqzcwxb
2022-04-21 23:12:51 +08:00
@Dogod37 #8 11 楼说的很对,你开个线程池就行,就算是 300 个线程都随你
git00ll
2022-04-21 23:43:13 +08:00
nio ,你想开多少都可以,还不用担心线程太多。不过你调用的三方服务也是够垃的。
liian2019
2022-05-09 17:24:58 +08:00
量不大,业务不是太重要,用线程池去并发调用还行。量大的话这种场景最好还是别用多线程,技术上很容易实现搞些 CompletableFuture 什么的,对 C 的同步接口使用线程池要考虑的东西太多,如线程池参数怎么配置,下游接口能不能扛得住你这并发调用,线上跑起来线程池满了咋办,现在可能 150S ,请求堵住了,很可能就不止 150S 了,甚至整个系统都会受影响。其实还是提交和结果查询分两个接口来的比较好。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/848291

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX