从xxl-job源码中学习Netty的使用
1. 启动与Spring实例化
com.xxl.job.core.executor.impl.XxlJobSpringExecutor.java类
继承SmartInitializingSingleton 类,在afterSingletonsInstantiated 实例化后方法中
调用initJobHandlerMethodRepository 把所有的xxljob任务管理起来;
private void initJobHandlerMethodRepository(ApplicationContext applicationContext) {if (applicationContext == null) {return;}// init job handler from method//扫描所有的bean,并获取XxlJob的注解,registJobHandler加入到 一个 map 中// 见jobHandlerRepositoryString[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);for (String beanDefinitionName : beanDefinitionNames) {Object bean = applicationContext.getBean(beanDefinitionName);Map<Method, XxlJob> annotatedMethods = null; // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBeantry {annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),new MethodIntrospector.MetadataLookup<XxlJob>() {@Overridepublic XxlJob inspect(Method method) {return AnnotatedElementUtils.findMergedAnnotation(method, XxlJob.class);}});} catch (Throwable ex) {logger.error("xxl-job method-jobhandler resolve error for bean[" + beanDefinitionName + "].", ex);}if (annotatedMethods==null || annotatedMethods.isEmpty()) {continue;}for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {Method executeMethod = methodXxlJobEntry.getKey();XxlJob xxlJob = methodXxlJobEntry.getValue();if (xxlJob == null) {continue;}String name = xxlJob.value();if (name.trim().length() == 0) {throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");}if (loadJobHandler(name) != null) {throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");}// execute method/*if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +"The correct method format like \" public ReturnT<String> execute(String param) \" .");}if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +"The correct method format like \" public ReturnT<String> execute(String param) \" .");}*/executeMethod.setAccessible(true);// init and destoryMethod initMethod = null;Method destroyMethod = null;if (xxlJob.init().trim().length() > 0) {try {initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());initMethod.setAccessible(true);} catch (NoSuchMethodException e) {throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");}}if (xxlJob.destroy().trim().length() > 0) {try {destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());destroyMethod.setAccessible(true);} catch (NoSuchMethodException e) {throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");}}// registry jobhandler//扫描所有的jobhandlerregistJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod));}}}
2. 调用父类的start() 方法 启动netty服务端
com.xxl.job.core.executor.XxlJobExecutor#initEmbedServer
核心代码见com.xxl.job.core.server.EmbedServer#start
// start server 服务端ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel channel) throws Exception {channel.pipeline()//心跳机制.addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS)) // beat 3N, close if idle// 使用 http 协议.addLast(new HttpServerCodec())// 拆包粘包.addLast(new HttpObjectAggregator(5 * 1024 * 1024)) // merge request & reponse to FULL// 业务处理EmbedHttpServerHandler.addLast(new EmbedHttpServerHandler(executorBiz, accessToken, bizThreadPool));}}).childOption(ChannelOption.SO_KEEPALIVE, true);// bindChannelFuture future = bootstrap.bind(port).sync();logger.info(">>>>>>>>>>> xxl-job remoting server start success, nettype = {}, port = {}", EmbedServer.class, port);// start registrystartRegistry(appname, address);// wait util stopfuture.channel().closeFuture().sync();
3. 定时任务发起一个任务执行 调用netty server段的接口
此处以手动调用为一个例子; 定时任务&时间轮见下回分析
com.xxl.job.admin.core.thread.JobTriggerPoolHelper#trigger
@startuml tomcat
JobInfoController -> JobTriggerPoolHelper: trigger()
JobTriggerPoolHelper -> XxlJobTrigger:trigger()
XxlJobTrigger -> XxlJobTrigger: processTrigger()
XxlJobTrigger -> XxlJobTrigger : runExecutor()
XxlJobTrigger -> ExecutorBizImpl :run()
@enduml

最终调用
@Overridepublic ReturnT<String> run(TriggerParam triggerParam) {return XxlJobRemotingUtil.postBody(addressUrl + "run", accessToken, timeout, triggerParam, String.class);}
4. 其他netty 详细内容见下回分析;
相关文章:
从xxl-job源码中学习Netty的使用
1. 启动与Spring实例化 com.xxl.job.core.executor.impl.XxlJobSpringExecutor.java类 继承SmartInitializingSingleton 类,在afterSingletonsInstantiated 实例化后方法中 调用initJobHandlerMethodRepository 把所有的xxljob任务管理起来; private…...
人工智能发展历程了解和Tensorflow基础开发环境构建
目录 人工智能的三次浪潮 开发环境介绍 Anaconda Anaconda的下载和安装 下载说明 安装指导 模块介绍 使用Anaconda Navigator Home界面介绍 Environment界面介绍 使用Jupter Notebook 打开Jupter Notebook 配置默认目录 新建文件 两种输入模式 Conda 虚拟环境 添…...
makefile追加warning日志
在Makefile中,你不能直接“追加”warning日志到构建过程中,但你可以通过几种方式在构建时产生额外的警告或消息。以下是一些常用的方法: 使用echo或printf命令: 在Makefile的规则中,你可以使用echo或printf命令来输出警…...
不要直接使用unidefined 而使用void 0
为什么不要使用unidefined 而使用void 0? 在JavaScript中,undefined 和 void 0 都可以用来表示未定义的值,但它们在使用和上下文中有一些微妙的差异,这也是为什么有时可能会推荐使用 void 0 而不是直接使用 undefined。 全局污染ÿ…...
注解详解系列 - @Scope:Bean作用域管理
注解简介 在今天的注解详解系列中,我们将探讨Scope注解。Scope是Spring框架中的一个重要注解,用于定义Spring bean的作用域。通过指定bean的作用域,我们可以控制bean的生命周期和创建方式。 注解定义 Scope注解用于指定Spring bean的作用域…...
数学建模基础:数学建模概述
目录 前言 一、数学建模的步骤 二、模型的分类 三、模型评价指标 四、常见的数学建模方法 实际案例:线性回归建模 步骤 1:导入数据 步骤 2:数据预处理 步骤 3:建立线性回归模型 步骤 4:模型验证 步骤 5&…...
人工智能大模型之开源大语言模型汇总(国内外开源项目模型汇总)
开源大语言模型完整列表 Large Language Model (LLM) 即大规模语言模型,是一种基于深度学习的自然语言处理模型,它能够学习到自然语言的语法和语义,从而可以生成人类可读的文本。 所谓"语言模型",就是只用来处理语言文…...
数据结构之B树
引言 在计算机科学中,数据结构是用于组织和存储数据的关键工具。其中,B树(B-tree)作为一种自平衡的树形数据结构,被广泛应用于数据库和文件系统中,以提高查找、插入、删除和范围查询的效率。本文将深入探讨…...
双色球预测算法(Java),——森林机器学习、时间序列
最近AI很火,老想着利用AI的什么算法,干点什么有意义的事情。其中之一便想到了双色球,然后让AI给我预测,结果基本都是简单使用随机算法列出了几个数字。 额,,,,咋说呢,双…...
【计算机网络篇】数据链路层(11)在数据链路层扩展以太网
文章目录 🍔使用网桥在数据链路层扩展以太网🥚网桥的主要结构和基本工作原理🎈网桥的主要结构🔎网桥转发帧的例子🔎网桥丢弃帧的例子🔎网桥转发广播帧的例子 🥚透明网桥🔎透明网桥的…...
Ubuntu20.04 使用scrapy-splash爬取动态网页
我们要先安装splash服务,使用dock安装,如果dock没有安装,请参考我的上一篇博文: 按照官方文档:https://splash.readthedocs.io/en/stable/install.html 1.下载splash sudo docker pull scrapinghub/splash2.安装scrapy…...
Function:控制继电器上下电,上电后adb登录,copy配置文件
import serial import time import datetime import subprocess import osdef append_to_txt(file_path, content):if os.path.exists(file_path):with open(file_path, a) as file: # 使用 a 模式打开文件进行追加file.write(content \n) # 追加内容,并换行else…...
香港电讯高可用网络助力企业变革金融计算
客户背景 客户是一家金融行业知名的量化私募对冲基金公司,专注于股票、期权、期货、债券等主要投资市场,在量化私募管理深耕多年,目前资管规模已达数百亿级,在国内多个城市均设有办公地点。 客户需求 由于客户业务倚重量化技术…...
LDR6020一拖二快充线:多设备充电新选择
随着科技的快速发展,我们的日常生活中越来越多地依赖于智能设备。然而,每当手机、平板或其他移动设备电量告急时,我们总是需要寻找合适的充电线进行充电。为了解决这一痛点,市场上出现了一款备受瞩目的新产品——LDR6020一拖二快充…...
电脑ffmpeg.dll丢失原因解析,找不到ffmpeg.dll的5种解决方法
在数字化时代,多媒体文件的处理已经成为我们日常生活和工作中不可或缺的一部分。在计算机使用过程中,丢失ffmpeg.dll文件是一个特定但常见的问题,尤其是对于那些经常处理视频编解码任务的用户来说。下面小编讲全面分析ffmpeg.dll丢失原因以及…...
手机网站制作软件是哪些
手机网站制作软件是一种用于设计、开发和创建适用于移动设备的网站的软件工具。随着移动互联网时代的到来,越来越多的用户开始使用手机浏览网页和进行在线交流,因此,手机网站制作软件也逐渐成为了市场上的热门工具。 1. Adobe Dreamweaver&am…...
【Kubernetes项目部署】k8s集群+高可用、负载均衡+防火墙
项目架构图 (1)部署 kubernetes 集群 详见:http://t.csdnimg.cn/RLveS (2) 在 Kubernetes 环境中,通过yaml文件的方式,创建2个Nginx Pod分别放置在两个不同的节点上; Pod使用hostP…...
IPC工业电脑的现状、发展未来与破局策略
文章目录 全球工业电脑市场概况1.1 市场规模与增长1.2 区域分布与主要市场 工业电脑的技术发展与应用2.1 技术趋势与创新2.2 应用领域扩展2.3 工业自动化与智能化 竞争格局与市场参与者3.1 主要企业与市场竞争3.2 国内外竞争对比3.3 市场集中度与竞争策略 未来发展趋势与市场预…...
深入了解Redis的TYPE命令
Redis作为一个高性能的内存数据库,支持多种数据结构。在管理和操作Redis数据库时,了解键对应的数据类型是至关重要的。本文将深入探讨Redis的TYPE命令,它用于返回存储在指定键中的值的数据类型。 什么是TYPE命令? TYPE命令用于查…...
iptables(3)规则管理
简介 上一篇文章中,我们已经介绍了怎样使用iptables命令查看规则,那么这篇文章我们就来介绍一下,怎样管理规则,即对iptables进行”增、删、改”操作。 注意:在进行iptables实验时,请务必在个人的测试机上进行,不要再有任何业务的机器上进行测试。 在进行测试前,为保障…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
