[英]How can I change @Scheduler cron expression dynamically in spring boot?
我正在嘗試在特定時間調用 API。 但有時 api 調用可能會失敗,所以我做了一個邏輯來檢查 api 調用何時失敗。
在確認 api 調用失敗后,我想將@Schedulercron 表達式從當前的 cron 表達式更改為 15 分鍾后。
如何動態更改 cron 表達式?
下面是我的 API 調用代碼。
@Scheduled(cron="0 9 19 * * *", zone = "Asia/Seoul")
public void callAPi() throws InterruptedException {
swrList = new ArrayList<>();
List<GeoInfo> giList = gs.getGeoXY();
for(GeoInfo gi : giList) {
ShortWeatherReq swr = new ShortWeatherReq(APK.getApiKey(),"1",gi.getX(),gi.getY());
swr.setBaseDate(); //현재 날짜로 baseDate를 설정하는 메소드를 호출
swr.setNx(gi.getX()); //x좌표값 저장
swr.setNy(gi.getY()); //y좌표값 저장
swrList.add(swr); //list에 swr 추가
}
for(GeoInfo gi : giList) {
ShortWeatherReq swr = new ShortWeatherReq(APK.getApiKey(),"2",gi.getX(),gi.getY());
swr.setBaseDate(); //현재 날짜로 baseDate를 설정하는 메소드를 호출
swr.setNx(gi.getX()); //x좌표값 저장
swr.setNy(gi.getY()); //y좌표값 저장
swrList.add(swr); //list에 swr 추가
}
//위 객체를 가지고 이제 API를 호출할수 있게 Service에게 전해줘야 함
sws.setSwrList(swrList);
temperList = sws.callSW(); // API 통신 Service 호출
//Confirming API call failure
if(temperList.isEmpty()) { //온도 리스트가 비어있다면 진입
logger.warn("TemperList is empty");
//이제 여기서 메일을 보내주는 서비스를 만들어서 메일 전송을 해줘야 함
ms.sendErrorMail();
logger.info("-------------------");
logger.info("API Connection Fail");
}else {
logger.info("-------------------");
logger.info("API ConnectionSuccess");
logger.info("-------------------");
//List에 담긴 온도 DB에 저장
for(int i = 0;i<temperList.size();i++) {
Temperature temp = temperList.get(i);
ts.saveTemp(temp);
}
logger.info("DB Store Success");
}
}
首先,您應該激活Spring Retry
在您的App
class 上重試。
@SpringBootApplication
@EnableScheduling
@EnableRetry
public class App {
// something
}
然后,您需要將@Retryable
添加到您用作@Scheduled
的方法中。
@Scheduled(cron="0 9 19 * * *", zone = "Asia/Seoul")
// Add this line
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000), value={ApiCallException.class})
public void callAPi() throws InterruptedException {
swrList = new ArrayList<>();
List<GeoInfo> giList = gs.getGeoXY();
for(GeoInfo gi : giList) {
ShortWeatherReq swr = new ShortWeatherReq(APK.getApiKey(),"1",gi.getX(),gi.getY());
swr.setBaseDate(); //현재 날짜로 baseDate를 설정하는 메소드를 호출
swr.setNx(gi.getX()); //x좌표값 저장
swr.setNy(gi.getY()); //y좌표값 저장
swrList.add(swr); //list에 swr 추가
}
for(GeoInfo gi : giList) {
ShortWeatherReq swr = new ShortWeatherReq(APK.getApiKey(),"2",gi.getX(),gi.getY());
swr.setBaseDate(); //현재 날짜로 baseDate를 설정하는 메소드를 호출
swr.setNx(gi.getX()); //x좌표값 저장
swr.setNy(gi.getY()); //y좌표값 저장
swrList.add(swr); //list에 swr 추가
}
//위 객체를 가지고 이제 API를 호출할수 있게 Service에게 전해줘야 함
sws.setSwrList(swrList);
temperList = sws.callSW(); // API 통신 Service 호출
//Confirming API call failure
if(temperList.isEmpty()) { //온도 리스트가 비어있다면 진입
// Add this line
throw new ApiCallException("API Connection Fail")
}else {
logger.info("-------------------");
logger.info("API ConnectionSuccess");
logger.info("-------------------");
//List에 담긴 온도 DB에 저장
for(int i = 0;i<temperList.size();i++) {
Temperature temp = temperList.get(i);
ts.saveTemp(temp);
}
logger.info("DB Store Success");
}
}
這里是用@Retryable
注解設置backoff
參數來設置你想要的下一個運行時。 在Spring Retry
文檔中與BackOffPolicies
相關,定義如下。
在短暫失敗后重試時,在重試之前稍等片刻通常會有所幫助,因為通常失敗是由一些只能通過等待才能解決的問題引起的。 如果 RetryCallback 失敗,RetryTemplate 可以根據 BackoffPolicy 暫停執行。
您可以在此處找到有關Spring Retry
的詳細信息。
雖然我的回答沒有提供動態更改的 cron 語句,但我希望它能解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.