7 changed files with 116 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,41 @@ |
|||
public class RetryUtils { |
|||
private static final long BASE_WAIT_MS = 500; |
|||
private static final int MAX_RETRY = 5; |
|||
|
|||
@FunctionalInterface |
|||
public interface RetryTask<T> { |
|||
T execute() throws Exception; |
|||
} |
|||
|
|||
public static <T> T retry(RetryTask<T> task) throws Exception { |
|||
int attempt = 0; |
|||
while (attempt < MAX_RETRY) { |
|||
try { |
|||
return task.execute(); |
|||
} catch (Exception e) { |
|||
attempt++; |
|||
if (attempt >= MAX_RETRY) { |
|||
System.out.println("最终失败: " + e.getMessage()); |
|||
throw e; |
|||
} |
|||
long waitTime = BASE_WAIT_MS * (1L << attempt); |
|||
System.out.println("尝试执行 #" + attempt + "... 失败"); |
|||
System.out.println("等待: " + waitTime + "ms"); |
|||
try { |
|||
Thread.sleep(waitTime); |
|||
} catch (InterruptedException ie) { |
|||
Thread.currentThread().interrupt(); |
|||
throw new RuntimeException(ie); |
|||
} |
|||
} |
|||
} |
|||
throw new IllegalStateException("重试逻辑异常"); |
|||
} |
|||
|
|||
public static void main(String[] args) throws Exception { |
|||
RetryUtils.retry(() -> { |
|||
System.out.println("尝试执行"); |
|||
throw new RuntimeException("模拟失败"); |
|||
}); |
|||
} |
|||
} |
|||
Binary file not shown.
@ -0,0 +1,60 @@ |
|||
import java.util.regex.Pattern; |
|||
|
|||
public class UrlFormatException extends RuntimeException { |
|||
private final String invalidUrl; |
|||
|
|||
public UrlFormatException(String message, String invalidUrl) { |
|||
super(message); |
|||
this.invalidUrl = invalidUrl; |
|||
} |
|||
|
|||
public UrlFormatException(String message, String invalidUrl, Throwable cause) { |
|||
super(message, cause); |
|||
this.invalidUrl = invalidUrl; |
|||
} |
|||
|
|||
public String getInvalidUrl() { |
|||
return invalidUrl; |
|||
} |
|||
} |
|||
|
|||
class UrlValidator { |
|||
private static final Pattern URL_PATTERN = Pattern.compile("^(https?|http)://[\\w-]+(\\.[\\w-]+)+([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?$"); |
|||
|
|||
public static void validate(String url) { |
|||
if (url == null || url.isBlank()) { |
|||
throw new UrlFormatException("URL不能为空", url); |
|||
} |
|||
if (!URL_PATTERN.matcher(url).matches()) { |
|||
throw new UrlFormatException("URL格式不合法,仅支持http/https协议", url); |
|||
} |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
System.out.println("=== 测试 URL 校验 ==="); |
|||
|
|||
System.out.println("\n空URL校验:"); |
|||
try { |
|||
UrlValidator.validate(null); |
|||
} catch (UrlFormatException e) { |
|||
System.out.println(" 异常: " + e.getMessage()); |
|||
System.out.println(" 无效URL: " + e.getInvalidUrl()); |
|||
} |
|||
|
|||
System.out.println("\n非法URL校验:"); |
|||
try { |
|||
UrlValidator.validate("ftp://example.com"); |
|||
} catch (UrlFormatException e) { |
|||
System.out.println(" 异常: " + e.getMessage()); |
|||
System.out.println(" 无效URL: " + e.getInvalidUrl()); |
|||
} |
|||
|
|||
System.out.println("\n正确URL校验:"); |
|||
try { |
|||
UrlValidator.validate("https://www.example.com/page"); |
|||
System.out.println(" 通过"); |
|||
} catch (UrlFormatException e) { |
|||
System.out.println(" 异常: " + e.getMessage()); |
|||
} |
|||
} |
|||
} |
|||
Binary file not shown.
@ -0,0 +1,15 @@ |
|||
URL返回404时是否继续重试?如何优化? |
|||
|
|||
结论:不应该继续重试。 |
|||
|
|||
- 404(Not Found)表示资源永久不存在,重试不会改变结果,只会浪费系统资源。 |
|||
|
|||
优化方案: |
|||
|
|||
1. 在重试逻辑中增加状态码判断:将404、401、403等永久失败状态码加入黑名单,遇到这些状态直接终止重试。 |
|||
|
|||
2. 扩展 RetryUtils :支持可配置的重试条件,如只重试5xx错误、连接超时等临时错误。 |
|||
|
|||
3. 断路器联动:当某个URL连续返回404时,直接将其加入熔断名单,后续请求直接拦截,避免无效调用。 |
|||
|
|||
4. 缓存404结果:对返回404的URL进行本地缓存,一段时间内不再发起请求。 |
|||
Loading…
Reference in new issue