最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中進行異步調(diào)用失敗的解決方法詳解

 更新時間:2026年01月13日 09:23:01   作者:程序員大華  
異步編程是一種非阻塞的編程模式,允許程序在等待某個操作完成時繼續(xù)執(zhí)行其他任務,而不是一直等待,下面我們就來看看異步調(diào)用失敗的相關解決方法吧

1.異步編程介紹

什么是異步編程

異步編程是一種非阻塞的編程模式,允許程序在等待某個操作完成時繼續(xù)執(zhí)行其他任務,而不是一直等待。

當操作完成后,通過回調(diào)函數(shù)、Future 或事件通知等方式獲取結(jié)果。

同步 vs 異步對比:

  • 同步:順序執(zhí)行,每一步必須等待前一步完成
  • 異步:非阻塞執(zhí)行,可以同時處理多個任務

Java 中的異步實現(xiàn)方式

CompletableFuture (Java 8+)

// 創(chuàng)建異步任務
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 模擬耗時操作
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    return "異步任務結(jié)果";
});

// 處理結(jié)果
future.thenAccept(result -> System.out.println("結(jié)果: " + result));

@Async 注解 (Spring Framework)

@Service
public class AsyncService {
    
    @Async
    public CompletableFuture<String> asyncMethod() {
        // 異步執(zhí)行的方法
        return CompletableFuture.completedFuture("執(zhí)行結(jié)果");
    }
}

回調(diào)函數(shù)

public interface Callback {
    void onSuccess(String result);
    void onError(Exception e);
}

public void asyncOperation(Callback callback) {
    new Thread(() -> {
        try {
            // 模擬操作
            String result = doSomething();
            callback.onSuccess(result);
        } catch (Exception e) {
            callback.onError(e);
        }
    }).start();
}

2.異步編程中的常見錯誤

網(wǎng)絡相關錯誤

  • 連接超時
  • 讀取超時
  • DNS 解析失敗
  • 網(wǎng)絡不可達

資源相關錯誤

  • 內(nèi)存不足
  • 線程池耗盡
  • 數(shù)據(jù)庫連接超時

業(yè)務邏輯錯誤

  • 遠程服務返回錯誤碼
  • 數(shù)據(jù)格式異常
  • 業(yè)務規(guī)則校驗失敗

示例:可能出錯的異步方法

public class UnreliableService {
    
    // 模擬不可靠的遠程服務調(diào)用
    public CompletableFuture<String> callExternalService(String data) {
        return CompletableFuture.supplyAsync(() -> {
            // 模擬隨機錯誤
            double random = Math.random();
            if (random < 0.3) {
                throw new RuntimeException("網(wǎng)絡超時");
            } else if (random < 0.6) {
                throw new RuntimeException("服務端錯誤");
            }
            return "處理結(jié)果: " + data;
        });
    }
}

3. 異步重試機制實現(xiàn)

手動重試實現(xiàn)

基礎重試邏輯

public class SimpleRetry {
    
    public static <T> CompletableFuture<T> retryAsync(
            Supplier<CompletableFuture<T>> task, 
            int maxAttempts, 
            long delayMs) {
        
        CompletableFuture<T> result = new CompletableFuture<>();
        retryAsync(task, maxAttempts, delayMs, 1, result);
        return result;
    }
    
    private static <T> void retryAsync(
            Supplier<CompletableFuture<T>> task, 
            int maxAttempts, 
            long delayMs, 
            int attempt, 
            CompletableFuture<T> result) {
        
        task.get().whenComplete((response, throwable) -> {
            if (throwable == null) {
                result.complete(response);
            } else if (attempt >= maxAttempts) {
                result.completeExceptionally(throwable);
            } else {
                // 延遲后重試
                CompletableFuture.delayedExecutor(delayMs, TimeUnit.MILLISECONDS)
                    .execute(() -> retryAsync(task, maxAttempts, delayMs, attempt + 1, result));
            }
        });
    }
}

使用 Spring Retry

添加依賴

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.0</version>
</dependency>

配置重試模板

@Configuration
@EnableRetry
public class RetryConfig {
    
    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate template = new RetryTemplate();
        
