[EBPF] 实时捕获DM数据库是否存在SQL阻塞

1. 介绍

eBPF(extened Berkeley Packet Filter)是一种内核技术,它允许开发人员在不修改内核代码的情况下运行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由贝尔实验室开发的一种网络过滤器,可以捕获和过滤网络数据包。

eBPF 可以在不侵入任何业务代码的基础上实现应用的可观测性。但是 eBPF 对 Linux 内核版本是有一定要求的(4.14 以上)。

2. 工作原理

eBPF 的工作原理主要分为三个步骤:加载、编译和执行。

eBPF 需要在内核中运行。这通常是由用户态的应用程序完成的,它会通过系统调用来加载 eBPF 程序。在加载过程中,内核会将 eBPF 程序的代码复制到内核空间。

eBPF 程序需要经过编译和执行。这通常是由Clang/LLVM的编译器完成,然后形成字节码后,将用户态的字节码装载进内核,并通过一个JIT编译步骤将程序的通用字节码转换为机器特定指令集,以优化程序的执行速度。

在内核中运行时,eBPF 程序通常会挂载到一个内核钩子(hook)上,以便在特定的事件发生时被执行。例如,可以将 eBPF 程序挂载到网络协议栈的某个位置,以便在收到网络数据包时被执行。

最后,eBPF 程序还需要经过内核安全机制的检查。这是为了确保 eBPF 程序不会破坏内核的稳定性和安全性。在检查过程中,内核会对 eBPF 程序的代码进行分析,以确保它不会进行恶意操作,如系统调用、内存访问等。如果 eBPF 程序通过了内核安全机制的检查,它就可以在内核中正常运行了。在运行过程中,eBPF 程序可以访问内核的数据结构,并通过内核接口与其他组件进行交互。例如,eBPF 程序可以捕获网络数据包,并通过内核接口将它们转发给用户态的应用程序。总之,eBPF 的工作原理是通过动态加载、执行和检查无损编译过的代码来实现的。

3.环境介绍

名称版本
linux版本(centos8.5)4.18.0-348.el8.x86_64
DM88.1.4.27
pythonPython 3.6.8

4.安装环境

4.1检查环境

CONFIG_DEBUG_INFO_BTF=y必须项,否则就是操作系统不支持

[root@localhost opt]# uname -r
4.18.0-348.el8.x86_64
[root@localhost opt]# cat /boot/config-`uname -r` | grep CONFIG_DEBUG_INFO_BTF
CONFIG_DEBUG_INFO_BTF=y

4.2安装依赖包

[root@localhost opt]# dnf install -y bison cmake ethtool flex git iperf3 libstdc++-devel python3-netaddr python3-pip gcc gcc-c++ make zlib-devel elfutils-libelf-devel
[root@localhost opt]# dnf install -y clang clang-devel llvm llvm-devel llvm-static ncurses-devel
[root@localhost opt]# dnf -y install netperf
[root@localhost opt]# pip3 install pyroute2
[root@localhost opt]# ln -s /usr/bin/python3 /usr/bin/python

4.3安装并编译bcc

[root@localhost opt]# git clone https://github.com/iovisor/bcc.git
[root@localhost opt]# mkdir bcc-build
[root@localhost opt]# cd bcc-build/
[root@localhost opt]# cmake ../bcc -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LLVM_SHARED=1
[root@localhost opt]# make -j10
[root@localhost opt]# make install 

4.4添加环境变量

安装后,可以将 bcc 目录添加到$PATH,可以将其添加到 ~/.bashrc

[root@localhost opt]# vim ~/.bashrc
bcctools=/usr/share/bcc/tools
export PATH=$bcctools:$PATH
[root@localhost opt]# source ~/.bashrc

4.5安装DM并初始化实例

此步骤忽略

5.思路

5.1模拟阻塞场景

建表sql

create table lock_test01(id int primary key, name varchar(20));
create table lock_test02(id int primary key, name varchar(20));

insert into lock_test01(id, name) values(1, '1cheng');
insert into lock_test01(id, name) values(2, '1gao');

insert into lock_test02(id, name) values(1, '2cheng');
insert into lock_test02(id, name) values(2, '2gao');

阻塞场景

-- Session A 执行insert 不提交
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '3zzzz');
-- Session B 执行insert  会发生阻塞
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '4zzzz');

5.2判断堆栈中的核心函数

下面的堆栈是阻塞SQL的线程堆栈

Thread 127 (Thread 0x7fb29dfeb700 (LWP 19089)):
#0  0x00007fb64d8a77e8 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x0000000000752f72 in os_event2_wait_timeout (event=event@entry=0x7fb6315e1fb0, s_time=s_time@entry=30) at /home/dmops/build/svns/1725521374498/os/osevent2.c:303
#2  0x0000000001e571cb in uevent_wait_timeout (env=env@entry=0x7fb29dfe6020, event=event@entry=0x7fb6315e1fa8, s_time=s_time@entry=30) at /home/dmops/build/svns/1725521374498/knl/uevent.c:111
#3  0x0000000000ccc186 in trx4_waiting_timeout (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, w_time=w_time@entry=3) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14642
#4  0x0000000000ccc32a in trx4_waiting_interval (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, s_time=s_time@entry=0) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14217
#5  0x0000000000cd69e4 in trx4_waiting (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, s_time=s_time@entry=0) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14383
#6  0x00000000018446f0 in nins2_check_second_unique (memobj=memobj@entry=0x7fb2e000d3b8, trx=trx@entry=0x7fb6315e0898, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, bcur=bcur@entry=0x7fb29dfdce90, key=key@entry=0x7fb34c417a60, desc=desc@entry=0x7fb2ee14c098, tableid=tableid@entry=1017, search_mode=search_mode@entry=2, need_lock_row=need_lock_row@entry=1, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, pll_index_fill=pll_index_fill@entry=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:8616
#7  0x0000000001847789 in nins2_second_unique_search_and_check (memobj=memobj@entry=0x7fb2e000d3b8, trx=trx@entry=0x7fb6315e0898, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, table=table@entry=0x7fb2ee14aae8, key=key@entry=0x7fb34c417a60, need_lock_row=need_lock_row@entry=1, search_mode=search_mode@entry=2, desc=desc@entry=0x7fb2ee14c098, rec_len=19, rowid=rowid@entry=4, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=pll_index_fill@entry=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10126
#8  0x0000000001848fd9 in nins2_second_unique_insert_low (memobj=memobj@entry=0x7fb2e000d3b8, trx=0x7fb6315e0898, ptx=0x7fb29dfdd2c0, pbc=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, table=0x7fb2ee14aae8, tuple=tuple@entry=0x7fb34c417998, key=key@entry=0x7fb34c417a60, need_lock_row=need_lock_row@entry=1, search_mode=search_mode@entry=2, n_rol_len_fixed_part=n_rol_len_fixed_part@entry=45, rowid=rowid@entry=4, with_trxid=with_trxid@entry=0, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=pll_index_fill@entry=0, org_trx_id_out=org_trx_id_out@entry=0x0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10222
#9  0x00000000018492c5 in nins2_second_unique_insert (memobj=memobj@entry=0x7fb2e000d3b8, trx=<optimized out>, ptx=<optimized out>, pbc=<optimized out>, index=index@entry=0x7fb2ee14bd70, table=<optimized out>, tuple=0x7fb34c417998, key=0x7fb34c417a60, need_lock_row=1, search_mode=2, n_rol_len_fixed_part=45, rowid=4, ign_cflt=0, cflt_rowid=0x0, need_modify=0x7fb29dfdfb6c, bcur=0x7fb29dfdce90, pll_index_fill=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10267
#10 0x0000000001849a39 in nins2_index_insert_entry_low (memobj=memobj@entry=0x7fb2e000d3b8, trx=<optimized out>, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, tuple=tuple@entry=0x7fb34c417998, key=0x7fb34c417998, key@entry=0x7fb34c417a60, need_lock_row=1279359584, need_lock_row@entry=1, search_mode=1, search_mode@entry=2, n_rol_len_fixed_part=2, n_rol_len_fixed_part@entry=45, rowid=0x7fb20000002d, rowid@entry=0x7fb29dfdff50, ign_cflt=4, ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=0x0, need_modify@entry=0x7fb29dfdfb6c, table=0x7fb29dfdfb6c, table@entry=0x7fb2ee14aae8, with_rowid=2650656400, with_rowid@entry=0, vm_node=0x7fb300000000, vm_node@entry=0x7fb34c416fd0, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10508
#11 0x000000000185c1f8 in nins2_index_insert_entry (env=0x7fb29dfe6020, memobj=0x7fb2e000d3b8, vm=vm@entry=0x7fb2e000d350, index=index@entry=0x7fb2ee14bd70, tuple=0x7fb34c417998, key=key@entry=0x7fb34c417a60, need_lock_low=1, n_rol_len_fixed_part=45, rowid=rowid@entry=0x7fb29dfdff50, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, table=0x7fb2ee14aae8, with_rowid=0, vm_node=vm_node@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:11889
#12 0x000000000185ceea in nins2_exec_insert_low (nins2_vm=nins2_vm@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:12796
#13 0x000000000185da5f in nins2_exec_insert (nins2_vm=nins2_vm@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:13492
#14 0x000000000186077f in nins2_exec (nins2_vm=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:18904
#15 0x000000000195eab8 in vm_run_low (vm=vm@entry=0x7fb2e000d350) at /home/dmops/build/svns/1725521374498/op/vm.c:6115
#16 0x000000000195ef30 in vm_run (vm=vm@entry=0x7fb2e000d350) at /home/dmops/build/svns/1725521374498/op/vm.c:6196
#17 0x000000000195f080 in vm_run_pln_low (env=env@entry=0x7fb29dfe6020, stmt=stmt@entry=0x7fb2e000c8f0, pln=pln@entry=0x7fb2ee138ac8, ret_ident_flag=ret_ident_flag@entry=0 '\000', n_ret_col=n_ret_col@entry=0, ret_col_ident=ret_col_ident@entry=0x0, err_desc=err_desc@entry=0x0) at /home/dmops/build/svns/1725521374498/op/vm.c:11602
#18 0x0000000001fae1d0 in ntsk_process_exec_low (env=env@entry=0x7fb29dfe6020, stmt=0x7fb2e000c8f0, pln=pln@entry=0x7fb2ee138ac8, ret_ident_flag=ret_ident_flag@entry=0 '\000', n_ret_col=<optimized out>, ret_col_ident=0x0, dlck_reprepare=dlck_reprepare@entry=0x7fb29dfe46bc) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:12603
#19 0x0000000001fb2256 in ntsk_process_prepare_and_exec (env=env@entry=0x7fb29dfe6020, sess=sess@entry=0x7fb2e00110f0, msg_in=msg_in@entry=0x7fb2e00029a8 "", stmtsql_out=stmtsql_out@entry=0x7fb29dfe57c8) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:13063
#20 0x0000000001fde785 in ntsk_process_cop (env=0x7fb29dfe6020, task=<optimized out>) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:21389
#21 0x0000000001e5b755 in uthr_db_main_for_sess (sess2=0x7fb2e00110f0) at /home/dmops/build/svns/1725521374498/knl/uthr.c:1367
#22 0x00007fb64d8a117a in start_thread () from /lib64/libpthread.so.0
#23 0x00007fb64ccb5dc3 in clone () from /lib64/libc.so.6
  1. 头部 pthread_cond_timedwait 和 uevent_wait_timeout 都是自定义函数,而不是标准库提供的系统函数。

2) os_event2_wait_timeout:这是一个封装函数,它调用 pthread_cond_timedwait 并接受一个事件和超时时间(30秒)。

  1. uevent_wait_timeout:这个函数在内核中用于等待 uevent 事件,传入的参数包括环境指针和事件指针,以及超时时间。

  2. trx4_waiting_timeout:这个函数可能是一个事务相关的等待函数,传入了环境、事务和等待时间(3秒)

根据函数命名以及堆栈的含义,pthread_cond_timedwait 和 uevent_wait_timeout 肯定是代码底层的通用函数,所以初步判断SQL阻塞使用 trx4_waiting_timeout 函数就可以 我们此时进行测试。

6.编写代码

[root@localhost opt]# vim ebpf_trx.py

from bcc import BPF
  
# 定义 eBPF 程序
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
#include <linux/timekeeping.h>

BPF_HASH(start_time, u64);

// 处理 uprobe 事件
int trace_ntsk_process_cop(struct pt_regs *ctx) {
    u64 pid_tgid = bpf_get_current_pid_tgid(); // 获取 PID 和 TGID
    u64 thread_id = pid_tgid >> 32; // 获取线程号
    u64 timestamp = bpf_ktime_get_ns();

    // 记录开始时间
    start_time.update(&pid_tgid, &timestamp);
    bpf_trace_printk("ntsk_process_cop called: pid=%d, thread_id=%d, timestamp=%llu", pid_tgid & 0xFFFFFFFF, thread_id, timestamp);
    return 0;
}

