html调用接口_接口调用老超时?知道原理才能记得深刻!

本文通过一个简单的示例解释了接口调用设置超时时间的原理,以数据库操作为例,展示了如何使用线程池和Future.get方法来实现超时控制。当UserService通过CallUtils调用UserDAO的耗时数据库操作时,由于设置了1秒的超时,导致在2秒的数据库操作完成后抛出SocketTimeOutException,从而实现超时效果。
摘要由CSDN通过智能技术生成

0a8b58a983a093084a2b154d5a88a88d.gif  

平常开发过程中,如果涉及到RPC调用,对于服务调用方和服务提供方,都是可以设置接口超时时间的。以调用方为例,调用方需要调用远程的一个接口,为了保证服务的质量,一般会设置调用接口的超时时间,比如将调用接口的超时时间设置为1秒,当调用远程接口后,经过1秒还未拿到结果,那么就认为是超时了,调用方就不会继续等待服务提供方返回结果,而是直接抛出一个SocketTimeOutException。

  其实不仅仅是RPC接口调用需要设置超时时间,数据库、缓存这些一样的,一般都会设置超时时间,不能让程序无休止的等待下去。   那么问题来了!!应用或者说框架,是如何设置超时时间的呢?我们设置超时时间为1秒,那么程序是怎么保证1秒后就停止调用了呢?这也就是本文要介绍的,接口调用设置超时时间的原理。   本文将以设置调用数据库超时为例,介绍设置超时时间是怎么实现的,明白这个原理后,其他比如RPC调用、缓存调用的超时原理也就明白。1    CallUtils-带有超时的执行工具类

  下面是一个CallUtils,包含一个线程池和execute方法,execute方法中默认超时时间为1秒。

package cn.ganlixin.util; import java.util.concurrent.*; /**  * 带有超时的任务执行器  */ public class CallUtils {     /**      * 用于执行任务的线程池      */     private static ExecutorService executorService = Executors.newFixedThreadPool(5);     /**      * 执行任务,并且超时时间为1秒      *      * @param callable 需要执行的任务      * @param       任务执行完毕后返回值类型      * @return 任务结果      */     public static T execute(Callable callable) {         // 提交任务         Future future = executorService.submit(callable);         try {             return future.get(1, TimeUnit.SECONDS);         } catch (InterruptedException | ExecutionException | TimeoutException e) {             e.printStackTrace();         }         return null;     } }2

UserService-将调用数据库

  UserService使用CallUtils来执行数据库操作,因为CallUtils设置有调用超时:

package cn.ganlixin.service;

import cn.ganlixin.dao.UserDAO;

import cn.ganlixin.model.User;

import cn.ganlixin.util.CallUtils;

import java.util.List;

public class UserService {

    private UserDAO userDAO = new UserDAO();

    public List getAllUser() {

        return CallUtils.execute(() -> userDAO.getAllUserFromDB());

    }

}

3

UserDAO-耗时的数据库操作

  userDAO中,作为测试,只提供了一个getAllUserFromDB方法,休眠2秒来模拟数据库操作,因为UserService使用CallUtils来调用该方法,CallUtils的超时时间为1秒,所以该数据库操作必定会超时:

package cn.ganlixin.dao;

import cn.ganlixin.model.User;

import java.util.List;

import java.util.concurrent.TimeUnit;

public class UserDAO {

    /**

     * 从DB获取全量user列表

     */

    public List getAllUserFromDB() {

        try {

            // 模拟数据库操作,耗时2秒

            TimeUnit.SECONDS.sleep(2);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return null;

    }

}

4

进行测试

  创建测试类,测试UserService的getAllUser方法,因为getAllUser方法中使用CallUtils来调用数据库操作,CallUtils的超时时间为1秒,而数据库操作需要2秒,所以getAllUser方法必然会超时。

package cn.ganlixin.test;

import cn.ganlixin.service.UserService;

import org.junit.Test;

public class TestUserService {

    public UserService userService = new UserService();

    @Test

    public void testGetAllUser() {

        userService.getAllUser();

    }

}

  执行测试,输出如下:

5

总结

  本文演示了接口超时调用的原理,实现接口调用超时,无非是通过将任务提交到线程池后,使用future.get,设置超时时间即可。

  上面的代码很多细节都不太规范,比如涉及到数据库的超时,应该是数据库连接池的超时配置,而我在演示时是直接使用CallUtils来替代了,但是明白这个原理就OK。

055ae80b975290c81742648cb9d79c41.gif

bb0f611d02ed09f8f8ccc8013bf89a63.png

链接:

https://www.cnblogs.com/-beyond/p/13204252.html#4619685

本文为51Testing经授权转载,转载文章所包含的文字来源于作者。如因内容或版权等问题,请联系51Testing进行删除

推荐阅读

点击阅读☞手动远远不够,现代人都是怎么助力接口自动化测试的?

点击阅读☞不懂代码也没问题,学会Jmeter就能进行接口测试啦!

点击阅读☞Web页面测试和接口测试的区别?

点击阅读☞接口测试基础题!答错就说不过去了!

点击阅读☞不懂代码也没问题,学会Jmeter就能进行接口测试啦!

ba942a96f2a9ac234f7f31f59fa3874b.gif

897d2dcf34f2833ce539424285ec6f76.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值