        // 重試策略:最多重試3次,遇到特定異常時重試
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, 
            Collections.singletonMap(RuntimeException.class, true));
        template.setRetryPolicy(retryPolicy);
        
        // 退避策略:每次重試間隔1秒
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(1000);
        template.setBackOffPolicy(backOffPolicy);
        
        return template;
    }
}

使用 @Retryable 注解

@Service
public class RetryableService {
    
    @Retryable(
        value = {RuntimeException.class},
        maxAttempts = 3,
        backoff = @Backoff(delay = 1000)
    )
    @Async
    public CompletableFuture<String> retryableAsyncMethod() {
        return CompletableFuture.supplyAsync(() -> {
            // 模擬可能失敗的操作
            if (Math.random() < 0.7) {
                throw new RuntimeException("臨時錯誤");
            }
            return "成功結(jié)果";
        });
    }
    
    @Recover
    public CompletableFuture<String> recover(RuntimeException e) {
        return CompletableFuture.completedFuture("降級結(jié)果");
    }
}

高級重試策略實現(xiàn)

指數(shù)退避重試

public class ExponentialBackoffRetry {
    
    public static <T> CompletableFuture<T> retryWithExponentialBackoff(
            Supplier<CompletableFuture<T>> task,
            int maxAttempts,
            long initialDelay,
            long maxDelay) {
        
        return retryWithExponentialBackoff(task, maxAttempts, initialDelay, maxDelay, 1);
    }
    
    private static <T> CompletableFuture<T> retryWithExponentialBackoff(
            Supplier<CompletableFuture<T>> task,
            int maxAttempts,
            long initialDelay,
            long maxDelay,
            int attempt) {
        
        CompletableFuture<T> future = task.get();
        
        if (attempt >= maxAttempts) {
            return future;
        }
        
        return future.handle((result, throwable) -> {
            if (throwable == null) {
                return CompletableFuture.completedFuture(result);
            } else {
                // 計算退避時間
                long delay = Math.min(maxDelay, initialDelay * (long) Math.pow(2, attempt - 1));
                
                // 添加隨機抖動避免驚群效應
                delay = (long) (delay * (0.5 + Math.random()));
                
                CompletableFuture<T> nextAttempt = CompletableFuture
                    .delayedExecutor(delay, TimeUnit.MILLISECONDS)
                    .supplyAsync(() -> 
                        retryWithExponentialBackoff(task, maxAttempts, initialDelay, maxDelay, attempt + 1)
                    )
                    .thenCompose(cf -> cf);
                
                return nextAttempt;
            }
        }).thenCompose(cf -> cf);
    }
}

基于條件的重試

public class ConditionalRetry {
    
    public static <T> CompletableFuture<T> retryWithCondition(
            Supplier<CompletableFuture<T>> task,
            Predicate<Throwable> shouldRetry,
            int maxAttempts,
            Function<Integer, Long> delayCalculator) {
        
        CompletableFuture<T> result = new CompletableFuture<>();
        retryWithCondition(task, shouldRetry, maxAttempts, delayCalculator, 1, result);
        return result;
    }
    
    private static <T> void retryWithCondition(
            Supplier<CompletableFuture<T>> task,
            Predicate<Throwable> shouldRetry,
            int maxAttempts,
            Function<Integer, Long> delayCalculator,
            int attempt,
            CompletableFuture<T> result) {
        
        task.get().whenComplete((response, throwable) -> {
            if (throwable == null) {
                result.complete(response);
                return;
            }
            
            boolean canRetry = attempt < maxAttempts && shouldRetry.test(throwable);
            
            if (!canRetry) {
                result.completeExceptionally(throwable);
                return;
            }
            
            long delay = delayCalculator.apply(attempt);
            CompletableFuture.delayedExecutor(delay, TimeUnit.MILLISECONDS)
                .execute(() -> 
                    retryWithCondition(task, shouldRetry, maxAttempts, delayCalculator, attempt + 1, result)
                );
        });
    }
}

完整的重試工具類

public class AsyncRetryUtil {
    
    /**
     * 異步重試執(zhí)行器
     */
    public static class AsyncRetryBuilder<T> {
        private final Supplier<CompletableFuture<T>> task;
        private int maxAttempts = 3;
        private Predicate<Throwable> retryCondition = ex -> true;
        private Function<Integer, Long> delayStrategy = attempt -> 1000L * attempt;
        private Consumer<Integer> onRetry = attempt -> {};
        private Function<Throwable, T> fallback = null;
        
