多人开发,创建了多个定时任务用来推送二三十种业务数据,同时也为部分业务数据做了及时推送的机制,采用的restemplate工具类,在一段时间之内 ,系统运行得很正常,突然有一天,测试发现断网之后,很多及时推送的数据就不没有出现在接收方的系统里面,就像连锁反应一样,经排查,原因如下
-
restemplate调用接口前,线程能打印出日志,开始调用接口后,就没有输出日志,也就是没有响应消息,甚至异常也捕获不到,此现象断定restemplate调用接口出现了阻塞
-
配置了restemplate的超时时间 ,竟然没有生效,找出失效的原因后,成功捕获到超时异常
观察某一次RestTemplate 发起的POST请求卡死
一开始怀疑是线程池的可用线程数量不够,加大核心线程池数量、最大线程数量和线程队列数量后,发现阻塞问题依旧。
在查询资料后,发现restemplate是单线程,可能出现阻塞,反思一下,如果配置了超时机制且生效了,那么在第一个接口调用请求之后,就应该正常触发第二个接口调用才对,实际上我们第一个请求都没有闭环,原理上说不通。
当然restemplate的单线程设计也曾质疑过【
Spring 异步HTTP AsyncRestTemplate介绍_zzhongcy的博客-CSDN博客_resttemplate异步还是同步的
】,也尝试使用 AsyncRestTemplate改造 RestTemplate,发现 AsyncRestTemplate已经过时了,就不再继续了。
RestTemplate的异步兄弟AsyncRestTemplate。
在 Spring 3 时代,为了能更优雅地实现HTTP调用,引入了 RestTemplate,其中提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
在 Spring 4 时代,为了能实现异步地HTTP调用,引入了AsyncRestTemplate,使得编写异步代码和同步代码一样简单。
AsyncRestTemplate 是 Spring中提供异步的客户端HTTP访问的核心类。与RestTemplate类相似,它提供了一些类似的方法,只不过返回类型不是具体的结果,而是ListenableFuture包装类。
在定位到是restemplate阻塞问题后,开始走查代码,将封装了restemplate的工具类,拿来做单元测试,复现了阻塞问题,这样的做法还是非常有必要,因为很多时候代码不是自己写的,别人留下坑,都复现不出来的。
本人曾一度怀疑是restemplate版本不对导致的restemplate本身的超时机制不生效,然则本人使用与项目中同版本的restemplate进行测试后,发现超过机制是正常的,虽然浪费了时间,好在也排查除了一种可能性。
**千算万算没想到啊,在代码中发现竟然以前有人在配置restemplate支持重定向功能时,把已经配置过的超时赶时间,重新覆盖为空了,直接导致超时机制失效,**而
restTemplate用的是直接new的,未重写连接池也未设置超时时间。看源码得知底层用的jdk的httpurlconnection,若readTimeOut和connectionTimeOut没有设置,那请求是没有超时时间的,导致请求一直hang住。
restTemplate超时时间引发的生产事故 - 编程猎人 (programminghunter.com)
采用debug走查代码时,在方法【supportRedirectUrl】中创建的HttpComponentsClientHttpRequestFactory,直接将方法【httpComponentsClientHttpRequestFactory】中配置过的超时时间覆盖掉了
@Bean
public RestTemplate restTemplate(HttpComponentsClientHttpRequestFactory httpFactory) {
RestTemplate restTemplate = new RestTemplate(httpFactory);
restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) {
return false;
@Override
public void handleError(ClientHttpResponse clientHttpResponse) {
});
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.TEXT_HTML);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(mediaTypes);
restTemplate.getMessageConverters().add(converter);
this.supportRedirectUrl(httpsFactory, restTemplate);
return restTemplate;
* 添加重定向支持
* @param restTemplate
private void supportRedirectUrl(RestTemplate restTemplate) {
TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;
SSLContext sslContext = null;
try {
sslContext =
SSLContexts
.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
} catch (
NoSuchAlgorithmException | KeyManagementException | KeyStoreException e
e.printStackTrace();
SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
new NoopHostnameVerifier()
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
HttpClient httpClient = HttpClientBuilder
.create()
.setRedirectStrategy(new LaxRedirectStrategy())
.setSSLSocketFactory(connectionSocketFactory)
.build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
@Bean(name = "httpFactory")
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory()
throws Exception {
RequestConfig defaultRequestConfig = RequestConfig
.custom()
.setConnectTimeout(ConnectTimeout)
.setSocketTimeout(socketTimeout)
.setConnectionRequestTimeout(ConnectTimeout)
.build();
CloseableHttpClient closeableHttpClient = HttpClients
.custom()
.setDefaultRequestConfig(defaultRequestConfig)
.build();
HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(
closeableHttpClient
httpFactory.setReadTimeout(readTimeout);
httpFactory.setConnectTimeout(ConnectTimeout);
httpFactory.setConnectionRequestTimeout(connectionRequestTimeout);
httpFactory.setBufferRequestBody(false);
return httpFactory;
项目过程中,往往都是多人协作,意料之外的问题往往不是开发语言的问题,反而人为制造问题更为隐匿,遇到这种不可控的情况 ,平时开发工作过程中,做好code review就显得尤其至关重要,做系统,也好比万丈高楼平地起,在团队成员能力不成熟时,做好核心代码管控+代码评审缺一不可,每个人的一砖一瓦都应当对个人负责,对项目负责,一时的无所谓,欠的“债”,逃不掉,总要还。
项目中要求向A系统推送存在多种类型数据,代码中以创建多个定时任务来且异步的方式去推送成千上万的数据。
为了保障数据推送,采用方式有
- 选择及时性要求很高的部分数据采用及时和定时推送
- 推送服务启动时,推送一次的全部数据
- 底层采用restemplate调用A系统的接口
- application.properties配置线程池初始化参数
精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用
精讲RestTemplate第2篇-多种底层HTTP客户端类库的切换
精讲RestTemplate第3篇-GET请求使用方法详解
精讲RestTemplate第4篇-POST请求方法使用详解
精讲RestTemplate第5篇-DELETE、PUT等请求方法使用详解
精讲RestTemplate第6篇-文件上传下载与大文件流式下载
一、异常现象
转载自 https://www.cnblogs.com/jimw/p/9037542.html
现在公司项目基本都从臃肿的项目转换成微服务的方向转换,因此也从中使用了spring clound的一些组件,在此过程中就遇到了restTemplate的坑。
起初,是直接注入RestTemplate,后来则不断的遇到错误日志无法请求,出现异常。
异常信息:
org.springframework...
使用
restTemplate方式调用服务上传文件时遇到的问题
最近在使用
restTemplate方式调用服务上传本地的excel文档时遇到了无法上传的问题,特此记录下来。
先说明一下这个项目的背景,前端页面有导入按钮,点击按钮可以导入本地的文件,然后在消费端想要通过
restTemplate的方式调用服务端,将这个文档中的数据插入到数据库中,但是一直传递不到服务端。现在
解决了这个问题,直接上代码。
消费端代码
//excel数据导入数据库
@
PostMapping("/impNews")
一、问题的出现
最近在使用RestTemplate发送HTTP请求时,服务端发送回来的响应结果中,HTTP响应码为400、500之类的,RestTemplate默认不处理这类响应结果,直接抛异常。但是,该请求的响应结果内容却是我需要用到的,因为我需要通过该请求的响应结果内容,告诉用户远程调用接口时,出现错误时问题是什么,以及通过请求返回的自定义结果集,来进行其他操作。
现在我们开发中,不管用户执行该请求是否成功,返回的HTTP状态码都是200,但是会在返回的自定义结果集中的code、message去体现
我们项目的短信功能是接第三方,原来对接第三方给我们回执确认
请求是get
请求我们在
排查问题的时候可以通过nginx的日志拿到对方给我们
请求的参数;最近我们换了另外一家第三方,新的第三方给我们的确认
请求是
post,遇到问题
排查,发现nginx没有打印具体参数,于是查阅一些资料和运维一起做了实验和线上调整,调整后我们可以拿到
请求参数,更方便我们
排查问题;
【Nginx设置打印
post请求参数】
一、Nginx配置文件(nginx.conf)设置打印
post请求参数:在http模块的log_format中增加 “dm”:$request_body 防止中
### 回答1:
stm32f030f4是意法半导体(STMicroelectronics)推出的一款32位单片机,具有串口和flash读写功能。如果在同时使用串口与flash读写时出现卡死现象,可能是以下几个原因导致的:
1. 中断优先级设置不正确:stm32f030f4有多个外设,包括串口和flash,在同时使用时,需要设置正确的中断优先级,以确保高优先级的中断可以正常执行。如果中断优先级设置不正确,可能会导致卡死现象。
2. 资源冲突:串口和flash都使用了DMA(直接内存访问)来提高数据传输效率,如果DMA通道或缓冲区被同时使用,可能会发生资源冲突,导致卡死。在使用串口和flash时,需要确保DMA资源分配的正确性。
3. 程序逻辑错误:在程序的设计与编写过程中,可能存在逻辑错误,例如死循环、死锁等,导致程序无法正常执行。这种情况下,需要对程序进行仔细的调试和排查,找出错误的原因并进行修正。
针对以上问题,可以尝试以下解决方法:
1. 检查中断优先级设置:修改中断优先级设置,确保高优先级的中断可以正常执行。
2. 确保资源分配的正确性:如果串口和flash同时使用了DMA,需要仔细检查DMA通道和缓冲区的分配是否正确。
3. 调试和排查程序错误:通过添加调试信息、查看日志等方法,找出程序中的逻辑错误,并进行相应的修正。
若以上方法均无法解决卡死现象,建议参考stm32f030f4的相关技术文档,查找更为详细的解决方案,或者联系意法半导体的技术支持团队,寻求进一步的帮助。
### 回答2:
当STM32F030F4的串口(UART)和Flash(闪存)同时被使用时出现卡死现象,可能是由以下几个原因引起的:
1. 资源冲突:由于串口和Flash使用的IO引脚可能会发生冲突,导致读写操作无法正常进行。此时需要检查串口和Flash的引脚配置,确保它们没有冲突。
2. 中断优先级配置不当:当串口和Flash同时使用时,中断可能会相互干扰,导致卡死现象。在使用中断时,需要正确配置中断优先级,确保串口和Flash的中断能够按照正确的优先级触发和执行。
3. 数据处理不及时:当串口和Flash同时工作时,串口接收到的数据可能积压,而Flash读写操作需要一定的时间。如果处理串口接收数据的任务耗时较长,可能导致读写操作无法及时进行,最终导致卡死现象。此时需要优化数据的处理流程,确保能够及时处理串口接收到的数据。
4. 程序逻辑错误:代码中可能存在逻辑错误或错误的操作顺序,导致串口和Flash同时使用时出现卡死现象。此时需要仔细检查代码,确保程序逻辑正确,并按照正确的顺序使用串口和Flash。
针对以上问题,可以按照以下步骤进行排查和解决:
1. 检查串口和Flash的引脚配置,确保它们没有冲突。
2. 配置中断优先级,确保串口和Flash的中断按照正确的优先级触发和执行。
3. 优化数据处理流程,确保能够及时处理串口接收到的数据。
4. 仔细检查代码,确保程序逻辑正确,并按照正确的顺序使用串口和Flash。
通过以上步骤进行排查和解决,应该能够解决串口和Flash同时使用时出现卡死现象的问题。
### 回答3:
首先,stm32f030f4是意法半导体(STMicroelectronics)生产的一款32位ARM Cortex-M0微控制器,具有串口功能和Flash存储器。当串口与Flash读写同时使用时出现卡死现象可能是由于以下几个原因:
1. 资源冲突:串口和Flash模块可能使用了相同的硬件资源,例如DMA通道或中断向量表。如果两个模块同时使用相同的资源,可能会导致资源冲突,从而导致卡死现象。可以通过重新分配资源或调整中断优先级的方式解决这个问题。
2. 中断处理:如果串口和Flash的中断服务程序没有正确编写或配置,可能会导致系统无法响应其他任务,从而导致卡死。在使用中断处理时,确保中断服务程序可以快速执行并及时退出,避免长时间占用CPU资源。
3. Flash操作错误:如果在Flash读写过程中发生错误,例如擦除或编程操作失败,可能会导致系统卡死。可以在Flash操作之前使用软件或硬件的方式检查Flash空闲状态,并及时处理擦除或编程错误。
4. 电源问题:在使用Flash存储器时,确保电源供应稳定可靠。如果电源波动或电源不稳定,可能会导致Flash操作异常,从而导致系统卡死。可以通过添加电源稳压电路或使用更稳定的电源进行解决。
综上所述,当stm32f030f4串口与Flash读写一起使用时出现卡死现象,可以首先检查资源冲突并重新分配资源。同时,确保中断处理程序正确配置和高效执行,检查Flash操作过程中是否存在错误,并确保电源供应的稳定性。如果问题仍然存在,可能需要进一步调试和分析代码以找出具体的问题所在。
Enter router password: wangzhuo2020
Traceback (most recent call last):
File "main.py", line 37, in <module>
stok = re.findall(r'"token":"(.*?)"',r1.text)[0]
IndexError: list index out of range
Press any key to continue . . .
[/code]
小米路由器4A千兆版刷入OpenWrt教程
Fa木兰der~Li:
mybatis 简单类型报异常ReflectionException
迷茫小猿:
小米路由器4A千兆版刷入OpenWrt教程
行万路明于省:
小米路由器4A千兆版刷入OpenWrt教程
sinat_38424109: