简体   繁体   中英

Java: use of org.springframework.retry.annotation.Retryable

I'm attempting to use org.springframework.retry.annotation.Retryable with an expectation that if a connection reset or timeout happens, the execution can re-try the call again. But so far I'm not getting the retry setup to work properly. The timeout error looks like this this error:

    javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: 
    java.net.SocketTimeoutException: Read timed out

Here is what I have for the retry:

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.util.function.Supplier;

@Service
public interface RetryService {

    @Retryable(maxAttempts = 4,
            backoff = @Backoff(delay = 1000))
    <T> T run(Supplier<T> supplier);

}

and retry implementing class:

import com.service.RetryService;
import org.springframework.stereotype.Service;

import java.util.function.Supplier;

@Service
public class RetryImpl implements RetryService {
    @Override
    public <T> T run(Supplier<T> supplier) {
        return supplier.get();
    }
}

I use it in the following way:

retryService.run(()->
        myClient.cancel(String id)
);

and MyClient.java has the following implementation for the cancel call and caching:

public Response cancel(String id) {
    String externalUrl = "https://other.external.service/rest/cancel?id="+id;

    WebTarget target = myClient.target(externalUrl);
    return target.request()
                .accept(MediaType.APPLICATION_JSON)
                .cacheControl(cacheControl())
                .buildPut(null)
                .invoke();
}

private static CacheControl cacheControl(){
    CacheControl cacheControl = new CacheControl();
    cacheControl.setMustRevalidate(true);
    cacheControl.setNoStore(true);
    cacheControl.setMaxAge(0);
    cacheControl.setNoCache(true);
    return cacheControl;
}

The externalUrl var above is an endpoint that's a void method - it returns nothing. My hope is that when timeout happens, the retry implementation would fire up and call the external service another time. My setup works in Postman as long as timeout does NOT occur. But if I let it sit for about 30 min, and try again, then I get the timeout error as above. And if I issue another call via Postman right after the timeout, i do get a successful execution. So the retry setup is not working, seems like something falls asleep. I've tried a dazzling number of variations to make it work, but no luck so far. When timeout happens, i see no logs in Kibana in the external service, while getting the the error above on my end. I'm hoping there is something obvious that I'm not seeing here, or maybe there is a better way to do this. Any help is very much appreciated.

You need to set @EnableRetry on one of your @Configuration classes.

See the README: https://github.com/spring-projects/spring-retry

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM