Linux perf probe 的使用(三)
文章目录
- 前言
- 一、Dynamic Tracing
- 二、kprobes
- 2.1 perf kprobe 的使用
- 2.2 kprobe Arguments
- 3.3 tcp_sendmsg()
- 3.3.1 Kernel: tcp_sendmsg()
- 3.3.2 Kernel: tcp_sendmsg() with size
- 3.3.2 Kernel: tcp_sendmsg() line number and local variable
- 三、uprobes的使用
- 3.1 perf uprobe 的使用
- 3.2 uprobe Arguments
- 参考资料
前言
perf使用术语探测事件来指kprobes、uprobes和USDT探测。这些是“动态”的,必须先初始化,然后才能跟踪它们:默认情况下,它们不在perf列表的输出中(某些USDT探针可能存在,因为它们已自动初始化)。一旦初始化,它们将被列为“Tracepoint event”。
一、Dynamic Tracing
跟踪点和动态跟踪之间的区别如下图所示,该图说明了常见跟踪点库的覆盖范围:
图片来自于:https://www.brendangregg.com/perf.html
tracepoint和kprobe之间的比较如下表所示:
虽然动态跟踪可以看到所有内容,但它也是一个不稳定的接口,因为它检测原始代码。这意味着您开发的任何动态跟踪工具都可能在内核补丁或更新后崩溃。首先尝试使用静态跟踪点,因为它们的接口应该更稳定。它们也可以更容易使用和理解,因为它们的设计考虑到了跟踪最终用户。
动态跟踪的一个好处是,它可以在实时系统上启用,而无需重新启动任何东西。您可以使用已经运行的内核或应用程序,然后开始动态检测,它(安全地)修补内存中的指令以添加检测。这意味着在您开始使用该功能之前,该功能的开销为零。前一刻,您的二进制文件未经修改且全速运行,下一刻,它将运行您动态添加的一些额外的检测指令。一旦您使用完动态跟踪会话,这些指令最终应该被删除。
使用动态跟踪和执行额外指令时的开销与检测事件的频率乘以每个检测所做的工作有关。
对于内核分析,使用CONFIG_KPROBES=y和CONFIG_KPROBE_EVENTS=y来启用内核动态跟踪,而CONFIG_FRAME_POINTER=y用于基于帧指针的内核堆栈。对于用户级分析,CONFIG_UPROBES=y和CONFIG_UROBE_EVENTS=y用于用户级动态跟踪。
使用 perf-probe 命令动态跟踪函数:
NAMEperf-probe - Define new dynamic tracepointsDESCRIPTIONThis command defines dynamic tracepoint events, by symbol and registers without debuginfo, or by C expressions (C line numbers, C function names, and C local variables) with debuginfo.
常用的一些参数选项:
-a, --add=Define a probe event (see PROBE SYNTAX for detail).-d, --del=Delete probe events. This accepts glob wildcards(*, ?) and character classes(e.g. [a-z], [!A-Z]).-l, --list[=[GROUP:]EVENT]List up current probe events. This can also accept filtering patterns of event names. When this is used with --cache, perf shows all cached probes instead of the live probes.
二、kprobes
2.1 perf kprobe 的使用
以下是创建和使用kprobe的典型工作流,在本例中,用于检测do_nanosleep()内核函数。
动态跟踪的函数要在内核符号文件/proc/kallsyms中:
[root@localhost ~]# cat /proc/kallsyms | grep do_nanosleep
ffffffffb0f66b40 t do_nanosleep
在没有动态跟踪do_nanosleep之前:
[root@localhost ~]# perf list probe:do_nanosleepList of pre-defined events (to be used in -e):Metric Groups:
使用perf list查询不到do_nanosleep事件。
接下来动态跟踪do_nanosleep函数:
perf probe --add do_nanosleep
perf record -e probe:do_nanosleep -a sleep 5
perf script
perf probe --del do_nanosleep
kprobe是使用probe子命令和–add(–add是可选的)创建的,当不再需要它时,将使用probe和–del删除它。以下是该序列的输出,包括列出探测事件:
(1)添加动态事件:
[root@localhost ~]# perf probe --add do_nanosleep
Added new event:probe:do_nanosleep (on do_nanosleep)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1
(2)查看动态事件(do_nanosleep初始化后,将被列为“Tracepoint event”):
[root@localhost ~]# perf list probe:do_nanosleepList of pre-defined events (to be used in -e):probe:do_nanosleep [Tracepoint event]Metric Groups:
(3)record/script 动态事件
[root@localhost ~]# perf record -e probe:do_nanosleep -aR sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.618 MB perf.data (3 samples) ]
[root@localhost ~]# perf scriptsleep 30562 [001] 63910.281197: probe:do_nanosleep: (ffffffffb0f66b40)sleep 30568 [000] 63910.340391: probe:do_nanosleep: (ffffffffb0f66b40)pool 6556 [002] 63910.844546: probe:do_nanosleep: (ffffffffb0f66b40)
[root@localhost ~]# cat /proc/kallsyms | grep do_nanosleep
ffffffffb0f66b40 t do_nanosleep
(4)删除动态事件
[root@localhost ~]# perf probe --del probe:do_nanosleep
Removed event: probe:do_nanosleep
(5)kretprobe
可以通过添加%return来检测函数的返回:
[root@localhost ~]# perf probe --add do_nanosleep%return
Added new event:probe:do_nanosleep (on do_nanosleep%return)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1
这使用kretprobe:
[root@localhost ~]# perf probe --add do_nanosleep%return
Added new event:probe:do_nanosleep (on do_nanosleep%return)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]#
[root@localhost ~]# perf record -e probe:do_nanosleep -aR sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.611 MB perf.data (2 samples) ]
[root@localhost ~]# perf scriptpool 6556 [000] 64259.662728: probe:do_nanosleep: (ffffffffb0f66b40 <- ffffffffb08c6a6b)sleep 518 [001] 64260.171569: probe:do_nanosleep: (ffffffffb0f66b40 <- ffffffffb08c6a6b)
[root@localhost ~]# perf probe --del probe:do_nanosleep
Removed event: probe:do_nanosleep
2.2 kprobe Arguments
至少有四种不同的方式将参数插入内核函数。
(1)
首先,如果内核debuginfo可用,那么perf可以获得函数变量(包括参数)的信息。使用–vars选项列出do_nanosleep()kprobe的变量:
-V, --vars=Show available local variables at given probe point. The argument syntax is same as PROBE SYNTAX, but NO ARGs.
[root@localhost ~]# perf probe --vars do_nanosleep
Available variables at do_nanosleep@<do_nanosleep+0>enum hrtimer_mode modestruct hrtimer_sleeper* t
此输出显示名为mode和t的变量,它们是do_nanosleep()的入口参数。可以在创建探头时添加这些内容,以便在记录时包含这些内容。例如,添加模式:
[root@localhost ~]# perf probe 'do_nanosleep mode'
Added new event:probe:do_nanosleep (on do_nanosleep with mode)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]# perf record -e probe:do_nanosleep -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.605 MB perf.data (3 samples) ][root@localhost ~]# perf scriptpool 6556 [000] 64979.664437: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1sleep 5962 [002] 64980.279301: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1pool 6556 [000] 64980.316230: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1
输出显示 mode 变量等于1。
(2)
第二,如果内核debuginfo不可用(正如我在生产中经常发现的那样),那么可以通过它们的寄存器位置读取参数。一个技巧是使用相同的系统(相同的硬件和内核)并在其上安装内核调试信息以供参考。然后,可以使用-n(dry run)和-v(verbose)选项查询此参考系统以查找寄存器位置,以执行探测:
[root@localhost ~]# perf probe -nv 'do_nanosleep mode'
......
Found 1 probe_trace_events.
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Writing event: p:probe/do_nanosleep _text+7760704 mode=%si:u32
Added new event:probe:do_nanosleep (on do_nanosleep with mode)
......
由于它是一个 dry run,因此不会创建事件。但是输出显示了模式变量的位置:它位于寄存器%si中,并打印为32位十六进制数(u32)。现在可以通过复制和粘贴模式声明字符串(mode=%si:x32)在无debuginfo系统上使用此语法:
[root@localhost ~]# perf probe 'do_nanosleep mode=%si:u32'
Added new event:probe:do_nanosleep (on do_nanosleep with mode=%si:u32)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]# perf record -e probe:do_nanosleep -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.606 MB perf.data (3 samples) ][root@localhost ~]# perf scriptpool 6556 [000] 65807.996795: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1sleep 11789 [002] 65808.370905: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1pool 6556 [000] 65808.648566: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1
只有当系统具有相同的处理器ABI和内核版本时,这才有效,否则可能会检测到错误的寄存器位置。
(3)
第三,如果您知道处理器ABI,可以自己确定寄存器位置。下一节中给出了一个 uprobes 的示例。
(4)
第四,有一个新的内核调试信息源:BPF类型格式(BTF)。默认情况下,这更可能是可用的,将来的perf版本应该支持它作为备用的debuginfo源。
(5)
对于使用kretprobe检测的do_nanosleep的返回,可以使用特殊的$retval变量读取返回值:
perf probe 'do_nanosleep%return $retval'
查看内核源代码以确定返回值包含的内容。
3.3 tcp_sendmsg()
3.3.1 Kernel: tcp_sendmsg()
此示例显示在Linux 3.10.0内核上检测内核tcp_sendmsg()函数:
[root@localhost perf]# cat /proc/kallsyms | grep tcp_sendmsg
ffffffffb0e93fc0 T tcp_sendmsg
[root@localhost perf]# perf probe --add tcp_sendmsg
Added new event:probe:tcp_sendmsg (on tcp_sendmsg)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1[root@localhost perf]# perf record -e probe:tcp_sendmsg -a -g -- sleep 5
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.632 MB perf.data (42 samples) ]
[root@localhost perf]# perf report --stdio
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 42 of event 'probe:tcp_sendmsg'
# Event count (approx.): 42
#
# Children Self Trace output
# ........ ........ ..................
#100.00% 100.00% (ffffffffb0e93fc0)|---__GI___libc_writesystem_callsys_writevfs_writedo_sync_writesock_aio_writetcp_sendmsg#
# (Tip: For memory address profiling, try: perf mem record / perf mem report)
这显示了write()系统调用到tcp_sendmsg()的路径。
[root@localhost perf]# perf probe --del tcp_sendmsg
Removed event: probe:tcp_sendmsg
3.3.2 Kernel: tcp_sendmsg() with size
如果内核具有debuginfo(CONFIG_DEBUG_INFO=y),则可以从函数中找出内核变量。这是检查size_ t(整数)的简单示例:
列出tcp_sendmsg()可用的变量:
-V, --vars=Show available local variables at given probe point. The argument syntax is same as PROBE SYNTAX, but NO ARGs.
[root@localhost perf]# perf probe -V tcp_sendmsg
Available variables at tcp_sendmsg@<tcp_sendmsg+0>int size_goallong int timeosize_t sizestruct kiocb* iocbstruct msghdr* msgstruct sock* sk
使用“size”变量为tcp_sendmsg()创建探测:
[root@localhost perf]# perf probe --add 'tcp_sendmsg size'
Added new event:probe:tcp_sendmsg (on tcp_sendmsg with size)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1
Tracing this probe:
[root@localhost perf]# perf record -e probe:tcp_sendmsg -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.628 MB perf.data (49 samples) ][root@localhost perf]# perf scriptsshd 29204 [001] 82790.664230: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82790.664939: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82790.665627: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82790.665712: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.667466: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82790.667566: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.668484: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.668582: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.672211: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82791.674832: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82791.677249: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82791.677519: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.681480: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82791.681772: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.684988: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.685259: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82792.689914: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82792.692504: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82792.694701: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82792.694949: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30......
3.3.2 Kernel: tcp_sendmsg() line number and local variable
使用debuginfo,perf_events可以为内核函数内的行创建跟踪点。列出tcp_sendmsg()的可用行探测:
-L, --line=Show source code lines which can be probed. This needs an argument which specifies a range of the source code. (see LINE SYNTAX for detail)
[root@localhost perf]# perf probe -L tcp_sendmsg
<tcp_sendmsg@/usr/src/debug/kernel-3.10.0-957.el7/linux-3.10.0-957.el7.x86_64/net/ipv4/tcp.c:0>0 int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,size_t size)2 {struct iovec *iov;struct tcp_sock *tp = tcp_sk(sk);struct sk_buff *skb;6 int iovlen, flags, err, copied = 0;7 int mss_now = 0, size_goal, copied_syn = 0, offset = 0;bool sg;long timeo;11 lock_sock(sk);13 flags = msg->msg_flags;14 if (flags & MSG_FASTOPEN) {15 err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);16 if (err == -EINPROGRESS && copied_syn > 0)goto out;18 else if (err)goto out_err;offset = copied_syn;}......}
[root@localhost perf]# perf probe -V tcp_sendmsg:81
Available variables at tcp_sendmsg:81@<tcp_sendmsg+826>bool sgint copiedint flagsint iovlenint mss_nowint offsetint size_goallong int timeosize_t seglenstruct iovec* iovstruct sock* skunsigned char* from
现在让我们跟踪第81行,并在循环中检查seglen变量:
[root@localhost perf]# perf probe --del tcp_sendmsg
Removed event: probe:tcp_sendmsg
[root@localhost perf]# perf probe --add 'tcp_sendmsg:81 seglen'
Added new event:probe:tcp_sendmsg (on tcp_sendmsg:81 with seglen)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1[root@localhost perf]# perf record -e probe:tcp_sendmsg -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.619 MB perf.data (33 samples) ][root@localhost perf]# perf scriptsshd 29204 [001] 83979.203223: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83979.205938: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [001] 83979.208299: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83979.208539: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.214403: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [001] 83979.214656: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.218265: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.218564: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83980.223443: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83980.226039: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83980.226248: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x70sshd 29204 [002] 83980.229020: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83980.229094: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.232982: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83980.233220: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.236385: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.236677: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.241734: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83981.244477: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [002] 83981.246985: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83981.247241: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.251093: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83981.251360: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.254500: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.254828: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.259723: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83982.262445: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [002] 83982.264933: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83982.265127: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.268984: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83982.269206: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.272402: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.272704: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30
还可以在内核过滤中使用–filter,以仅匹配所需的数据。
三、uprobes的使用
uprobes(用户空间探测器)与kprobes类似,但适用于用户空间。它们可以动态地插入应用程序和库中的函数,并提供一个不稳定的API,用于深入其他工具范围之外的软件内部。uprobes在2012年发布的Linux3.5中提供。
3.1 perf uprobe 的使用
在使用 perf 时,uprobes的创建与kprobes类似。例如,要为libc文件打开函数创建uprobe,fopen:
# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add fopen
Added new event:probe_libc:fopen (on fopen in /lib/x86_64-linux-gnu/libc-2.27.so)
二进制路径使用-x指定。uprobe名为probe_libc:fopen,现在可以与perf record一起使用来记录事件。
完成uprobe后,可以使用–del:
# perf probe --del probe_libc:fopen
Removed event: probe_libc:fopen
可以通过添加%return来检测函数的返回:
# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add fopen%return
使用uretpobe。
3.2 uprobe Arguments
如果您的系统具有目标二进制文件的debuginfo,则变量信息(包括参数)可能可用。这可以使用–vars列出:
# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --vars fopen
Available variables at fopen@<_IO_vfscanf+15344>char* filenamechar* mode
输出显示fopen具有 filename 和 mode 变量。创建探针时可以添加以下内容:
perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add 'fopen filename mode'
Debuginfo可以通过-dbg或-dbgsym包提供。如果这在目标系统上不可用,但在另一个系统上,则其他系统可以用作参考系统,如前一节kprobes中所示。
参考资料
https://www.brendangregg.com/perf.html
相关文章:
Linux perf probe 的使用(三)
文章目录前言一、Dynamic Tracing二、kprobes2.1 perf kprobe 的使用2.2 kprobe Arguments3.3 tcp_sendmsg()3.3.1 Kernel: tcp_sendmsg()3.3.2 Kernel: tcp_sendmsg() with size3.3.2 Kernel: tcp_sendmsg() line number and local variable三、uprobes的使用3.1 perf uprobe …...
python GUI编程 多窗口跳转
# 多窗口跳转例子from tkinter import *def main(): # 主窗体def goto(num):root.destroy() # 关闭主窗体if num 1:one() # 进入第1个窗体elif num 2:two() # 进入第2个窗体root Tk()root.geometry(300x150600200)root.title(登录窗口)but1 Button(root, text"进入…...
nuxt 学习笔记
这里写目录标题路由跳转NuxtLinkquery参数params参数嵌套路由tab切换效果layouts 文件夹强制约定放置所有布局文件,并以插槽的形式作用在页面中1.在app.vue里面2.component 组件使用Vue < component :is"">Vuex生命周期数据请求useFetchuseAsyncDat…...
Python编程自动化办公案例(1)
作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.使用库讲解 1.xlrd 2.xlwt 二.主要案例 1.批量合并 模板如下…...
一站式 Elasticsearch 集群指标监控与运维管控平台
上篇文章写了一下消息运维管理平台,今天带来的是ES的监控和运维平台。目前初创企业,不像大型互联网公司,可以重复的造轮子。前期还是快速迭代试错阶段,方便拿到市场反馈,及时调整自己的战略和产品方向。让自己活下去&a…...
C# 调用Python
一、简介 IronPython 是一种在 NET 和 Mono 上实现的 Python 语言,由 Jim Hugunin(同时也是 Jython 创造者)所创造。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python是…...
51单片机最强模块化封装(3)
文章目录 前言一、创建smg文件,添加smg文件路径二、smg文件编写三、模块化测试总结前言 本篇文章将带大家继续封装我们的代码。 这里我们会封装数码管的操作函数。 一、创建smg文件,添加smg文件路径 这里的操作就不过多解释了,大家自行看前面的文章即可。 51单片机模块化…...
【CSS 布局】水平垂直居中
CSS 布局-水平垂直居中 一、水平居中 创建一个父盒子,和子盒子 <div class"parent"><div class"child"></div> </div>基本样式如下 .parent {background-color: #fff; }.child {background-color: #999;width: 100p…...
【C++】类和对象--类的6个默认成员函数
目录1.类的6个默认成员函数2.构造函数2.1概念2.2特性3.析构函数3.1概念3.2特性4.拷贝构造函数4.1概念4.2特征5.赋值运算符重载5.1运算符重载5.2赋值运算符重载5.3前置和后置重载5.4流插入和流提取运算符重载6.const成员7.取地址重载和const取地址操作符重载1.类的6个默认成员函…...
常见面试题---------如何处理MQ消息丢失的问题?
如何处理MQ消息丢失的问题? RabbitMQ丢失消息分为如下几种情况: 生产者丢消息: 生产者将数据发送到RabbitMQ的时候,可能在传输过程中因为网络等问题而将数据弄丢了。 RabbitMQ自己丢消息: 如果没有开启RabbitMQ的持久化&#x…...
十四、Linux网络:高级IO
目录 五种IO模型 同步IO 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO...
带你走进API安全的知识海洋
Part1什么是API API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访…...
【Java】TCP的三次握手和四次挥手
三次握手 TCP三次握手是一个经典的面试题,它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接,并进行数据传递。(客户端主动发起的)TCP之所以需要三次握手是因为TCP双方都是全双工的。 什么是全双工? TCP任何…...
JUC并发编程
1.什么是JUC java.util工具包、包、分类 业务:普通业务线程代码 Thread Runable: 没有返回值、效率相比Callable相对较低。 2.线程和进程 进程:一个程序,QQ.exe Music.exe 程序的集合 一个进程往往可以包含多个线程,至少包含一个…...
概率统计·假设检验【正态总体均值的假设检验、正态总体方差的假设检验】
均值假设检验定义 2类错误 第1类错误(弃真):当原假设H0为真,观察值却落入拒绝域,因而拒 绝H0这类错误是“以真为假” 犯第一类错误的概率显著性水平α第2类错误(取伪):当原假设H0不…...
如何预测机组设备健康状态?你可能需要这套解决方案
1. 应用场景随机振动[注1]会发生在工业物联网的各个场景中,包括产线机组设备的运行、运输设备的移动、试验仪器的运行等等。通过分析采集到的振动信号可以预估设备的疲劳年限、及时知晓设备已发生的异常以及预测未来仪器可能发生的异常等等。本篇教程会提供给有该方…...
C++类和对象:面向对象编程的核心。| 面向对象还编什么程啊,活该你是单身狗。
👑专栏内容:C学习笔记⛪个人主页:子夜的星的主页💕座右铭:日拱一卒,功不唐捐 文章目录一、前言二、面向对象编程三、类和对象1、类的引入2、类的定义Ⅰ、声明和定义在一起Ⅱ、声明和定义分开Ⅲ、成员变量命…...
CUDA虚拟内存管理
CUDA中的虚拟内存管理 文章目录CUDA中的虚拟内存管理1. Introduction2. Query for support3. Allocating Physical Memory3.1. Shareable Memory Allocations3.2. Memory Type3.2.1. Compressible Memory4. Reserving a Virtual Address Range5. Virtual Aliasing Support6. Ma…...
线程池小结
什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象; 为什么使用线程池 …...
vue3状态管理模式 Pinia
状态管理库 Pinia是Vue的专属状态管理库,它允许你跨组件或页面共享状态 1:安装与使用pinia 1.1 安装语法:npm install pinia1.2 创建一个pinia(根存储)并将其传递给应用程序 import { createApp } from vue import…...
python基于django的自媒体社区交流平台
自媒体社区平台采用python技术,基于django框架,mysql数据库进行开发,实现了以下功能: 本系统主要包括管理员,用户,商家和普通管理员四个角色组成,主要包括以下功能: 1;前台:首页、需求通告、优质案例、帮助中心、意见反馈、个人中心、后台管理…...
Python中类和对象(2)
1.继承 Python 的类是支持继承的:它可以使用现有类的所有功能,并在无需重新编写代码的情况下对这些功能进行扩展。 通过继承创建的新类称为 “子类”,被继承的类称为 “父类”、“基类” 或 “超类”。 继承语法是将父类写在子类类名后面的…...
SpringMvc入门
Spring与Web环境的集成 1.ApplicationContext应用上下文的获取方式 分析 之前获取应用上下文对象每次都是从容器中获取,编写时都需要new ClasspathXmlApplicationContext(Spring配置文件),这样的弊端就是配置加载多次应用上下文就创建多次。 在Web项目…...
设计模式之单例模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、单例模式是什么? 单例模式是一种创建型的软件设计模式,在工程项目中非常常见。通过单例模式的设计&am…...
贪心算法(基础)
目录 一、什么是贪心? (一)以教室调度问题为例 1. 问题 2. 具体做法如下 3. 因此将在这间教室上如下三堂课 4. 结论 (二)贪心算法介绍 1. 贪心算法一般解题步骤 二、最优装载问题 (一…...
【九宫格坐标排列 Objective-C语言】
一、这个案例做好之后的效果如图: 1.这个下载是可以点击的,当你点击之后,弹出一个框,过一会儿,框框自动消失,这里变成“已安装” 2.那么,我现在先问大家一句话:大家认为在这一个应用里面,它包含几个控件, 3个,哪3个:一个是图片框,一个是Label,一个是按钮, 这…...
Tomcat简介
目录 一、Tomcat简介 二、下载安装Tomcat 三、利用Tomcat部署静态页面 一、Tomcat简介 Tomcat是一个HTTP服务器,可以按照HTTP的格式来解析请求来调用用户指定的相关代码然后按照HTTP的格式来构造返回数据。 二、下载安装Tomcat 进入Tomcat官网选择与自己电脑…...
Python基础及函数解读(深度学习)
一、语句1.加注释单行注释:(1)在代码上面加注释: # 后面跟一个空格(2)在代码后面加注释:和代码相距两个空格, # 后面再跟一个空格多行注释:按住shift 点击三次"&am…...
车道线检测-PolyLaneNet 论文学习笔记
论文:《PolyLaneNet: Lane Estimation via Deep Polynomial Regression》代码:https://github.com/lucastabelini/PolyLaneNet地址:https://arxiv.org/pdf/2004.10924.pdf参考:https://blog.csdn.net/sinat_17456165/article/deta…...
GO——接口(下)
接口接口值警告:一个包含空指针值的接口不是nil接口sort.Interface接口http.Handler接口类型断言类型分支接口值 接口值,由两个部分组成,一个具体的类型和那个类型的值。它们被称为接口的动态类型和动态值。对于像Go语言这种静态类型的语言&…...
常州网站推广/北京网站开发
动态树问题。 维护一个森林,支持树上动态查询、修改、删边、加边、换根等等,但始终保持是一颗树。 我学的主要是路径查询和修改。貌似路径和子树不能兼顾…但有一个很厉害的数据结构叫Top Tree,能同时兼顾,听起来好厉害…...
企业内部系统网站制作/常州网站建设优化
計算机组成原理FPGA实验指导书《计算机组成原理》实验指导书计算机科学与技术学院目录实验一 熟悉实验平台……………………………………………………………………(3)实验二 总线传送…………………………………………………………………………(10)实验三 运算器的设计与调试……...
wordpress双语站/安徽疫情最新情况
一、原理 Levoy在1988年提出了光线投射(ray-casting)算法[1],其基本原理是:从屏幕上每一个像素点出发,沿着视线方向发射出一条光线,当这条光线穿过体数据时,沿着光线方向等距离采样,…...
日本一级a做爰片免费网站/山东移动网站建设
模糊搜索表:show tables like *name*; 查看表结构:desc table_name查看表的详细信息:desc formatted table_name 查看分区信息:show partitions table_name;根据分区查询数据:select table_coulm from table_name wher…...
平面ui设计是学什么/热狗网站关键词优化
Axure RP Pro - 相关问题 - 如何获取IFrame的URLAxure RP Pro中支持IFrame部件,在IFrame中可以载入一个页面或指定的URL,但是并不能获取这个URL进行判断,此时可以借助于jQuery实现,示例代码如下:var customization_fou…...
wordpress福利/seo简单优化操作步骤
■ 定义 background-image属性用于定义元素的背景图像 ■ 使用说明 语法: background-image: none | url(图片链接的url)属性值: none:无背景图片(默认的) url:使用绝对或相对地址指定背景图像 实际开发常见于logo或者一些装饰性的…...