【前车之鉴】坑啊~ RestHighLevelClient 超时时间偶尔失效问题解决方案

news2024/10/12 6:13:05

文章目录

    • show me code
    • 缘起
      • 原因分析
    • 几点建议

结论:实际你的配置是生效的,只不过效果不明显而已,通过下面的配置放大直观效果。

show me code

核心代码

public static void main(String[] args) {
        RestClientBuilder builder = RestClient.builder("你解析的节点host");
        builder.setRequestConfigCallback(ref -> {
            ref.setConnectTimeout(100);
            ref.setSocketTimeout(100);
            ref.setConnectionRequestTimeout(100);
            return ref;
        });
        builder.setHttpClientConfigCallback(ref -> {
            // 核心代码
            IOReactorConfig build = IOReactorConfig.custom().setSelectInterval(100).build();
            ref.setDefaultIOReactorConfig(build);
            return ref;
        });
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
    }

上面是伪代码但是核心点配置已经注明,先给在ES中底层使用HttpAsyncClientBuilder ,这和以往我们使用传统ApaceHttpClient 不同的是底层使用了NIO:IOReactor,因此在超时时间策略的控制上和传统阻塞方式不一样,有兴趣请继续往下看笔者分析

缘起

由于最近发现ES组件超时频繁,很多甚至出现10几秒到20多秒,然后检查相关配置发现历史同学接入改组件并没有去设置对应的超时时间,导致走到了ES默认的超时时间30s,这个可以在ElasticsearchRestClientProperties得出结论, 而且还知道连接超时默认1s

在这里插入图片描述
调整看起来好像就是注入对应的spring配置,比如我设置如下

spring.elasticsearch.rest.read-timeout=5ms

然后请求测试发现根本没效果,要知道我是拿云主机去连接es,我人在北京机房在上海,别告诉我5ms以内就能处理,【事实上你改到1ms都不一定有效果】,为啥说不一定我前后测过几十次,就有1-2次成功,我还想这玩意还有不确定因素?

成功验证超时堆栈信息如下:

Caused by: java.net.SocketTimeoutException: 5 milliseconds timeout on connection http-outgoing-7 [ACTIVE]
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:387)
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:92)
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:175)
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:261)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:502)
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:211)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
… 1 common frames omitted


原因分析

其实我一开始先去官网搜了下,发现毛都没有,唯一和timeout相关居然是在创建索引、mapping的request 每次携带参数timeout,如下配置:

   CreateIndexRequest createIndexRequest = new CreateIndexRequest();
        Settings build = Settings.builder()
                .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 2)
                .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1).build();
        createIndexRequest.timeout("5ms");
        createIndexRequest.settings(build);
        createIndexRequest.index(xxxx);
          return  client.indices().create(createIndexRequest, RequestOptions.DEFAULT).isAcknowledged();

但是该参数无法再查询中设置,而且这个timeout控制的是不是客户端到服务端,而是es集群中协调节点 到 副本节点之间的超时时间,很显然不符合我们的要求【默认也是30s】

我想难道在RestHighLevelClient中使用requestConfig注入timeout方式难道不行吗?既然不行为啥提供这种方式,岂不是自相矛盾,直到我偶然看到几次成功,才尝试跟踪上面的堆栈信息 来到timeoutCheck才发现问题所在,在ES底层使用了HttpAsyncClientBuilder#AbstractIOReactor ,NIO在发起请求后通过周期性不断问询服务端selectKey结果,同时做session校验,下面就是关于timeout的校验,

在这里插入图片描述
在这里插入图片描述
可以看出只有在timeoutCheckInterval 周期内才会去校验,默认1s,这样偶而手动请求就会被跳过,造成大家以为没有实现【后来我通过jmeter方式并发去请求,哪怕是1s 也基本能复现了】,因此通过在构建RestHighLevelClient 中指定NIO的配置如下,适当增加周期检测频率以此来直观处理业务上的超时请求

  builder.setHttpClientConfigCallback(ref -> {
            // 核心代码
            IOReactorConfig build = IOReactorConfig.custom().setSelectInterval(100).build();
            ref.setDefaultIOReactorConfig(build);
            return ref;
        });

几点建议

上面的配置需要注意,如果你的服务类似于B端服务QPS较低,但是业务繁琐,强烈建议调低setSelectInterval,我这里设置100ms ,因为业务低的服务很难被默认1s的周期检查从而进一步探查到超时现象,这样能让业务更明显感知,否则b端业务对es聚合操作较大, 如果极端情况拖到30s,很容易让ES集群超负荷。

而对于C端服务这类请求量级高的,稍微降低到500ms足矣。

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

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

相关文章

【M2TR】M2TR: Multi-modal Multi-scale Transformers for Deepfake Detection

文章目录 M2TR: Multi-modal Multi-scale Transformers for Deepfake Detectionkey points研究贡献方法多尺度变压器频率过滤器跨模态融合损失函数SR-DF数据集实验总结M2TR: Multi-modal Multi-scale Transformers for Deepfake Detection 会议/期刊:ICMR ’22 作者: key …

深入理解栈(Stack)(纯小白进)

目录: 一、栈是什么?1. 栈的概念2.栈的结构选择 二、栈的实现1. 栈结构体的定义2. 栈的初始化3. 栈的销毁4. 入栈5.出栈6. 取栈顶元素7. 栈中元素的个数8. 判断栈是否为空 总结 一、栈是什么? 1. 栈的概念 栈(Stack)…

