Java中的请求重发机制:详细解读与实现

Java中的请求重发机制:详细解读与实现

在进行网络请求时,尤其是对外部服务的调用,网络波动或服务器故障常常会导致请求失败。因此,重试机制(请求重发)是实现高可用系统的重要组成部分。在Java中,不同的HTTP客户端库提供了不同的请求重发机制。本文将详细解读在Java中如何实现请求重发机制,涵盖 HttpURLConnection、Java 11 自带的 HttpClientApache HttpClientRestTemplate 四种常见工具。

1. HttpURLConnection中的重发机制

HttpURLConnection 是 Java 标准库中最基本的 HTTP 客户端。默认情况下,HttpURLConnection 支持自动重试功能,但它的重试行为有很多限制,通常只能针对网络层面的异常进行重试。

默认重试机制

HttpURLConnection 的默认行为在以下情况下会进行自动重试:

  • Connection reset(连接被重置)
  • Timeouts(超时)

但是,它仅在发生这些异常时进行简单的重试,而且没有太多自定义选项。具体来说,它没有内建的重试次数限制、间隔时间配置等选项。

如何自定义重试机制

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;public class HttpURLConnectionRetry {public static void main(String[] args) throws IOException {URL url = new URL("https://example.com");int maxRetries = 3;int retries = 0;boolean success = false;while (retries < maxRetries && !success) {HttpURLConnection connection = (HttpURLConnection) url.openConnection();try {connection.setRequestMethod("GET");connection.setConnectTimeout(5000);connection.setReadTimeout(5000);int responseCode = connection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {System.out.println("Request successful.");success = true;} else {retries++;System.out.println("Request failed. Retrying... " + retries);}} catch (IOException e) {retries++;System.out.println("IOException occurred. Retrying... " + retries);} finally {connection.disconnect();}}if (!success) {System.out.println("Failed after " + maxRetries + " retries.");}}
}

在这个例子中,我们手动控制了请求的重试次数。可以根据具体的异常情况,选择是否重试,并根据需要设置间隔时间。

2. Java 11 HttpClient中的请求重发机制

Java 11 引入了全新的 HttpClient,相比 HttpURLConnection 提供了更为灵活和强大的功能,包括自动重试机制、异步请求等。

默认重试机制

Java 11 HttpClient 在某些情况下会自动重试请求。例如,当遇到连接超时、响应超时等异常时,HttpClient 会根据配置进行重试。可以通过 HttpClient 的配置来控制重试机制。

自定义重试机制

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.TimeUnit;public class HttpClientRetry {public static void main(String[] args) throws Exception {HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5))  // 设置连接超时.build();HttpRequest request = HttpRequest.newBuilder().uri(new URI("https://example.com")).timeout(Duration.ofSeconds(5))  // 设置读取超时.build();int maxRetries = 3;int retries = 0;boolean success = false;while (retries < maxRetries && !success) {try {HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());if (response.statusCode() == 200) {System.out.println("Request successful.");success = true;} else {retries++;System.out.println("Request failed. Retrying... " + retries);}} catch (Exception e) {retries++;System.out.println("Exception occurred. Retrying... " + retries);}}if (!success) {System.out.println("Failed after " + maxRetries + " retries.");}}
}

HttpClient 的重试机制总结

  • 自动重试HttpClient 会自动重试某些情况下的请求失败。
  • 自定义重试:你可以在应用层面实现自定义的重试逻辑,如上所示。
  • 更强大的配置HttpClient 提供了更多灵活的超时设置和异步请求支持,适合构建高效的网络请求。

3. Apache HttpClient中的请求重发机制

Apache HttpClient 是 Java 生态中常用的第三方 HTTP 客户端库,相比 HttpURLConnection 和 Java 11 的 HttpClient,它提供了更为丰富的配置选项和自定义功能。

默认重试机制

Apache HttpClient 默认启用了一定的重试机制,针对常见的网络错误会自动重试,例如 IOException

自定义重试机制

Apache HttpClient 允许你通过实现 RequestRetryHandler 接口来定制请求的重试逻辑。例如:

import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.RequestConfig;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.HttpResponse;import java.io.IOException;public class ApacheHttpClientRetry {public static void main(String[] args) throws IOException {// 创建重试处理器,设置最大重试次数DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(3, false);HttpClient client = HttpClients.custom().setRetryHandler(retryHandler).build();HttpGet request = new HttpGet("https://example.com");HttpResponse response = client.execute(request);System.out.println("Response Code: " + response.getStatusLine().getStatusCode());}
}

RequestRetryHandler的工作原理

RequestRetryHandler 接口允许你定制重试策略。你可以决定哪些异常会触发重试,以及重试的最大次数。例如,你可以指定只有连接超时或者服务器不可用时才进行重试,其他错误则不进行重试。

4. RestTemplate中的请求重发机制

RestTemplate 是 Spring 框架提供的 HTTP 客户端,广泛应用于 Spring 应用中。与 HttpURLConnectionApache HttpClient 类似,RestTemplate 也支持请求重发机制,尤其是通过与 HttpRequestFactory 配合使用。

默认重试机制

RestTemplate 本身没有内建的重试机制,但你可以通过自定义 ClientHttpRequestFactoryHttpRequestRetryHandler 来实现请求重试。

自定义重试机制

import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.RequestConfig;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.client.HttpClient;public class RestTemplateRetry {public static void main(String[] args) {// 创建 HttpClient,设置重试机制DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(3, false);HttpClient httpClient = HttpClients.custom().setRetryHandler(retryHandler).build();ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);RestTemplate restTemplate = new RestTemplate(factory);// 发起请求String url = "https://example.com";String response = restTemplate.getForObject(url, String.class);System.out.println(response);}
}

在这个例子中,我们通过 HttpComponentsClientHttpRequestFactoryApache HttpClient 集成到 RestTemplate 中,并配置了重试机制。

RestTemplate 的重试机制总结

  • 默认无重试RestTemplate 默认没有重试机制,需要通过第三方库如 Apache HttpClient 来实现。
  • 灵活的集成:你可以根据业务需求集成不同的 HTTP 客户端(如 Apache HttpClientJava 11 HttpClient)来实现更灵活的重试逻辑。

5. 总结与建议

  1. 选择合适的工具:如果你使用的是 Java 11,可以优先选择 HttpClient,它已经内建了很多现代化的功能,支持更高效的异步请求和重试机制。对于较复杂的需求,Apache HttpClient 提供了更多自定义选项。
  2. 自定义重试策略:大多数 Java HTTP 客户端都允许你自定义请求的重试机制,通过指定最大重试次数、重试

间隔时间、异常类型等来优化请求的可靠性。
3. 使用第三方库:在 Spring 项目中,RestTemplate 是一个方便的选择,你可以通过集成 HttpClient 来实现复杂的重试策略。
4. 注意性能:虽然请求重试可以提高系统的稳定性,但过多的重试可能导致性能下降。需要根据实际情况平衡重试次数和请求响应时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贪心算法理论

系列博客目录 文章目录 系列博客目录贪心算法 (Greedy Algorithm)贪心算法的特点贪心算法的适用条件常见的贪心算法问题贪心算法的步骤贪心算法示例&#xff1a;活动选择问题贪心算法的优缺点 贪心算法 (Greedy Algorithm) 贪心算法是一种在每一步选择中都采取当前状态下最优的…

centos更换源文件,换源,替换源

期初怎么折腾就是不行&#xff0c;换了源也是不能使用的&#xff0c;最后发现不是换的源不行&#xff0c;而是之前的源文件不行&#xff0c;然后给所有的源文件在yum源统一放在了bak目录下&#xff0c;随后我们再去下载安装源文件。 您将yum源下载之后&#xff0c;先将您的其他…

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…

Python 爬虫实战基于 Class 的天气查询与反爬虫练习

需求&#xff1a; 要实现一个简单的天气查询爬虫&#xff0c;使用 requests 库来获取网页内容&#xff0c;使用 BeautifulSoup 来解析网页并提取天气信息。以下是一个基本示例&#xff0c;展示了如何抓取天气信息并输出当天的温度和天气状况。 以下是使用 class 类方式实现带有…

线性表-链式描述(C++)

链式实现的线性表&#xff1a; 链式实现的线性表&#xff0c;即链表&#xff08;Linked List&#xff09;&#xff0c;是一种通过节点&#xff08;Node&#xff09;的集合来存储数据的线性数据结构。在链表中&#xff0c;每个节点包含两部分&#xff1a;存储数据的域&#xff…

蓝牙定位的MATLAB仿真程序|基于信号强度的定位,平面、四个蓝牙基站(附源代码)

这段代码通过RSSI信号强度实现了蓝牙定位&#xff0c;展示了如何使用锚点位置和测量的信号强度来估计未知点的位置。它涵盖了信号衰减模型、距离计算和最小二乘法估计等基本概念。通过图形化输出&#xff0c;用户可以直观地看到真实位置与估计位置的关系。 文章目录 蓝牙定位原…

机器学习算法(六)---逻辑回归

常见的十大机器学习算法&#xff1a; 机器学习算法&#xff08;一&#xff09;—决策树 机器学习算法&#xff08;二&#xff09;—支持向量机SVM 机器学习算法&#xff08;三&#xff09;—K近邻 机器学习算法&#xff08;四&#xff09;—集成算法 机器学习算法&#xff08;五…

Attention显存统计与分析

Attention显存估计 简单的Attention函数 import torch import torch.nn as nn import einops class Attention(nn.Module):def __init__(self, dim, num_heads8, qkv_biasFalse, qk_scaleNone, attn_drop0., proj_drop0.):super().__init__()self.num_heads num_headshead_d…

Spring系列之批处理Spring Batch介绍

概述 官网&#xff0c;GitHub A lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. 执行流程 实战 假设有个待处理的任务&#xff0c;如文件batch-tes…

[保姆式教程]使用labelimg2软件标注定向目标检测数据和格式转换

定向目标检测是一种在图像或视频中识别和定位对象的同时&#xff0c;还估计它们方向的技术。这种技术特别适用于处理有一定旋转或方向变化的对象&#xff0c;例如汽车、飞机或文本。定向目标检测器的输出是一组旋转的边界框&#xff0c;这些框精确地包围了图像中的对象&#xf…

Socket编程:UDP网络编程项目

目录 一、回显服务器 二、翻译器 三、聊天室 一、回显服务器 项目介绍&#xff1a;使用UDPIPv4协议进行Linux网络编程&#xff0c;实现回显服务器和客户端 功能介绍&#xff1a;客户端发送数据&#xff0c;经过服务端再返回到客户端&#xff0c;输出数据 源代码&#xff1…

SQL面试题——抖音SQL面试题 最近一笔有效订单

最近一笔有效订单 题目背景如下,现有订单表order,包含订单ID,订单时间,下单用户,当前订单是否有效 +---------+----------------------+----------+-----------+ | ord_id | ord_time | user_id | is_valid | +---------+----------------------+--------…

HarmonyOS4+NEXT星河版入门与项目实战(24)------Stage模型

文章目录 1、概念2、配置文件1、全局配置文件2、模块配置文件3、UIAbility生命周期1、图文归纳2、生命周期方法入口4、页面生命周期1、图文描述1、概念 2、配置文件 1、全局配置文件 2、模块配置文件 统一修改配置文件技巧:点击任意json 文件,选择 Open editor ,在显示的列表…

torch_geometric使用手册-Heterogeneous Graph Learning(专题三)

大量的现实世界数据集以异构图(Heterogeneous Graph) 的形式存储,这促使了在PyG中引入专门的功能。例如,大多数推荐系统中的图(如社交图)都是异构图,它们存储着关于不同类型的实体及其不同类型关系的信息。本教程介绍了如何将异构图映射到PyG中,以及如何将其作为输入用于…

手机实时提取SIM卡打电话的信令声音-蓝牙电话如何适配eSIM卡的手机

手机实时提取SIM卡打电话的信令声音 --蓝牙电话如何适配eSIM卡的手机 一、前言 蓝牙电话的海外战略中&#xff0c;由于海外智能手机市场中政策的差异性&#xff0c;对内置eSIM卡的手机进行支持是非常合理的需求。Android系列手机中&#xff0c;无论是更换通信运营商&#xf…

QT6学习第五天 第一个QT Quick程序

QT6学习第五天 第一个QT Quick程序 概述创建Qt Quick程序使用Qt资源文件程序发布 概述 如果将程序的用户界面成为前端&#xff0c;程序的数据存储和逻辑业务成为后端&#xff0c;那么传统QT Widgets程序的前后端都是用C完成的。对于现代软件开发而言&#xff0c;前端演化速度远…

LabVIEW内燃机气道试验台测控系统

基于LabVIEW软件开发的内燃机气道试验台测控系统主要应用于内燃机气道的性能测试和数据分析&#xff0c;通过高精度的测控技术&#xff0c;有效提升内燃机的测试精度和数据处理能力。 项目背景 随着内燃机技术的发展&#xff0c;对其气道性能的精准测量需求日益增加。该系统通…

flutter底部导航栏中间按钮凸起,导航栏中间部分凹陷效果

关键代码: Scaffold中设置floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked和extendBody: true&#xff0c; BottomAppBar中设置shape: const CircularNotchedRectangle() Scaffold(extendBody: true,//body是否延伸脚手架底部&#xff0c;在底部导航…

108.【C语言】数据结构之二叉树查找值为x的节点

目录 1.题目 代码模板 2.分析 分类讨论各种情况 大概的框架 关键部分(继续递归)的详解 递归调用展开图 3.测试结果 其他写法 4.结论 5.注意事项 不推荐的写法 1.题目 查找值为x的节点并返回节点的地址 代码模板 typedef int BTDataType; typedef struct BinaryT…

算法刷题Day1

BM47 寻找第k大 第一天就随便记录吧&#xff0c;万事开头难&#xff0c;我好不容易开的头&#xff0c;就别难为自己&#xff0c;去追求高质量了。嘿嘿嘿 题目 传送门 解题思路一&#xff1a;维护一个大小为k的最小堆。最后返回堆顶元素。 代码&#xff1a; # # 代码中的类名…