巧用newSingleThreadExecutor让异步任务顺序跑

背景

Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统 。一个用来控制 Flume 采集任务的 Web 应用,需要对任务进行管理,主要操作「启动、停止、新建、编辑、删除」,本质就是对 Flume 进程进行管理。

任务控制流程:

  1. 任务启动:创建一个 Flume 进程。
  2. 任务停止:停止该 Flume 进程。
  3. 修改启动状态的任务:先停止正在执行的 Flume 进程、再创建一个 Flume 进程。
  4. 任务删除:启动状态的任务先停止 Flume 进程、再删除任务信息。

本文介绍近期对这个功能的优化操作:用 Executors.newSingleThreadExecutor() 单线程调度对任务的处理命令,保证异步任务能按页面提交的顺序顺次执行

不间断地 在 CSDN 写博客十多年了,CSDN 有流量没收益,转场掘金,有收益,没流量。本文首发掘金, 《掘金金石计划投稿》求赞!

旧逻辑

任务管理类是个单例,用了 ThreadPoolExecutor 线程池去调度 Flume 进程的操作。但是线程池没法保证任务的执行顺序,所以加了很多 awaitsleep 操作,等待任务执行完成后才返回响应结果给页面。

这个思路没问题,必要的等待可以保证后台的 Flume 进程按页面的操作指令执行,但用户体验很纠结。

异步任务管理过程中等待常量是 2秒,加上整个 Web 处理操作,以及 Controller 里面的 Sleep 操作,通过 Web 页面对 Flume 任务的管理操作响应时间平均 8 秒左右。

我在测试的时候编辑一个启用状态的任务,提交后需要心里默数到 20 才能看到页面操作结果,确实需要很大的耐心。现场也反馈过这个问题,怎么优化呢?

优化思路

既然都用异步了,为什么非要 awaitsleep 呢?最初思路是,直接去掉这些代码,页面响应果然很快,但是操作结果总是不合理。

  1. 停止、启动连续操作时,Flume 进程并没有启动:点击 「停止」操作,立即点「启动」,Flume 进程并没有起来。
  2. 编辑启动状态的任务:先停止、再启动操作,进程也没有启动。

这是因为线程池调度任务的是多线程的,而停止操作为了保证进程能被 kill 掉,它的逻辑是:

kill 进程ID
休眠 2 秒
再 kill -9

启动操作命令和停止操作一起的时候,最终启动的进程 2秒后又被 kill 掉了,所以直接去掉休眠操作不行。除了休眠等待,怎么保证线程池提按 Runnable 的提交顺序执行呢?

解决办法

更换线程池类型,用 Executors.newSingleThreadExecutor() 保证按提交顺序执行 Runnable;前端只管提交操作命令,后台调度时去掉所有的 await /sleep 等阻塞操作,立即返回响应结果给页面。

优化前,修改一个启动状态的任务,耗时 11 秒:
在这里插入图片描述
优化后,相同操作耗时 700 毫秒:
在这里插入图片描述

启示录

除了休眠等待,怎么保证线程池提按 Runnable 的提交顺序执行呢?我甚至尝试了去更改 flume-ng 脚本,启动任务之前先 kill 掉之前的任务,结果直接把刚刚启动的 flume 任务又给 kill 掉了。

后来想到了还是要在线程池的调度顺序上,如何让Java的线程池顺序执行任务?这不就是 newSingleThreadExecutor 嘛?

他强任他强,清风拂山冈;任他前端怎么点,单线程调度按序走!
不搭题,就是想到了这句话而已。

不间断地 在 CSDN 写博客十多年了,CSDN 有流量没收益,转场掘金,有收益,没流量。本文首发掘金, 《掘金金石计划投稿》求赞!

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

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

相关文章

头歌——机器、深度学习——手写体识别

第1关:神经网络基本概念 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务,你需要掌握:1.神经网络基本概念。 神经网络基本概念 神经网络由输入层、隐藏层、输出层组成;…

【华为OD机试】最左侧冗余覆盖子串(C++ Java JavaScript Python )

题目 题目描述 给定两个字符串s1和s2和正整数K,其中s1长度为n1,s2长度为n2,在s2中选一个子串,满足: 该子串长度为n1+k该子串中包含s1中全部字母,该子串每个字母出现次数不小于s1中对应的字母,我们称s2以长度k冗余覆盖s1,给定s1,s2,k,求最左侧的s2以长度k冗余覆盖s1的…

逆向学习网络篇:心跳包与TCP服务器

本节课在线学习视频(网盘地址,保存后即可免费观看): ​​https://pan.quark.cn/s/31c74a06f8db​​ 在网络通信中,心跳包是一种重要的机制,用于维持客户端与服务器之间的连接状态。本文将深入探讨心跳包的…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-22池化层

22池化层 import torch from torch import nn# 最大汇聚层和平均汇聚层 def pool2d(X, pool_size, modemax):p_h, p_w pool_sizeY torch.zeros((X.shape[0] - p_h 1, X.shape[1] - p_w 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode max:Y[i, j] X…

【源码】含70演示高转化率Magento2外贸时装女装跨境电商模板V1.2.2

MagMog是下一代最高转化率和可扩展的跨境电商Magento2主题,让您几乎可以立即上手。这是一个终极解决方案:主题附带一系列电子商务功能,可以启用您商店的隐藏功能,并且您无需支付任何额外费用。 100% 免费。 MagMog从定制设计到内…

AI大模型企业应用实战(16)-langchain核心组件

1 stuff 将文档列表插入到提示词中,适合文档较小或少量文档的应用。 2 refine 通过循环输入文档并迭代更新答案来构建响应,一次只传递给LLM一个文档,适合LLM上下文大小不能容纳的小文档。 参考: https://js.langchain.com/v0.1…

搭建个人官网时如何配置SMTP邮件自动发送

什么是 SMTP? SMTP( Simple Mail Transfer Protocol ) 是一种简单邮件传输协议,可以在互联网上通过SMTP来发送电子邮件,是建模在 FTP 文件传输服务上的一种邮件服务,主要用于传输系统之间的邮件信息并提供来信有关的通知。SMTP 服…

pycharm不能安装包的解决方法

一直使用VScode写python,最近使用pycharm,但是pycharm不能安装包,类似这种 后面直接使用ALT F12跳转终端: pip install 需要添加的包 -i https://pypi.tuna.tsinghua.edu.cn/simple不报错了

量检具管理有一套

量检具是用于测量和检验产品尺寸、形状和质量的工具。有一位年轻的工程师小张,他负责管理工厂的量检具,确保它们能够准确地测量产品尺寸和质量。有一天,小张发现量检具出现了一些问题。他注意到一些量具的读数不准确,导致生产出来…

常见的 Linux 命令

在 Linux 系统中,有许多常用的命令可用于执行各种任务。以下是一些基本和常用的 Linux 命令及其用途: 文件和目录操作 显示当前目录 pwd # 显示当前工作目录的路径列出目录内容 ls # 列出当前目录的文件和子目录 ls -l # 以详细格式列出文件和目录…

【吊打面试官系列-Mysql面试题】NULL 是什么意思?

大家好,我是锋哥。今天分享关于 【NULL 是什么意思?】面试题,希望对大家有帮助; NULL 是什么意思? 答:NULL 这个值表示 UNKNOWN(未知):它不表示“”(空字符串)。对 NULL 这个值的任何比较都会生产一个 NULL 值。您不能…

ABAP - SALV SET_ZERO方法不显示金额0.00

财务觉得报表上的金额为0的数据混淆视线,所以提出了报表不显示0.00的格式要求。 要求报表是这个样: SALV提供了 cl_salv_column_table->set_zero() 来进行控制金额0.00是否显示 实现SALV不显示金额0.00关键代码: DATA:lo_columns TYPE …

LeetCode:经典题之206、92题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …

Java中的反射编程实用指南

Java中的反射编程实用指南 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,我们将深入探讨Java中的反射编程。反射是Java提供的一种强大机制&am…

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 &am…

注塑件检测视觉检测中可能遇到的外观缺陷

机器视觉检测注塑件不良特征有哪些?按照检测需求一般分为两类:外观缺陷和尺寸缺陷。但由于注塑件的工艺特点及原材料特性,注塑件外观缺陷在生产过程中出现的概率于频率远远大于尺寸缺陷。 注塑件检测视觉检测中可能遇到的外观缺陷 1、色差&a…

竞赛选题 python+opencv+深度学习实现二维码识别

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 pythonopencv深度学习实现二维码识别 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:3分 该项目较为新颖&…

Vue核心指令解析:探索MVVM与数据操作之美

文章目录 前言一、Vue.js1. MVVM模式介绍2. 单页面组件介绍及案例讲解3. 插值表达式介绍及案例讲解 二、Vue常用指令详解1. 数据绑定指令v-textv-html 2. 条件渲染指令v-ifv-show 3. 列表渲染指令v-for循环数组介绍及案例讲解循环对象介绍及案例讲解 4. 事件监听指令v-on事件修…

Oracle-重启数据库及可能遇到的问题

1、登录到oracle用户 su - oracle2、关闭监听 lsnrctl stop3、杀掉oracle有关进程 #下面两条命令结合成一条 ps -ef|grep $ORACLE_SID|grep -v ora_|grep LOCALNO|awk {print $2}|xargs kill -9#查询pid ps -ef|grep $ORACLE_SID|grep -v ora_|grep LOCALNO|awk {print $2}…

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antd npm i lodash-es npm i types/lodash-es -D/components/CommonSearch index.tsx import React from react; import { Button, Card, Form } from antd; import styles from ./…