huang
2025-11-20 366ba040d2447bacd3455299425e3166f1f992bb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package com.mes.task.model;
 
import lombok.Builder;
import lombok.Data;
 
/**
 * 重试策略配置
 * 
 * @author mes
 * @since 2025-01-XX
 */
@Data
@Builder
public class RetryPolicy {
    
    /**
     * 最大重试次数
     */
    @Builder.Default
    private int maxRetryCount = 3;
    
    /**
     * 初始重试间隔(毫秒)
     */
    @Builder.Default
    private long initialRetryIntervalMs = 1000;
    
    /**
     * 重试间隔增长倍数(指数退避)
     */
    @Builder.Default
    private double backoffMultiplier = 2.0;
    
    /**
     * 最大重试间隔(毫秒)
     */
    @Builder.Default
    private long maxRetryIntervalMs = 30000;
    
    /**
     * 是否启用指数退避
     */
    @Builder.Default
    private boolean enableExponentialBackoff = true;
    
    /**
     * 可重试的异常类型(类名列表)
     */
    private java.util.List<String> retryableExceptions;
    
    /**
     * 不可重试的异常类型(类名列表)
     */
    private java.util.List<String> nonRetryableExceptions;
    
    /**
     * 默认重试策略
     */
    public static RetryPolicy defaultPolicy() {
        return RetryPolicy.builder()
            .maxRetryCount(3)
            .initialRetryIntervalMs(1000)
            .backoffMultiplier(2.0)
            .maxRetryIntervalMs(30000)
            .enableExponentialBackoff(true)
            .build();
    }
    
    /**
     * 计算重试间隔
     * 
     * @param retryAttempt 当前重试次数(从1开始)
     * @return 重试间隔(毫秒)
     */
    public long calculateRetryInterval(int retryAttempt) {
        if (!enableExponentialBackoff) {
            return initialRetryIntervalMs;
        }
        
        long interval = (long) (initialRetryIntervalMs * Math.pow(backoffMultiplier, retryAttempt - 1));
        return Math.min(interval, maxRetryIntervalMs);
    }
    
    /**
     * 判断异常是否可重试
     * 
     * @param exception 异常对象
     * @return 是否可重试
     */
    public boolean isRetryable(Throwable exception) {
        if (exception == null) {
            return false;
        }
        
        String exceptionClassName = exception.getClass().getName();
        
        // 检查不可重试列表
        if (nonRetryableExceptions != null) {
            for (String nonRetryable : nonRetryableExceptions) {
                if (exceptionClassName.contains(nonRetryable)) {
                    return false;
                }
            }
        }
        
        // 检查可重试列表
        if (retryableExceptions != null && !retryableExceptions.isEmpty()) {
            for (String retryable : retryableExceptions) {
                if (exceptionClassName.contains(retryable)) {
                    return true;
                }
            }
            return false; // 如果指定了可重试列表,但当前异常不在列表中,则不可重试
        }
        
        // 默认策略:网络异常、超时异常可重试,其他不可重试
        return isDefaultRetryable(exception);
    }
    
    /**
     * 默认重试判断逻辑
     */
    private boolean isDefaultRetryable(Throwable exception) {
        String exceptionClassName = exception.getClass().getName().toLowerCase();
        String message = exception.getMessage() != null ? exception.getMessage().toLowerCase() : "";
        
        // 网络相关异常
        if (exceptionClassName.contains("timeout") || 
            exceptionClassName.contains("connection") ||
            exceptionClassName.contains("network") ||
            message.contains("timeout") ||
            message.contains("connection") ||
            message.contains("网络")) {
            return true;
        }
        
        // 业务异常通常不可重试
        if (exceptionClassName.contains("illegalargument") ||
            exceptionClassName.contains("illegalstate") ||
            exceptionClassName.contains("validation")) {
            return false;
        }
        
        // 其他异常默认不可重试
        return false;
    }
}