        private AsyncRetryBuilder(Supplier<CompletableFuture<T>> task) {
            this.task = task;
        }
        
        public static <T> AsyncRetryBuilder<T> of(Supplier<CompletableFuture<T>> task) {
            return new AsyncRetryBuilder<>(task);
        }
        
        public AsyncRetryBuilder<T> maxAttempts(int maxAttempts) {
            this.maxAttempts = maxAttempts;
            return this;
        }
        
        public AsyncRetryBuilder<T> retryIf(Predicate<Throwable> condition) {
            this.retryCondition = condition;
            return this;
        }
        
        public AsyncRetryBuilder<T> delayStrategy(Function<Integer, Long> strategy) {
            this.delayStrategy = strategy;
            return this;
        }
        
        public AsyncRetryBuilder<T> onRetry(Consumer<Integer> callback) {
            this.onRetry = callback;
            return this;
        }
        
        public AsyncRetryBuilder<T> fallback(Function<Throwable, T> fallback) {
            this.fallback = fallback;
            return this;
        }
        
        public CompletableFuture<T> execute() {
            CompletableFuture<T> result = new CompletableFuture<>();
            execute(1, result);
            return result;
        }
        
        private void execute(int attempt, CompletableFuture<T> result) {
            task.get().whenComplete((response, throwable) -> {
                if (throwable == null) {
                    result.complete(response);
                    return;
                }
                
                boolean shouldRetry = attempt < maxAttempts && retryCondition.test(throwable);
                
                if (!shouldRetry) {
                    if (fallback != null) {
                        try {
                            T fallbackResult = fallback.apply(throwable);
                            result.complete(fallbackResult);
                        } catch (Exception e) {
                            result.completeExceptionally(e);
                        }
                    } else {
                        result.completeExceptionally(throwable);
                    }
                    return;
                }
                
                onRetry.accept(attempt);
                long delay = delayStrategy.apply(attempt);
                
                CompletableFuture.delayedExecutor(delay, TimeUnit.MILLISECONDS)
                    .execute(() -> execute(attempt + 1, result));
            });
        }
    }
}

使用示例

public class RetryExample {
    
    public static void main(String[] args) throws Exception {
        // 模擬不可靠的服務
        Supplier<CompletableFuture<String>> unreliableService = () -> 
            CompletableFuture.supplyAsync(() -> {
                double rand = Math.random();
                if (rand < 0.8) {
                    throw new RuntimeException("服務暫時不可用");
                }
                return "服務調(diào)用成功";
            });
        
        // 使用重試工具
        CompletableFuture<String> result = AsyncRetryUtil.AsyncRetryBuilder
            .of(unreliableService)
            .maxAttempts(5)
            .retryIf(ex -> ex.getMessage().contains("暫時不可用"))
            .delayStrategy(attempt -> 1000L * attempt) // 線性退避
            .onRetry(attempt -> 
                System.out.println("第 " + attempt + " 次重試..."))
            .fallback(ex -> "降級結(jié)果")
            .execute();
        
        result.whenComplete((response, error) -> {
            if (error != null) {
                System.out.println("最終失敗: " + error.getMessage());
            } else {
                System.out.println("最終結(jié)果: " + response);
            }
        });
        
        // 等待異步操作完成
        Thread.sleep(10000);
    }
}

4. 注意事項

重試策略選擇

  • 網(wǎng)絡超時:使用指數(shù)退避 + 隨機抖動
  • 服務限流:根據(jù)返回的等待時間重試
  • 業(yè)務錯誤:根據(jù)具體錯誤碼決定是否重試

避免的問題

  • 無限重試:設置最大重試次數(shù)
  • 資源耗盡:合理控制重試頻率
  • 雪崩效應:使用斷路器模式配合重試
  • 重復操作:確保操作的冪等性

監(jiān)控和日志

// 添加重試監(jiān)控
public class RetryMonitor {
    private static final MeterRegistry meterRegistry = new SimpleMeterRegistry();
    
    public static void recordRetry(String operation, int attempt) {
        Counter.builder("retry.attempts")
            .tag("operation", operation)
            .register(meterRegistry)
            .increment();
    }
    
