1.通过transmittable-thread-local源码理解线程池线程本地变量传递的码解原理
2.RocketMQ延迟消息的极限是多少
3.STM32F103正点原子学习笔记系列——串口
4.tracert工作原理&路由原理
5.linux中查看网卡流量六种方法
6.ClickHouse 源码解析: MergeTree Merge 算法
通过transmittable-thread-local源码理解线程池线程本地变量传递的原理
最近几周,我投入了大量的码解时间和精力,完成了UCloud服务和中间件迁移至阿里云的码解工作,因此没有空闲时间撰写文章。码解不过,码解回忆起很早之前对ThreadLocal源码的码解qq ios源码下载分析,其中提到了ThreadLocal存在向预先创建的码解线程中传递变量的局限性。恰好,码解我的码解一位前同事,HSBC的码解技术大牛,提到了团队引入了transmittable-thread-local(TTL)来解决此问题。码解借此机会,码解我深入分析了TTL源码,码解本文将全面分析ThreadLocal和InheritableThreadLocal的码解局限性,并深入探讨TTL整套框架的码解实现。如有对线程池和ThreadLocal不熟悉的读者,建议先阅读相关前置文章,本篇文章行文较为干硬,字数接近5万字,希望读者耐心阅读。
在Java中,没有直接的API允许子线程获取父线程的实例。获取父线程实例通常需要通过静态本地方法Thread#currentThread()。同样,为了在子线程中传递共享变量,也常采用类似的方法。然而,这种方式会导致硬编码问题,限制了方法的复用性和灵活性。为了解决这一问题,线程本地变量Thread Local应运而生,其基本原理是通过线程实例访问ThreadLocal.ThreadLocalMap来实现变量的存储与传递。
ThreadLocal与InheritableThreadLocal之间的区别主要在于控制ThreadLocal.ThreadLocalMap的创建时机和线程实例中对应的属性获取方式。通过分析源码,可以清楚地看到它们之间的联系与区别。对于不熟悉概念的读者,可以尝试通过自定义实现来理解其中的原理与关系。
ThreadLocal和InheritableThreadLocal的最大局限性在于无法为预先创建的线程实例传递变量。泛线程池Executor体系、TimerTask和ForkJoinPool等通常会预先创建线程,因此无法在这些场景中使用ThreadLocal和InheritableThreadLocal来传递变量。抽签特效网页源码
TTL提供了更灵活的解决方案,它通过委托机制(代理模式)实现了变量的传递。委托可以基于Micrometer统计任务执行时间并上报至Prometheus,然后通过Grafana进行监控展示。此外,TTL通过字节码增强技术(使用ASM或Javassist等工具)实现了类加载时期替换Runnable、Callable等接口的实现,从而实现了无感知的增强功能。TTL还使用了模板方法模式来实现核心逻辑。
TTL框架的核心类TransmittableThreadLocal继承自InheritableThreadLocal,通过全局静态变量holder来管理所有TransmittableThreadLocal实例。holder实际上是一个InheritableThreadLocal,用于存储所有线程本地变量的映射,实现变量的全局共享。disableIgnoreNullValueSemantics属性的设置可以影响NULL值的处理方式,影响TTL实例的行为。
发射器Transmitter是TransmittableThreadLocal的一个公有静态类,提供传输TransmittableThreadLocal实例和注册当前线程变量至其他线程的功能。通过Transmitter的静态方法,可以实现捕获、重放和复原线程本地变量的功能。
TTL通过TtlRunnable类实现了任务的封装,确保在执行任务时能够捕获和传递线程本地变量。在任务执行前后,通过capture和restore方法捕获和重放变量,实现异步执行时上下文的传递。
启用TTL的Agent模块需要通过Java启动参数添加javaagent来激活字节码增强功能。TTL通过Instrumentation回调激发ClassFileTransformer,实现目标类的字节码增强,从而在执行任务时自动完成上下文的捕捉和传递。
TTL框架提供了一种高效、灵活的方式来解决线程池中线程复用时上下文传递的问题。通过委托机制和字节码增强技术,TTL实现了无入侵地提供线程本地变量传递功能。如果您在业务代码中遇到异步执行时上下文传递的问题,TTL库是一个值得考虑的解决方案。
RocketMQ延迟消息的极限是多少
在实际开发过程中利用RocketMQ延迟发消息的功能会遇到设定时间后不起效果,没有延迟立刻就会消费到消息这种问题,所以经过查源码发现:这里失败的原因就是与消息的过期事件(TTL)有直接的关系。在RocketMQ中过期时间必须是阿修罗刀源码非负位整数即0<=n<= 2^-1 以毫米为单位,2^-1 = ,所以它的延迟消息的极限值就是毫秒,大概也就是天最长时间。STMF正点原子学习笔记系列——串口
数据通信的基础概念涉及到串行和并行通信、单工、半双工、全双工通信以及同步、异步通信。串行通信仅需一根线传输数据,而并行通信则需要多根线。通信方向的分类包括单工(数据单向传输)、半双工(双向传输需分时进行)和全双工(同时双向传输)。同步通信共享同一时钟信号,而异步通信则通过在数据中加入起始位和停止位来同步。
串口(RS)是按位发送和接收的接口,常见的有RS、RS和RS等。RS接口的典型配置包括数据输出(TXD)和数据输入(RXD),以及地线(GND)。在Stm中,主要关注的接口是TXD、RXD和GND。RS与CMOS/TTL电平之间存在差异:RS的逻辑1为-~-3V,逻辑0为+3~+V,而CMOS电平的逻辑1为3.3V,逻辑0为0V。TTL电平的逻辑1为5V,逻辑0为0V。由于电平的不兼容,CMOS/TTL不能直接与RS进行信息交换。
RS通信协议包括:启动位(必须占1位,电平为逻辑0),有效数据位(可选5-9位,LSB在前,MSB在后),校验位(可选1位,可不设置),以及停止位(必须有,可选0.5-2位,电平为逻辑1)。RS异步通信协议的狂风副本源码这些要素是通信过程中的关键组成部分。
STM的USART(通用同步异步收发器)可以与外部设备进行全双工异步通信,其主要特征包括数据寄存器(DR)、波特率部分、波特率寄存器(BRR)等。在进行读写操作时,只能操作数据寄存器。USART的波特率部分依赖于挂载在哪个时钟总线上,如APB1或APB2。在设置波特率时,需要计算USARTDIV的值,该值取决于挂载的时钟频率和使用的波特率。
HAL库为STM提供了外设初始化和中断回调机制,MspInit()是一个留给用户定义的接口,用于完成GPIO、NVIC、CLOCK等的初始化。串口USART的初始化涉及到GPIO的配置、时钟通道的选择、中断优先级的设置等。通过HAL库的函数,可以以中断或阻塞的方式实现USART/UART的异步通信。
IO引脚的复用功能使得GPIO端口既能够用于输入/输出,也能被其他非GPIO外设控制。在F1系列的STM中,有多种引脚复用配置选项,允许用户根据需求灵活配置。
编程实战和源码解读部分则涉及到实际的项目开发和代码理解,包括如何在特定项目中应用上述通信原理和库函数,以及如何通过阅读和分析源码来深入理解底层实现和优化代码。
tracert工作原理&路由原理
1:1 <1 ms <1 ms <1 ms proxy.huayuan.hy [...1]
2 * ms ms ..2.3
3 ms ms ms ...
4 ms ms ms ..7.
5 ms ms ms ..3.
6 ms ms ms ..3.
7 ms ms ms xd--5-a8.bta.net.cn [...5]
Trace complete.
看一下上面这个过程 应该不用解释了
下面我们来分析一下 我们是怎么看到这个回显的
大家都知道我们所发送的tracert数据包 属于icmp数据包的一种
关于ttl的概念不知道能否理解
ttl 就是生存时间的意思 也就是我们所发送的数据包 在转发过程中的寿命问题
很好理解 如果寿命为0的话 就不能到达目的地 每经过一个三层设备我们的数据包的
ttl值都会减一 如果减到0 就证明不能到达就会给我们的源主机一个回应显示
并告知源主机 在哪个三层设备将这个生存值置0的 然后将这个三层设备的ip地址转发给
源主机
上面我们说的是ttl的一个原理和作用
下面我们来说 tracert包的原理
我们发送TRACERT包时 第一次的包的ttl值为1 这样到第一个三层设备那就会给
源主机一个回应 并告知其IP
依次类推 第二次发送的时候的TTL值等于2
第三次为3 默认最大hop为
也就是说ttl最大升到
这样我门就能清楚的看到 我们的数据包是怎么到达目的地的
2:当IP子网中的一台主机发送IP分组给同一IP子网的另一台主机时,它将直接把IP分组送到网络上,对方就能收到。而要送给不同IP子网上的主机时,它要选择一个能到达目的子网上的路由器,把IP分组送给该路由器,由路由器负责把IP分组送到目的地。如果没有找到这样的路由器,主机就把IP分组送给一个称为“缺省网关(default gateway)”的路由器上。“缺省网关”是每台主机上的一个配置参数,它是js怎么替换源码接在同一个网络上的某个路由器端口的IP地址。
路由器转发IP分组时,只根据IP分组目的IP地址的网络号部分,选择合适的端口,把IP分组送出去。同主机一样,路由器也要判定端口所接的是否是目的子网,如果是,就直接把分组通过端口送到网络上,否则,也要选择下一个路由器来传送分组。路由器也有它的缺省网关,用来传送不知道往哪儿送的IP分组。这样,通过路由器把知道如何传送的IP分组正确转发出去,不知道的IP分组送给“缺省网关”路由器,这样一级级地传送,IP分组最终将送到目的地,送不到目的地的IP分组则被网络丢弃了。目前TCP/IP网络,全部是通过路由器互连起来的,Internet就是成千上万个IP子网通过路由器互连起来的国际性网络。网络称为以路由器为基础的网络(router based network),形成了以路由器为节点的“网间网”。在“网间网”中,路由器不仅负责对IP分组的转发,还要负责与别的路由器进行联络,共同确定“网间网”的路由选择和维护路由表。路由动作包括两项基本内容:寻径和转发。寻径即判定到达目的地的最佳路径,由路由选择算法来实现。由于涉及到不同的路由选择协议和路由选择算法,要相对复杂一些。为了判定最佳路径,路由选择算法必须启动并维护包含路由信息的路由表,其中路由信息依赖于所用的路由选择算法而不尽相同。路由选择算法将收集到的不同信息填入路由表中,根据路由表可将目的网络与下一站(nexthop)的关系告诉路由器。路由器间互通信息进行路由更新,更新维护路由表使之正确反映网络的拓扑变化,并由路由器根据量度来决定最佳路径。这就是路由选择协议(routing protocol),例如路由信息协议(RIP)、开放式最短路径优先协议(OSPF)和边界网关协议(BGP)等。
转发即沿寻径好的最佳路径传送信息分组。路由器首先在路由表中查找,判明是否知道如何将分组发送到下一个站点(路由器或主机),如果路由器不知道如何发送分组,通常将该分组丢弃;否则就根据路由表的相应表项将分组发送到下一个站点,如果目的网络直接与路由器相连,路由器就把分组直接送到相应的端口上。这就是路由转发协议(routed protocol)。
路由转发协议和路由选择协议是相互配合又相互独立的概念,前者使用后者维护的路由表,同时后者要利用前者提供的功能来发布路由协议数据分组。
linux中查看网卡流量六种方法
方法一、nload工具源码包路径:
查看参数帮助命令:
nload help
-a:这个好像是全部数据的刷新时间周期,单位是秒,默认是.
-i:进入网卡的流量图的显示比例最大值设置,默认 kBit/s.
-m:不显示流量图,只显示统计数据。
-o:出去网卡的流量图的显示比例最大值设置,默认 kBit/s.
-t:显示数据的刷新时间间隔,单位是毫秒,默认。
-u:设置右边Curr、Avg、Min、Max的数据单位,默认是自动变的.注意大小写单位不同!
h|b|k|m|g h: auto, b: Bit/s, k: kBit/s, m: MBit/s etc.
H|B|K|M|G H: auto, B: Byte/s, K: kByte/s, M: MByte/s etc.
-U:设置右边Ttl的数据单位,默认是自动变的.注意大小写单位不同(与-u相同)!
Devices:自定义监控的网卡,默认是全部监控的,使用左右键切换。
如只监控eth0命令: nload eth0
方法二、iftop工具
源码包路径:
/%7Epdw/iftop/download/iftop-0..tar.gz
1、iftop界面相关说明
界面上面显示的是类似刻度尺的刻度范围,为显示流量图形的长条作标尺用的。
中间的= =这两个左右箭头,表示的是流量的方向。
TX:发送流量
RX:接收流量
TOTAL:总流量
Cumm:运行iftop到目前时间的总流量
peak:流量峰值
rates:分别表示过去 2s s s 的平均流量
2、iftop相关参数
常用的参数
-i设定监测的网卡,如:# iftop -i eth1
-B 以bytes为单位显示流量(默认是bits),如:# iftop -B
-n使host信息默认直接都显示IP,如:# iftop -n
-N使端口信息默认直接都显示端口号,如: # iftop -N
-F显示特定网段的进出流量,如# iftop -F ..1.0/或# iftop -F ..1.0/...0
-h(display this message),帮助,显示参数信息
-p使用这个参数后,中间的列表显示的本地主机信息,出现了本机以外的IP信息;
-b使流量图形条默认就显示;
-f这个暂时还不太会用,过滤计算包用的;
-P使host信息及端口信息默认就都显示;
-m设置界面最上边的刻度的最大值,刻度分五个大段显示,例:# iftop -m M
进入iftop画面后的一些操作命令(注意大小写)
按h切换是否显示帮助;
按n切换显示本机的IP或主机名;
按s切换是否显示本机的host信息;
按d切换是否显示远端目标主机的host信息;
按t切换显示格式为2行/1行/只显示发送流量/只显示接收流量;
按N切换显示端口号或端口服务名称;
按S切换是否显示本机的端口信息;
按D切换是否显示远端目标主机的端口信息;
按p切换是否显示端口信息;
按P切换暂停/继续显示;
按b切换是否显示平均流量图形条;
按B切换计算2秒或秒或秒内的平均流量;
按T切换是否显示每个连接的总流量;
按l打开屏幕过滤功能,输入要过滤的字符,比如ip,按回车后,屏幕就只显示这个IP相关的流量信息;
按L切换显示画面上边的刻度;刻度不同,流量图形条会有变化;
按j或按k可以向上或向下滚动屏幕显示的连接记录;
按1或2或3可以根据右侧显示的三列流量数据进行排序;
按根据左边的本机名或IP排序;
按根据远端目标主机的主机名或IP排序;
按o切换是否固定只显示当前的连接;
按f可以编辑过滤代码,这是翻译过来的说法,我还没用过这个!
按!可以使用Shell命令,这个没用过!没搞明白啥命令在这好用呢!
按q退出监控。
方法三、 ifstat
源码包路径:
mand
DESCRIPTION
watch runs command repeatedly, displaying its output (the first screenfull). This allows you to watch the program output change over time. By default, the program is run every 2 seconds; use -n or --interval to specify a different interval.
The -d or --differences flag will highlight the differences between successive updates. The --cumulative option makes highlighting sticky, presenting a running display of all positions that have ever changed. The -t or --no-title option turns off the header showing the interval, command, and current time at the top of the display, as well as the following blank line. watch will run until interrupted.
NOTE
Note that command is given to sh -c which means that you may need to use extra quoting to get the desired effect.
Note that POSIX option processing is used (i.e., option processing stops at the first non-option argument). This means that flags after command don't get interpreted by watch itself.
EXAMPLES
To watch for mail, you might do: watch -n from
To watch the contents of a directory change, you could use: watch -d ls -l
If youre only interested in files owned by user joe, you might use: watch -d 'ls -l fgrep joe'
You can watch for your administrator to install the latest kernel with: watch uname -r (Just kidding.)呵呵
BUGS
Upon terminal resize, the screen will not be correctly repainted until the next scheduled update. All --differences highlighting is lost on that update as well.
Non-printing characters are stripped from program output. Use cat -v as part of the command pipeline if you want to see them.
方法六、
watch cat /proc/net/dev
ClickHouse 源码解析: MergeTree Merge 算法
ClickHouse MergeTree 「Merge 算法」 是对 MergeTree 表引擎进行数据整理的一种算法,也是 MergeTree 引擎得以高效运行的重要组成部分。
理解 Merge 算法,首先回顾 MergeTree 相关背景知识。ClickHouse 在写入时,将一次写入的数据存放至一个物理磁盘目录,产生一个 Part。然而,随着插入次数增多,查询时数据分布不均,形成问题。一种常见想法是合并小 Part,类似 LSM-tree 思想,形成大 Part。
面临合并策略的选择,"数据插入后立即合并"策略会迅速导致写入成本失控。因此,需要在写入放大与 Part 数量间寻求平衡。ClickHouse 的 Merge 算法便是实现这一平衡的解决方案。
算法通过参数 base 控制参与合并的 Part 数量,形成树形结构。随着合并进行,形成不同层,总层数为 MergeTree 的深度。当树处于均衡状态时,深度与 log(N) 成比例。base 参数用于判断参与合并的 Part 是否满足条件,总大小与最大大小之比需大于等于 base。
执行合并时机在每次插入数据后,但并非每次都会真正执行合并操作。对于给定的多个 Part,选择最适合合并的组合是一个数学问题,ClickHouse 限制为相邻 Part 合并,降低决策复杂度。最终,通过穷举找到最优组合进行合并。
合并过程涉及对有序数组进行多路合并。ClickHouse 使用 Sort-Merge Join 类似算法,通过顺序扫描多个 Part 完成合并过程,保持有序性。算法复杂度为 Θ(M * N),其中 M 为 Part 长度,N 为参与合并的 Part 数量。
对于非主键字段,ClickHouse 提供两种处理方式:Horizontal 和 Vertical。Vertical 分为两个阶段,分别处理非主键字段的合并和输出。
源码解析包括 Merge 触发时机、选择需要合并的 Parts、执行合并等部分。触发时机主要在写入数据时,考虑执行 Mutate 任务后。选择需要合并的 Parts 通过 SimpleMergeSelector 实现,考虑了与 TTL 相关的特殊 Merge 类型。执行合并的类为 MergeTask,分为三个阶段:ExecuteAndFinalizeHorizontalPart、VerticalMergeStage。
Merge 算法是 MergeTree 高性能的关键,平衡写入放大与查询性能,是数据整理过程中的必要步骤。此算法通过参数和决策逻辑实现了在不同目标之间的权衡。希望以上信息能帮助你全面理解 Merge 算法。
Linux下调整TTL值的方法linux修改ttl
Linux系统是一种多用户、多任务、开放源码的多种操作系统,如果要在Linux上调整TTL值,就需要了解TTL(Time to Live)这个缩写。TTL可以用来控制数据包在网络中传播的距离,它还有助于减少网络中已经损坏的数据包的数量。本文将介绍如何在Linux系统下调整TTL值。
首先,你必须找到所要修改的TTL值所在的系统文件,一般在/etc/sysctl来存储系统中相关的内核参数的设置文件。TTL值的设定是由“net.ipv4.ip_default_ttl”参数来完成的。通常情况下,该参数的值为。
修改TTL参数值的命令: echo “net.ipv4.ip_default_ttl=” >> /etc/sysctl.conf
注意,上述命令并不能改变当前的TTL值,而是将该值写入系统参数配置文件。在该参数写入系统参数配置文件之后,TTL值的修改也不会立刻生效,而是需要重新载入hcf文件才能真正生效:sysctl -p
在修改完TTL值之后,我们可以通过以下命令来查看修改是否生效: sysctl net.ipv4.ip_default_ttl
此外,如果要在正式使用TTL值前先进行测试,就可以通过ping命令来测试,格式为:
ping -t
上述命令将会告诉ping命令要在发出的数据包的TTL的值,这样就可以测试出新的TTL值是否有效。
通过以上方法,我们就可以在Linux系统中调整TTL值,并确保这些设置的生效。在修改TTL值之前,一定要谨慎务必,因为它很有可能会造成网络不稳定,甚至严重拥堵。
急啊!大家谁知道这个BAT代码的内容是什么意思的告诉我,追加分!内容如下: @Echo off ping .0.0.1 -i
首先解决:@Echo off (关闭回显)
@echo off并不是DOS程序中的, 而是DOS批处理中的。当年的DOS,所有操作都用键盘命令来完成,当你每次都要输入相同的命令时,可以把这么多命令存为一个批处理,从此以后,只要运行这个批处理,就相当于打了几行、几十行命令。
DOS在运行批处理时,会依次执行批处理中的每条命令 ,并且会在显示器上显示,如果你不想让它们显示,可以加一个“echo off” 当然,“echo off”也是命令,它本身也会显示,如果连这条也不显示,就在前面加个“@”。
再次:ping .0.0.1 (本机回环地址),测试正常,则说明本机TCP/iP协议安装正常。或者说网卡没问题
如果这个都没有回应,有故障要先解决系统层面的。
至于-i 是ping命令的一个参数哦,就是指定发送回响请求消息的IP标题中的TTL字段值,其默认值是主机的默认TTL值。对于Windows XP 主机,该值一般是。TTL的最大值是。