游戏开发指南:使用 UOS C# 云函数快速构建与部署服务端逻辑实战教学

零基础的服务端小白,现在也可以使用 Unity 结合 C# 来轻松搞定游戏服务端啦! 在本篇文章中,我们将以游戏中的“抽卡”功能为例,展示如何使用 Unity Online Services(UOS)提供的强大 C# 云函数服务&#xf…

Elasticsearch(二)集成Spring Boot 基本的API操作

目录 一、集成Spring Boot 1、创建项目 2、pom文件 查看springboot集成的依赖 3、增加es的config类 二、索引相关API 1、创建索引 2、获取索引,判断其是否存在 3、删除索引 三、文档相关API 1、添加文档 2、获取文档,判断是否存在 3、获取文档…

Java后端面试----某团一面

美团一面 1.介绍一下你的第一个项目 这个就不多说了,主要是根据自己的简历上面的项目进行一个简短的概括使用的技术栈和什么背景解决了什么问题等等。 2.线程安全的类有哪些,平时有使用过哪些,主要解决什么问题 在Java中线程安全的类比如…

对后端返回的日期属性进行格式化(扩展 Spring MVC 的消息转换器)

格式化之前 格式化之后: 解决方式 方式一 在属性中加上注解,对日期进行格式化 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//JsonFormat(pattern &quo…

echarts按需引入解决项目大小问题

背景: 按需加载缩减项目大小,提升项目性能和可用性 实现: 创建echarts.js main.js进行配置 页面中引用 效果 全量导入 按需加载:

Chrome清除nslookup解析记录 - 强制http访问 - 如何禁止chrome 强制跳转https

步骤: 地址栏输入 chrome://net-internals/#hsts在Delete domain 栏的输入框中输入要http访问的域名,然后点击“delete”按钮最后在Query domain 栏中搜索刚才输入的域名,点击“query”按钮后如果提示“Not found”即可! 办法来自…

Linux系统:apt upgrade与apt update 命令的作用

一.sudo apt update命令 sudo apt update命令的主要作用是更新本地软件包列表。‌ 它不会下载或安装新的软件包,而是更新本地系统中软件包的列表,以反映远程存储库中的最新可用软件包信息。这确保了软件包管理器(APT)具有最新的软…

第十六周周报:单发的目标检测系列

目录 摘要 Abstract 一、SSD 1.1 模型结构 1.2 代码 二、YOLO 三、Termius 总结 摘要 本周主要学习单阶段的目标检测算法,如SSD、YOLO模型。详细学习了每个模型的原理,以及SSD和YOLO模型之间的异同。在本篇博客中将展示SSD的PyTorch实现代码&am…

Django使用uwsgi和nginx进行手动部署

在Django项目中使用uWSGI和Nginx进行部署是一种常见的生产环境配置。以下是一个详细的步骤指南,帮助你完成这个过程。 前提条件 有一个已经开发好的Django项目。服务器已安装Python、pip、Nginx和uWSGI。有一个有效的域名(可选,但推荐)。 步骤一&#xf…

CPU指令融合技术概述

什么是指令融合? 某些指令,例如add $3,$2,0, 只会使用rd/rs两个字段,但是这条指令却占用了全部32个bit, 这样会使得代码密度不高,指令域的有效利用率不高;这样,在实现某些功能的情况下,会使得CP…

Java创建线程池和线程池的七个核心参数

线程池的工作流程是:当一个任务被提交到线程池时,线程池会根据当前的线程数量和工作队列的状态来决定如何处理这个任务。如果当前运行的线程数量小于corePoolSize,则创建新线程执行任务;如果大于等于corePoolSize,则将…

毕设开源 大数据电影数据分析与可视化系统(源码+论文)

文章目录 0 前言1 项目运行效果2 设计概要3 最后 0 前言 🔥这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师…

完全免费安卓远程安卓方案:FRP+ADB甲壳虫方案,远程手机不是问题。

引言 在当今这个数字化时代,无论是在个人项目还是商业应用中,能够从公网访问到内网设备的能力变得越来越重要,尤其是安卓终端设备,在必要的情况下,从安卓远程到安卓进行紧急指导救援是未来一种重要的趋势. 通过合理的…

Java - WebSocket

一、WebSocket 1.1、WebSocket概念 WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发,并于2…

3种常用的缓存读写策略详解

在详解3种常用的缓存读写之前,我们先要了解什么事缓存读写。 缓存读写是指在使用缓存技术时,对数据进行读取和更新的操作过程。缓存是一种用于提高系统性能和可扩展性的技术,通过减少对慢速存储(如数据库)的访问次数&…

CAN总线仲裁机制

文章目录 1、什么是CAN总线仲裁?2、仲裁机制3、仲裁过程 1、什么是CAN总线仲裁? CAN总线上的每个节点都能监测到总线上发送的数据,当总线空闲时每个节点都能够进行报文发送,多个节点同时发送报文时,最终由哪个节点来进…

中间件有哪些分类?

中间件的分类 中间件是位于操作系统和应用程序之间的软件,它提供了一系列服务来简化分布式系统中的应用程序开发和集成。中间件可以根据其功能和用途被分为不同的类别。以下是中间件的一些主要分类: 1. 通信处理(消息)中间件&am…

Sentinel 1.80(CVE-2021-44139)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性 Report a Sentinel Security Vulnerability …