// 处理返回事件
int trace_ret_ntsk_process_cop(struct pt_regs *ctx) {
    u64 pid_tgid = bpf_get_current_pid_tgid(); // 获取 PID 和 TGID
    u64 thread_id = pid_tgid >> 32; // 获取线程号
    u64 *start_ts = start_time.lookup(&pid_tgid);

    if (start_ts != 0) {
        u64 end_time = bpf_ktime_get_ns();
        u64 total_time = end_time - *start_ts;
        u64 total_time_ms = total_time / 1000000;
        bpf_trace_printk("ntsk_process_cop exited: pid=%d, thread_id=%d, total_time=%llu ms", pid_tgid & 0xFFFFFFFF, thread_id, total_time_ms);
        start_time.delete(&pid_tgid);
    }
    return 0;
}
"""

# 加载 eBPF 程序
b = BPF(text=bpf_text)

# 设置 uprobe
b.attach_uprobe(name="/opt/dmdbms/bin/dmserver", sym="trx4_waiting_timeout", fn_name="trace_ntsk_process_cop")
b.attach_uretprobe(name="/opt/dmdbms/bin/dmserver", sym="trx4_waiting_timeout", fn_name="trace_ret_ntsk_process_cop")

# 输出跟踪信息
print("正在跟踪 uprobe... 按 Ctrl-C 结束。")

# 输出追踪信息
b.trace_print()

代码解释

  • BPF_HASH(start_time, u64); 创建一个哈希表 start_time,键类型为 u64,用于存储每个进程的开始时间。它通过 PID(进程标识符)来索引
  • bpf_get_current_pid_tgid(): 获取当前进程的 PID 和线程 ID
  • attach_uprobe ()表示将钩子附加到dmserver的trx4_waiting_timeout函数的头部位置
  • attach_uretprobe()表示将钩子附加到dmserver的trx4_waiting_timeout函数的结尾位置
  • 在函数开始的时候存储开始时间在函数结尾时相减就是执行该函数的耗时,并输出PID 以及 threadID即可。

7.验证代码

[root@localhost opt]# python ebpf_trx.py 

验证结果说明

  • 运行程序以后,会发现只有当SQL阻塞的时候才会输出信息(进程号、线程号、函数的执行耗时) 说明对trx4_waiting_timeout函数添加钩子是没有问题
  • 运行时会发现每隔3S输出一次,添加符号文件的堆栈可以看到trx4_waiting_timeout函数的w_time=3,这块可以一一对应。
  • 有了这些信息就能够做很多事情,比如说将信息推送到监控平台等。

8.总结与思考

  1. 利用ebpf技术在不登录数据库的情况下,通过对数据库的函数添加钩子,实时的对数据库是否存在阻塞判断
  2. 现有的监控逻辑都是新建数据库用户执行SQL语句来判断阻塞情况,告警的实时性取决于监控的周期频率,而使用ebpf技术能够解决这个痛点
  3. ebpf有多种实现方式,这里便于理解测试的话 使用python语言内置c语言的形式进行了说明。涉及到生产环境应该是使用go语言或者c语言去做能够有效避免源码泄露等问题
  4. 如给sql线程添加钩子,有代sql变量的偏移量的话,就能够不登录数据库的情况下捕获到慢SQL,就能够有效的解决很多问题了,有待探究

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何选择数据库架构

选择合适的数据库架构是一个复杂的过程&#xff0c;它取决于多种因素&#xff0c;包括应用程序的需求、数据量的大小、并发访问量、数据一致性要求、预算以及技术团队的熟悉程度等。以下是一些关键的步骤和考虑因素&#xff0c;帮助你选择合适的数据库架构&#xff1a; 1. 分析…

JavaScript对象方法

对象方法 已经讨论过hasOwnProperty(),propertyIsEnumerable()和isPrototypeOf()三个方法。 以及静态函数&#xff0c;Object.create(),Object.getPrototypeOf()等。 toString()方法 无参数&#xff0c;返回一个表示调用这个方法的对象值的字符串。默认返回信息很少&#x…

基因组学的未来:DAP-seq技术如何塑造

在生物科学的探索之旅中&#xff0c;我们一直在寻找更高效、更精确的方法来揭示基因的秘密。今天&#xff0c;我们自豪地介绍一种革命性的技术——DAP-Seq&#xff0c;它正在改变我们对基因表达调控的理解。 什么是DAP-Seq&#xff1f; DAP-Seq&#xff0c;即DNA亲和纯化测序技…

DataWhale x南瓜书学习笔记 task04笔记

线性判别分析&#xff08;LDA&#xff09; 前提假设&#xff1a;各类样本的协方差矩阵相同且满秩LDA的思想&#xff1a;1.设法让训练样例集投影到一条直线上&#xff0c;2.同类样例的投影点尽可能接近&#xff0c;异类样例的投影点尽可能远离&#xff0c;3.在对新样本进行分类时…

C++语法—引用

引用变量 概念 简单理解就是对一个已存在的变量起别名&#xff0c;与那个已存在的变量共用一块内存空间。 用法&#xff1a;已存在变量的类型 & 引用变量名 &#xff08;引用实体&#xff09;已存在变量 int main() {int a 1;int& b a;return 0; }在上面这个示例…

Lab1:虚拟机kolla安装部署openstack,并创建实例

实验内容&#xff1a; 创建并配置虚拟机安装OpenStack创建镜像创建实例类型选择网络配置创建实例 1、选择一个适合你的系统的虚拟机管理软件&#xff1a; VirtualBox &#xff08;推荐&#xff09; VMWare 其他 2、下载 .iso 镜像文件 openstack S 版本 iso 链接&#xff1…

计算机视觉实战项目4(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)

往期热门项目回顾&#xff1a; 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 AI健身教练-引体向上-俯卧撑计数…

网站设计中安全方面都需要有哪些考虑

网站设计中的安全性是一个多方面的问题&#xff0c;需要从多个角度进行考虑和实施。以下是一些关键的安全考虑因素&#xff1a; 数据加密&#xff1a; 使用SSL&#xff08;安全套接字层&#xff09;证书来建立加密连接&#xff0c;确保数据在传输过程中不被截获。定期更新SSL证…

保障电气安全的电气火灾监控系统主要组成有哪些?

电气火灾是什么&#xff1f; 电气火灾一般是指由于电气线路、用电设备、器具以及供配电设备出现故障性释放的热能&#xff1a;如高温、电弧、电火花以及非故障性释放的能量&#xff1b;如电热器具的炽热表面&#xff0c;在具备燃烧条件下引燃本体或其他可燃物而造成的火灾&…

动态规划入门题目->使用最小费用爬楼梯

1.题目&#xff1a; 2.解析&#xff1a; 做题模式&#xff1a; 步骤一&#xff1a;找状态转移方程 步骤二&#xff1a;初始化 步三&#xff1a;填表 步骤四&#xff1a;返回-> dp[n] dp[i]表示到达 i 位置最小花费 逻辑&#xff1a;要爬到楼顶先找到 i 位置 &#xff0c; 要…

如何在谷歌浏览器上玩大型多人在线游戏

在如今的数字时代&#xff0c;谷歌浏览器已经成为了许多人上网冲浪的首选工具。除了浏览网页、观看视频之外&#xff0c;你还可以在谷歌浏览器上畅玩各种大型多人在线游戏。本文将为你详细介绍如何在谷歌浏览器上玩大型多人在线游戏的步骤。 &#xff08;本文由https://chrome…

PTH原理 补丁+工具

顺着《域渗透攻防指南》4.9的总结记录下。 0x00 PTH简单说明 PTH在内网渗透中用于横向移动。由于NTLM && Kerberos都是采用用户密码的NTLM Hash&#xff0c;所以我们不需要非得拿用户明文口令&#xff0c;拿到hash一样可以。 拿到hash后&#xff0c;可以撞hash&…

【深度学习】03-神经网络01-4 神经网络的pytorch搭建和参数计算

# 计算模型参数,查看模型结构,我们要查看有多少参数&#xff0c;需要先安装包 pip install torchsummary import torch import torch.nn as nn from torchsummary import summary # 导入 summary 函数&#xff0c;用于计算模型参数和查看模型结构# 创建神经网络模型类 class Mo…

nginx+php+postgresql搭建漏洞靶场

经过我多番查找,最终得出一个结论,dvwa暂时不支持 postgresql 本文给大家提供一个思路,千万不要轻易模仿 更新系统包列表 首先,打开终端并更新你的系统包列表: sudo apt updatesudo apt upgrade -y安装必要的软件包 安装Nginx、PHP、PostgreSQL以及一些必要的PHP扩展:…

基于BeagleBone Black的网页LED控制功能(flask+gpiod)

目录 项目介绍硬件介绍项目设计开发环境功能实现控制LED外设构建Webserver 功能展示项目总结 &#x1f449; 【Funpack3-5】基于BeagleBone Black的网页LED控制功能 &#x1f449; Github: EmbeddedCamerata/BBB_led_flask_web_control 项目介绍 基于 BeagleBoard Black 开发板…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(四)-搜索

搜索 搜索内容比较多&#xff0c;onesearch分成两部分&#xff0c;第一部分&#xff0c;Query构建&#xff0c;其中包括搜索词设置&#xff0c;设置返回字段&#xff0c;filter&#xff0c;高亮&#xff1b;第二部分分页和排序。第一部分是映射引擎负责&#xff0c;映射通用表…

HAL+M4学习记录_2

一、Boot配置 内存地址是固定的&#xff0c;代码从0x0000 0000开始&#xff0c;而数据从0x2000 0000开始&#xff0c;F4支持三种不同的boot模式 复位芯片时&#xff0c;在SYSCLK的第4个上升沿BOOT引脚值被锁存&#xff0c;STM32F407通过此时BOOT[1:0]引脚值选择Boot模式 BOOT1…

深度学习(入门)03:监督学习

1、监督学习简介 监督学习&#xff08;Supervised Learning&#xff09;是一种重要的机器学习方法&#xff0c;它的目标是通过“已知输入特征”来预测对应的标签。在监督学习中&#xff0c;每一个“特征-标签”对被称为样本&#xff08;example&#xff09;&#xff0c;这些样…

物联网行业中模组的AT指令详解以及使用

01 概述 AT 命令&#xff08;AT Commands&#xff09;最早是由发明拨号调制解调器&#xff08;MODEM&#xff09;的贺氏公司&#xff08;Hayes&#xff09;为了控制 MODEM 而发明的控制协议。后来随着网络带宽的升级&#xff0c;速度很低的拨号 MODEM 基本退出一般使用市场&am…

【含文档】基于Springboot+Vue的高校师资管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…