并发请求接口调试

背景

项目开发过程中,有一项需求是5000个项目,需要以HTTP接口请求方式去调用对应的算法接口来进行处理。单个项目需要调用3-4个算法接口,串行方式调用预估需要5000 x 4 = 20000次接口请求。
单个接口预计耗时500ms,则预计总耗时,10000s,这个时间是不可接受的。这时候就需要采用线程并发的方式,去向算法服务端发起请求,来并行处理项目。

实际操作

第一种方式

直接在客户端代码内,对5000个项目串行调用算法接口。

public void test(){
        for( int i = 0; i < projects.size(); i++ ){
            // test1内部发起http请求对应算法接口
            testService.test1();
        }

        for( int i = 0; i < projects.size(); i++ ){
            // test2内部发起http请求对应算法接口
            testService.test2();
        }

        for( int i = 0; i < projects.size(); i++ ){
            // test3内部发起http请求对应算法接口
            testService.test3();
        }
}
问题:
  1. 客户端报出 java.net.BindException: Address already in use: bind 异常,原因是在于请求服务端算法接口时,每一次请求都会占用本机对应的一个端口与服务端建立连接(通常本机5000 - 65534 端口由于建立TCP/IP连接),当发起的请求数量超过了这个范围的端口数量,就会报出上述异常。原因也就是因为本机发起过多的请求。一般请求完成之后240s的时间,会将连接释放,该问题也可以通过缩短time_wait的时间来进行解决。
  2. 该方式由于是串行进行请求,总的耗时预计在5000 x 4 x 0.5 = 10000s时间,处理时间太漫长。

第二种方式

直接在客户端代码内,对每一个项目创建一个线程,然后线程内部按逻辑顺序调用算法接口。这样就在客户端创建了5000个线程,并行访问服务端算法接口。

public void test(){
        for( int i = 0; i < projects.size(); i++ ){
            new Thread( ()->{
                // test1内部发起http请求对应算法接口
                testService.test1();

                // test2内部发起http请求对应算法接口
                testService.test2();

                // test3内部发起http请求对应算法接口
                testService.test3();
            }).start();
        }
    }
问题:
  1. 客户端报出 java.net.ConnectException: Connection refused 异常,原因是在于向服务端算法接口发起的请求数量过多,服务端请求队列满了之后将会拒绝建立新的连接。虽然可以在服务端设置请求队列的长度,但是由于客户端请求的数量过多,需要对大量延迟处理的请求进行管理,实现的难度较大。

第三种方式

将5000个项目分成100个线程去处理,每个线程内部串行处理50个项目。

public void test(){
        for (int i = 0; i < 100; i++) {
            new Thread( ()->{
                for (int j = 0; j < 50; j++) {
                    // test1内部发起http请求对应算法接口
                    testService.test1();

                    // test2内部发起http请求对应算法接口
                    testService.test2();

                    // test3内部发起http请求对应算法接口
                    testService.test3();
                }
                
            }).start();
        }
    }
好处:
  1. 可以控制线程的数量,从而控制在单位时间内向接口并发请求的数量,减低服务端的压力。
  2. 可以发挥并行处理的优势。
  3. 基于此项目,发起请求的粒度仍为单个项目,无需采用将项目分块之后再发起请求,降低请求数量的方式。从而降低实现的复杂性,也可以减少参数传输和处理上的时间消耗。
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值