    public static void recordSuccess(String operation, long duration) {
        Timer.builder("retry.duration")
            .tag("operation", operation)
            .tag("status", "success")
            .register(meterRegistry)
            .record(duration, TimeUnit.MILLISECONDS);
    }
}

具體業(yè)務場景選擇合適的重試策略,提高系統(tǒng)的容錯能力和穩(wěn)定性。

以上就是Java中進行異步調(diào)用失敗的解決方法詳解的詳細內(nèi)容,更多關于Java異步調(diào)用的資料請關注腳本之家其它相關文章!

相關文章

  • Java關鍵字this與super詳解用法

    Java關鍵字this與super詳解用法

    這篇文章主要介紹了Java關鍵字this與super的用法,this與super是類實例化時通往Object類通道的打通者;this和super在程序中由于其經(jīng)常被隱式的使用而被我們忽略,但是理解其作用和使用規(guī)范肯定是必須的。接下來將詳述this與super各自的的作用,需要的朋友可以參考一下
    2022-04-04
  • Java程序?qū)崿F(xiàn)導出Excel的方法(支持IE低版本)

    Java程序?qū)崿F(xiàn)導出Excel的方法(支持IE低版本)

    下面小編就為大家?guī)硪黄狫ava程序?qū)崿F(xiàn)導出Excel的方法(支持IE低版本)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • 詳解IntelliJ IDEA創(chuàng)建spark項目的兩種方式

    詳解IntelliJ IDEA創(chuàng)建spark項目的兩種方式

    這篇文章主要介紹了詳解IntelliJ IDEA創(chuàng)建spark項目的兩種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Java設計模式系列之深入淺出單例模式

    Java設計模式系列之深入淺出單例模式

    設計模式是在大量的實踐中總結(jié)和理論之后優(yōu)選的代碼結(jié)構,編程風格,以及解決問題的思考方式,下面這篇文章主要給大家介紹了關于Java設計模式系列之深入淺出單例模式的相關資料,需要的朋友可以參考下
    2021-09-09
  • Java實戰(zhàn)之實現(xiàn)在線小說閱讀系統(tǒng)

    Java實戰(zhàn)之實現(xiàn)在線小說閱讀系統(tǒng)

    本文主要介紹了一個通過Java實現(xiàn)的在線電子書小說閱讀系統(tǒng),文中用到的技術有Layui、Springboot、SpringMVC、HTML、FTP、JavaScript、JQuery等,感興趣的可以試試
    2022-01-01
  • Eclipse設置斷點調(diào)試的方法

    Eclipse設置斷點調(diào)試的方法

    這篇文章主要介紹了Eclipse斷點調(diào)試的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 使用java實現(xiàn)云端資源共享小程序的代碼

    使用java實現(xiàn)云端資源共享小程序的代碼

    這篇文章主要介紹了用java寫一個云端資源共享小程序,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • javax.persistence中@Column定義字段類型方式

    javax.persistence中@Column定義字段類型方式

    這篇文章主要介紹了javax.persistence中@Column定義字段類型方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java 可重啟線程及線程池類的設計(詳解)

    java 可重啟線程及線程池類的設計(詳解)

    下面小編就為大家?guī)硪黄猨ava 可重啟線程及線程池類的設計(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • 用Java實現(xiàn)24點游戲

    用Java實現(xiàn)24點游戲

    喜歡玩游戲的有福啦,文中有非常詳細的開發(fā)框架,按著框架來實現(xiàn)就好啦.而且24點游戲是經(jīng)典的紙牌益智游戲.,需要的朋友可以參考下
    2021-05-05

最新評論

左权县| 博罗县| 娱乐| 无为县| 台东市| 九台市| 五华县| 临颍县| 海盐县| 循化| 托里县| 阜新市| 堆龙德庆县| 湛江市| 色达县| 珲春市| 拉萨市| 大渡口区| 四子王旗| 洞口县| 深泽县| 朝阳县| 海阳市| 浦东新区| 石狮市| 盐城市| 阜平县| SHOW| 错那县| 六枝特区| 阜康市| 太康县| 柘荣县| 基隆市| 华池县| 兴安县| 宣武区| 绥德县| 进贤县| 屏东县| 新昌县|