精华内容
下载资源
问答
  • Java重试超时连接

    2021-02-26 15:15:32
    一切正常,花花公子,但是当连接超时时,程序会抛出异常并退出.有没有更好的方法来执行此操作以允许它在超时时再次尝试,或者有没有办法在此方法中执行此操作?public static String getPage(String theURL) {URL url = ...

    我有一个方法(下面)下拉并返回网页的源作为字符串.一切正常,花花公子,但是当连接超时时,程序会抛出异常并退出.有没有更好的方法来执行此操作以允许它在超时时再次尝试,或者有没有办法在此方法中执行此操作?

    public static String getPage(String theURL) {

    URL url = null;

    try {

    url = new URL(theURL);

    } catch (MalformedURLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    exitprint();

    }

    InputStream is = null;

    try {

    is = url.openStream();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    exitprint();

    }

    int ptr = 0;

    StringBuffer buffer = new StringBuffer();

    try {

    while ((ptr = is.read()) != -1) {

    buffer.append((char)ptr);

    }

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    exitprint();

    }

    return buffer.toString();

    }

    展开全文
  • 应用中需要实现一个功能: 需要将常规解决方案try-在包装正常上传逻辑基础上,通过判断返回结果或监听异常决定是否重试,同时为了解决立即重试的无效执行(假设异常是有外部执行不稳定导致的:网络抖动),休眠一定...

    应用中需要实现一个功能: 需要将

    常规解决方案

    try-

    在包装正常上传逻辑基础上,通过判断返回结果或监听异常决定是否重试,同时为了解决立即重试的无效执行(假设异常是有外部执行不稳定导致的:网络抖动),休眠一定延迟

    public vo

    try-catch-redo-

    上述方案还是有可能重试无效,解决这个问题尝试增加重试次数 retrycount 以及重试间隔周期 interval ,达到增加重试有效的可能性。

    public void commonRetry(Map dataMap) throws InterruptedException {

    Map paramMap = Maps.newHashMap();

    paramMap.put("tableName", "creativeTable");

    paramMap.put("ds", "20160220");

    paramMap.put("dataMap", dataMap);

    boolean result = false;

    try {

    result = uploadToOdps(paramMap);

    if (!result) {

    reuploadToOdps(paramMap,1000L,10);//延迟多次重试

    }

    } catch (Exception e) {

    reuploadToOdps(paramMap,1000L,10);//延迟多次重试

    }

    }

    复制代码

    方案一和方案二存在一个问题:正常逻辑和重试逻辑强耦合,重试逻辑非常依赖正常逻辑的执行结果,对正常逻辑预期结果被动重试触发,对于重试根源往往由于逻辑复杂被淹没,可能导致后续运维对于重试逻辑要解决什么问题产生不一致理解。重试正确性难保证而且不利于运维,原因是重试设计依赖正常逻辑异常或重试根源的臆测。

    优雅重试方案尝试

    应用命令

    命令设计模式具体定义不展开阐述,主要该方案看中

    f936d388385c07c336e8bb8135a7d825.png

    IRetry约定了上传和重试接口,其实现类OdpsRetry封装ODPS上传逻辑,同时封装

    而我们的调用者LogicClient无需关注重试,通过重试者Retryer实现约定接口功能,同时 Retryer需要对重试逻辑做出响应和处理, Retryer具体重试处理又交给真正的IRtry接口的实现类OdpsRetry完成。通过采用命令模式,优雅实现正常逻辑和重试逻辑分离,同时通过构建重试者角色,实现正常逻辑和重试逻辑的分离,让重试有更好的扩展性。

    使用Guava retryer优雅的实现接口重调机制

    Guava retryer工具与

    Maven POM 引入

    2.0.0

    com.

    定义实现Callable接口的方法,以便Guava retryer能够调用

    private static Callable

    定义Retry对象并设置相关策略

    Retryer retryer = RetryerBuilder.newBuilder()

    //抛出runtime异常、checked异常时都会重试,但是抛出error不会重试。

    .retryIfException()

    //返回false也需要重试

    .retryIfResult(Predicates.equalTo(false))

    //重调策略

    .withWaitStrategy(WaitStrategies.fixedWait(10, TimeUnit.SECONDS))

    //尝试次数

    .withStopStrategy(StopStrategies.stopAfterAttempt(3))

    .

    简单三步就能使用Guava Retryer优雅的实现重调方法。

    更多特性

    RetryerBuilder是一个Factory创建者,可以自定义设置重试源且支持多个重试源,可以Exception异常对象 和 自定义断言对象 ,通过 retryIfException 和retryIfResult 设置,同时支持多个且能兼容。

    retryIfException :抛出runtime异常、checked异常时都会重试,但是抛出error不会重试。

    retryIfRuntimeException :只会在抛runtime异常的时候才重试,checked异常和error都不重试。

    retryIfExceptionOfType :允许我们只在发生特定异常的时候才重试,比如NullPointerException和IllegalStateException都属于runtime异常,也包括自定义的error 如:

    # 只在抛出error重试

    retryIfExceptionOfType(Error.class)

    # 只有出现指定的异常的时候才重试,如:

    retryIfExceptionOfType(IllegalStateException.class)

    retryIfExceptionOfType(NullPointerException.class)

    # 或者通过Predicate实现

    retryIfException(Predicates.or(Predicates.instanceOf(NullPointerException.class),

    Predicates.instanceOf(IllegalStateException.class)))

    复制代码

    retryIfResult可以指定你的Callable方法在返回值的时候进行重试,如

    // 返回false重试

    retryIfResult(Predicates.equalTo(false))

    //以_error结尾才重试

    retryIfResult(Predicates.containsPattern("_error$"))

    复制代码

    当发生重试之后,假如我们需要做一些额外的处理动作,比如发个告警邮件啥的,那么可以使用 RetryListener 。每次重试之后,guava-retrying会自动回调我们注册的监听。也可以注册多个RetryListener,会按照注册顺序依次调用。

    import com.github.rholder.retry.Attempt;

    import com.github.rholder.retry.RetryListener;

    import

    接下来在Retry对象中指定监听: withRetryListener(new MyRetryListener<>())

    e0e237fc2e0dfa711b3ecc87bf5ab9c4.png

    6114ace3a5b67bf1bda82843ec1a593a.png

    展开全文
  • Java重试机制

    2021-01-26 17:37:43
    在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。 Springboot可以通过整合Spring Retry框架实现重试。 ...

    在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。
    Springboot可以通过整合Spring Retry框架实现重试。
    下面讲一下整合Spring Retry框架的步骤:

    1、首先要在pom.xml配置中加入spring-retry的依赖:

    		<dependency>
    			<groupId>org.springframework.retry</groupId>
    			<artifactId>spring-retry</artifactId>
    		</dependency>

    2、在启动类中加入重试注解@EnableRetry。

    
    @EnableRetry
    @SpringBootApplication
    public class ServerMain {
    	
    	public static void main(String[] args) {
            SpringApplication.run(ServerMain.class, args);
        }
    	
    }

    3、新建重试接口RetryService

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.retry.annotation.Backoff;
    import org.springframework.retry.annotation.Recover;
    import org.springframework.retry.annotation.Retryable;
    import org.springframework.stereotype.Service;
    
    /**  
     * @Title:  RetryService.java   
     * @Package com.skd.modules.retry   
     * @Description:    TODO(重试接口)   
     * @ImportantNotes:
     */
    
    @Service
    public class RetryService {
    	
    	private final static Logger logger = LoggerFactory.getLogger(RetryService.class);
    	
    	private final int totalNum = 100000;
    	 
        /**
         * @Retryable的参数说明: •value:抛出指定异常才会重试
         * •include:和value一样,默认为空,当exclude也为空时,默认所以异常
         * •exclude:指定不处理的异常
         * •maxAttempts:最大重试次数,默认3次
         * •backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
         */
        @Retryable(value = IllegalArgumentException.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
        public int retry(int num) {
            logger.info("减库存({})开始" + LocalTime.now(),totalNum);
            // do something
            
            if (num <= 0) {
                throw new IllegalArgumentException("数量不对");
            }
            logger.info("减库存执行结束" + LocalTime.now());
            return totalNum - num;
        }
     
        @Recover
        public int recover(IllegalArgumentException e) {
            logger.warn("减库存失败!!!" + LocalTime.now());
            return totalNum;
        }
    	
    }
    

    4.测试

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = ServerMain.class)
    public class RetryTest {
    	
    	@Autowired
        private RetryService retryService;
    	
    	
    	@Test
        public void test() {
            int count = retryService.retry(-1);
    //		int count = retryService.retry(5);
    		System.out.println("库存为 :" + count);
    	}
    	
    }

    最后提供一个不使用注解的方式,例如动态指定重试次数,等待时间等

    // 声明式
    	void declarative() {
    		final RetryTemplate retryTemplate = new RetryTemplate();
    		// 重试次数
            final SimpleRetryPolicy policy = new SimpleRetryPolicy(3, Collections.<Class<? extends Throwable>, Boolean>
                    singletonMap(Exception.class, true));
            FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
            // 重试时间	默认1000ms。
    //        fixedBackOffPolicy.setBackOffPeriod(2000);
            retryTemplate.setRetryPolicy(policy);
            retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
            final RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() {
                public Object doWithRetry(RetryContext context) throws Exception {
                	System.out.println("重试次数:"+context.getRetryCount()+", 重试时间:"+LocalTime.now());
                	System.err.println("do some thing");
                    //设置context一些属性,给RecoveryCallback传递一些属性
                    context.setAttribute("key1", "value1");
                    String result = null;
                    if (StringUtils.isEmpty(result))
                    	throw new Exception("exception");
                    return context.getAttribute("key1");
                }
            };
    
            // 如果RetryCallback执行出现指定异常, 并且超过最大重试次数依旧出现指定异常的话,就执行RecoveryCallback动作
            final RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {
                public Object recover(RetryContext context) throws Exception {
                    System.err.println("do recory operation");
                    System.err.println(context.getAttribute("key1"));
                    return null;
                }
            };
    
            try {
                final Object execute = retryTemplate.execute(retryCallback, recoveryCallback);
                System.err.println(execute);
            } catch (Exception e) {
                e.printStackTrace();
            }
    	}

     

    展开全文
  • Java执行任务有多次重试超时

    千次阅读 2021-03-05 12:20:48
    我认为,但我认为,如果您正在安排与网络相关的任务,则不应重试,而应最终并行运行.我稍后会描述其他方法.关于您的代码,您应该将任务传递给执行程序,或将FutureTask传递给线程.它不会产生一个线程或自己执行.如果你有一...

    我认为,但我认为,如果您正在安排与网络相关的任务,则不应重试,而应最终并行运行.我稍后会描述其他方法.

    关于您的代码,您应该将任务传递给执行程序,或将FutureTask传递给线程.它不会产生一个线程或自己执行.如果你有一个执行者(参见ExecutorService),你甚至不需要FutureTask,你可以简单地安排它并获得一个可调用的.

    因此,假设您有ExecutorService,您可以调用:

    Future future = yourExecutor.submit(task);

    Future.get(timeout)将等待该超时并最终返回TimeoutException,即使该任务从未启动过,例如,如果Executor已经忙于完成其他工作而无法找到一个空闲线程.所以,你最终可能会尝试5次并等待几秒钟,而不会让任务有机会运行.这可能是也可能不是你所期望的,但通常不是.也许你应该等到它开始才能超时.

    此外,您应该显式取消Future,即使它抛出TimeoutException,否则它可能会继续运行,因为文档和代码都没有说当get with timeout失败时它会停止.

    即使你取消它,除非Callable被“正确写入”,它可能会继续运行一段时间.在这部分代码中你无法做到这一点,只要记住,没有任何线程可以“真正地停止”另一个线程在Java中所做的事情,并且有充分的理由.

    但是,我认为您的任务主要与网络相关,因此它应该对线程中断做出正确的反应.

    我通常使用不同的策略是这样的情况:

    >我会写公共静态T执行(可调用任务,int maxTries,int超时),所以任务,最大尝试次数(可能是1),最大总超时(“我希望答案最多10秒,无论多少你尝试的次数,10秒或什么都不是“)

    >我开始产生任务,将它交给执行者,然后调用future.get(timeout / tries)

    >如果我收到结果,请将其退回.如果我收到异常,会再试一次(见后)

    >但是如果我得到超时,我不会取消将来,而是将其保存在列表中.

    >我检查是否已经过了太多时间,或者重试次数太多.在这种情况下,我取消列表中的所有期货并抛出异常,返回null,无论如何

    >否则,我循环,再次安排任务(与第一个任务并行).

    >见第2点

    >如果我没有收到结果,我会检查列表中的未来,也许是之前生成的任务之一.

    假设您的任务可以执行多次(因为我认为它们是,否则无法重试),对于网络内容我发现此解决方案可以更好地工作.

    假设您的网络实际上非常繁忙,您要求网络连接,每次重试20秒.由于您的网络正忙,20次重试中没有一次能够在2秒内完成连接.但是,持续40秒的单次执行可能会设法连接和接收数据.这就像一个人在网络缓慢的情况下强制性地在页面上按f5,它不会有任何好处,因为每次浏览器都必须从头开始.

    相反,我保持各种期货运行,第一个设法获取数据将返回结果,其他将停止.如果第一个挂起,第二个可以工作,或者第三个可能.

    与浏览器相比,就像打开另一个选项卡并重试在那里加载页面而不关闭第一个选项卡.如果网络很慢,第二个将花费一些时间,但不会停止第一个,最终将正确加载.如果相反第一个标签挂起,第二个标签将快速加载.无论哪个先加载,我们都可以关闭另一个标签.

    展开全文
  • 1问题描述在应用软件的开发中,经常会遇到这样的一种需求:需要实现一个方法来执行某种任务,而这个方法的执行时间不能超过指定值,如果超时,则调用者不管这个方法将来是否可能执行成功,都要中断它的执行,或者让...
  • java重试http连接

    2021-03-08 09:55:22
    我正在发出http请求.... } 我最担心的是某个状态下的连接在后续重试时无效.换句话说,我是否需要完全重新创建’httpRequest’,我应该避免在catch块中调用httpRequest.abort(),并且只在最终失败时调用它吗? 谢谢
  • java了一个java方法,它连接到web服务。我想举例来说,它需要超过5秒,然后停止当前的程序和重新启动3次以上。如果所有时间都失败,则完全中止。到目前为止,我写了以下内容:private ConnectionInterface ...
  • 详解Spring Cloud Zuul重试机制探秘简介本文章对应spring cloud的版本为(Dalston.SR4),具体内容如下:开启Zuul功能通过源码了解Zuul的一次转发怎么开启zuul的重试机制Edgware.RC1版本的优化开启Zuul的功能首先如何...
  • Java实现几种简单的重试机制

    千次阅读 2021-02-12 10:47:17
    设计我们的目标是实现一个优雅的重试机制,那么先来看下怎么样才算是优雅无侵入:这个好理解,不改动当前的业务逻辑,对于需要重试的地方,可以很简单的实现可配置:包括重试次数,重试的间隔时间,是否使用异步方式...
  • 这是我入职公司的第一个任务,上级说简单,不过我搞了有两天了,因为在网上搜的自定义超时重试次数看不懂。。后来还是问强哥,他给了我一篇博客链接,然后我才有了思路。 发起post请求 OkHttpClient client = ...
  • 当我们把单体应用微服务化,本来一个进程内的函数调用就成了远程调用,这样就会涉及到网络...所以,我们设计重试的时候,需要定义什么情况下需要重试,例如,调用超时、被调用端返回了某种可以重试的错误(如繁忙中、流
  • 那么这就要求我们的JAVA应用具有自动连功能。 网上的教程统统都是错的 我可以说100%都是错的,我们在一个企业级的应用中,JDBC连接的参数至少有19个,这19个每一个都是非常重要的,而真正涉及到“自动连”有三...
  • 这两天在做项目过程中,需要请求外部服务的api需要考虑重试,为了代码优雅,决定使用注解的方式进行重试的配置,手写了个注解, 支持配置:重试的次数 支持自定义策略:1、延迟重试、即每失败一次下次重试延迟 2...
  • 重试的工具类Guava-retrying依赖com.github.rholderguava-retrying2.0.0Retryer retryer = RetryerBuilder.newBuilder()//抛出....retryIfException()//返回false也需要重试(可以根据返回值确定需不需要重试).re...
  • 背景:项目一个htmlunit自动化测试框架里,针对webclient....可以加入异常重试机制:如果出现异常,设定重试次数,等待web服务端启动完成,从而增加程序成功率。参考:https://www.icode9.com/content-4-546143.htm...
  • dubbo的超时重试

    2021-03-22 18:04:24
    消费者取消重试retries="0" dubbo源码分析:超时原理以及应用场景 本篇主要记录dubbo中关于超时的常见问题,实现原理,解决的问题以及如何在服务降级中体现作用等。 超时问题 为了检查对dubbo超时的理解,尝试...
  • Here's an example class I created and the test code: RetriableTask.java public class RetriableTask { protected static final int MAX_RETRIES = 10; protected int retries = 0; protected int n = 0; ...
  • } } } 如果您想重试一定次数,会变得更复杂一些.您必须使用StatefulJob并在其JobDataMap中持有一个retryCounter,如果作业失败,则它会增加.如果计数器超过最大重试次数,那么您可以根据需要禁用该作业. class MyJob ...
  • #Grpc--失败重试

    2021-04-23 13:08:29
    RPC 调用失败可以分为三种情况:RPC 请求还没有离开客户端RPC 请求到达服务器,但是服务器的应用逻辑还没有处理该请求服务器应用逻辑开始处理请求,并且处理失败前两种情况,gRPC 客户端会自动重试,与重试策略的...
  • org.apache.httpcomponentshttpclient4.5.1HttpClient的异常分两类java.io.IOExceptionHttpException其中,java.io.IOException认为...对于 java.io.IOException异常,我们想要重试,就需要实现HttpClient提供的Http...
  • scikitlearn tensorflow实用教材71.1元包邮(需用券)去购买 >本文基于HttpClient 4.5.13使用 http 请求...HttpClient 中支持两种重试:异常重试。服务不可用重试。异常重试HttpClient 执行时会抛出两种异常:jav...
  • 超时重试浅析

    2021-05-24 13:04:03
    超时很多情况下同时伴随着重试,因为某些情况下比如网络抖动问题等,重试是可以成功的;当然重试往往也会指定重试次数上限,因为如果程序确实存在问题,重试多少次都无济于事,那其实也是对资源的浪费。 为什么要...
  • JAVA Socket超时浅析

    2021-02-12 22:07:23
    JAVA Socket超时浅析套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的“终端”。针对一个特定的连接,每台机器上都有一个“套接字”,可以想象它们之间有一条虚拟的“线缆”。JAVA有两个...
  • HTTP请求的话,有可能请求超时,中断失败,IO异常其实都有可能,如果是平时打开一个网页还好,打不开的时候,你会关掉,或者他页面给你显示信息。但是同步,不可以这样做,一旦请求失败,必须让数据正确的同步,今天...
  • hbase.rpc.timeout:rpc的超时时间,默认60s,不建议修改,避免影响正常的业务,在线上环境刚开始配置的是3秒,运行半天后发现了 大量的timeout error,原因是有一个region出现了如下问题阻塞了写操作:“Blocking ...
  • 是否可以让ClientBootstrap在给定的尝试次数内尝试连接,或者直到达到超时为止?目前,如果连接被拒绝,我会收到一个异常,但是它应该尝试在后台进行连接,例如通过遵守“ connectTimeoutMillis”引导程序选项.解决方法:...
  • 如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试? 服务治理 调用链路自动生成 一个大型的分布式系统,或者说是用现在流行的微服务架构来说吧,分布式系统由大量的服务组成。那么这些服务之间互相是...
  • Feign实现远程调用,超时时间以及重试次数 继上次学习我们接着上次的代码改造通过Feign的方式实现远程调用首先在product-api中引入jar,但是当粘贴进去发现依赖并没有下载下来,我们还需要把parent,properties,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 69,610
精华内容 27,844
关键字:

java超时重试

java 订阅