当前位置: 首页 > news >正文

eBPF BCC开源工具简介

目录

官方链接

编译安装

ubuntu版本

安装

examples

tools

hello_world.py demo

运行报错

网上目前的解决办法

错误分析过程

python版本检测

libbcc库检查

python3 bcc库检查

正常输出

监控进程切换

运行输出

监控CPU直方图

缓存命中率监控:cachestat

cachetop

BCC开发指南


官方链接

主页:https://github.com/iovisor/bcc

bcc开发:https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md

编译安装

ubuntu版本

wj@wj:~$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

安装

git clone https://github.com/iovisor/bcc.git
mkdir bcc/build; cd bcc/build
cmake ..
make
sudo make install
cmake -DPYTHON_CMD=python3 .. # build python3 binding
pushd src/python/
make
sudo make install
popd安装路径:
/usr/share/bcc/tools

可以看到 /usr/share/bcc 目录下,有4个文件夹,examples  introspection  man  tools 。

在examples 文件下,有一些简单的demo。tools文件下有 bcc的各种工具。

examples

 

tools

hello_world.py demo

#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")# run in project examples directory with:
# sudo ./hello_world.py"
# see trace_fields.py for a longer examplefrom bcc import BPF# This may not work for 4.17 on x64, you need replace kprobe__sys_clone with kprobe____x64_sys_clone
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()

上述 hello_world.py程序中会监测 kprobe__sys_clone 事件,一旦内核监测到 kprobe__sys_clone 事件产生,就会打印 Hello, World! 出来。

运行报错

wj@wj:/usr/share/bcc/examples$ sudo python3 hello_world.py 
Traceback (most recent call last):File "/usr/share/bcc/examples/hello_world.py", line 9, in <module>from bcc import BPFFile "/usr/lib/python3/dist-packages/bcc/__init__.py", line 27, in <module>from .libbcc import lib, bcc_symbol, bcc_symbol_option, bcc_stacktrace_build_id, _SYM_CB_TYPEFile "/usr/lib/python3/dist-packages/bcc/libbcc.py", line 20, in <module>lib.bpf_module_create_b.restype = ct.c_void_pFile "/usr/lib/python3.10/ctypes/__init__.py", line 387, in __getattr__func = self.__getitem__(name)File "/usr/lib/python3.10/ctypes/__init__.py", line 392, in __getitem__func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b

网上目前的解决办法

主要还是python版本问题,将python2切换为python3。而我这边显然不是这个问题,因为我的机子上只有python3

错误分析过程

根据报错信息,和报错相关的路径:

/lib/x86_64-linux-gnu/libbcc.so.0 :bcc库采用的libbcc.so.0

/usr/lib/python3/dist-packages/bcc :报错的bcc库

python版本检测

使用的均为python3,没有python2,所以不存在版本问题。

libbcc库检查

wj@wj:/usr/share/bcc/examples$ ls -lh /lib/x86_64-linux-gnu/ |grep libbcc
-rw-r--r--  1 root root  5.0M 11月  5 14:48 libbcc.a
-rw-r--r--  1 root root  1.5M 11月  5 14:46 libbcc_bpf.a
lrwxrwxrwx  1 root root    15  1月 19  2021 libbcc_bpf.so -> libbcc_bpf.so.0
lrwxrwxrwx  1 root root    20 11月  5 14:54 libbcc_bpf.so.0 -> libbcc_bpf.so.0.28.0
-rw-r--r--  1 root root   51K  1月 19  2021 libbcc_bpf.so.0.18.0
-rw-r--r--  1 root root  2.8M 11月  5 14:48 libbcc_bpf.so.0.28.0
-rw-r--r--  1 root root  243K 11月  5 14:47 libbcc-loader-static.a
lrwxrwxrwx  1 root root    11  1月 19  2021 libbcc.so -> libbcc.so.0
lrwxrwxrwx  1 root root    16 11月  5 14:54 libbcc.so.0 -> libbcc.so.0.28.0
-rw-r--r--  1 root root  3.3M  1月 19  2021 libbcc.so.0.18.0
-rw-r--r--  1 root root  105M 11月  5 14:47 libbcc.so.0.28.0

可以看到libbcc库的实际指向为: libbcc.so.0 -> libbcc.so.0.28.0

根据报错内容,python库需要bpf_module_create_b,而libbcc.so.0.28.0中没有

可以通过以下命令查看:

wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.28.0 |grep bpf_module_create_
bpf_module_create_c
bpf_module_create_c_from_string
bpf_module_create_c.cold
bpf_module_create_c_from_string.cold
bpf_module_create_c
bpf_module_create_c_from_string

此时注意到上一个步骤中的libbcc.so.0.18.0,同样进行bpf_module_create_b检查

wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.18.0 |grep bpf_module_create_
bpf_module_create_b
bpf_module_create_c
bpf_module_create_c_from_string

发现存在bpf_module_create_b,即便不进行时间对比,通过版本号0.18.0与0.28.0也知道,
python3的bcc库竟然请求的是老版(0.18.0)的bcc lib库

python3 bcc库检查

wj@wj:/usr/share/bcc/examples$ ll  /usr/lib/python3/dist-packages/bcc/
总计 212
drwxr-xr-x   3 root root  4096 10月  4 15:36 ./
drwxr-xr-x 155 root root 12288 11月  5 14:56 ../
-rw-r--r--   1 root root  2566  1月 19  2021 containers.py
-rw-r--r--   1 root root 20914  1月 19  2021 disassembler.py
-rw-r--r--   1 root root 58581  1月 19  2021 __init__.py
-rw-r--r--   1 root root 12951  1月 19  2021 libbcc.py
-rw-r--r--   1 root root  4693  1月 19  2021 perf.py
drwxr-xr-x   2 root root  4096 10月  4 15:36 __pycache__/
-rw-r--r--   1 root root  9656  1月 19  2021 syscall.py
-rw-r--r--   1 root root 40588  1月 19  2021 table.py
-rw-r--r--   1 root root  1604  1月 19  2021 tcp.py
-rw-r--r--   1 root root  9102  1月 19  2021 usdt.py
-rw-r--r--   1 root root  4904  1月 19  2021 utils.py
-rw-r--r--   1 root root    23  1月 19  2021 version.py

根据文件时间可以确定,确实都是21年的老库,遂进行替换,先查找bcc源码中的bcc python库:

wj@wj:/usr/share/bcc/examples$ find / -name libbcc.py -ls 2>/dev/null408370     16 -rw-rw-r--   1 wj       wj          14561 11月  5 14:44 /home/wj/bcc/build/src/python/bcc-python3/bcc/libbcc.py408643     16 -rw-r--r--   1 root     root        14561 11月  5 14:44 /home/wj/bcc/build/src/python/bcc-python3/build/lib/bcc/libbcc.py407310     16 -rw-rw-r--   1 wj       wj          14561 11月  5 14:43 /home/wj/bcc/src/python/bcc/libbcc.py4496431     16 -rw-r--r--   1 root     root        12951 1月 19  2021 /usr/lib/python3/dist-packages/bcc/libbcc.py

wj@wj:/usr/share/bcc/examples$ cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/containers.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/disassembler.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/__init__.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/libbcc.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/perf.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/syscall.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/table.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/tcp.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/usdt.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/utils.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/version.py': 权限不够
sudo cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/

参考:AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b-CSDN博客

正常输出

可以看到 内核捕获到了 kprobe__sys_clone 事件,并打印出 Hello, World! 出来。

监控进程切换

//task_switch.py


#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")from bcc import BPF
from time import sleepb = BPF(src_file="task_switch.c")
b.attach_kprobe(event_re="^finish_task_switch$|^finish_task_switch\.isra\.\d$",fn_name="count_sched")# generate many schedule events
for i in range(0, 100): sleep(0.01)for k, v in b["stats"].items():print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))

k.prev_pid :表示上一个进程的 pid

k.curr_pid :表示切换到当前进程 pid

task_switch.c

#include <uapi/linux/ptrace.h>
#include <linux/sched.h>struct key_t {u32 prev_pid;u32 curr_pid;
};BPF_HASH(stats, struct key_t, u64, 1024);
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {struct key_t key = {};u64 zero = 0, *val;key.curr_pid = bpf_get_current_pid_tgid();key.prev_pid = prev->pid;// could also use `stats.increment(key);`val = stats.lookup_or_try_init(&key, &zero);if (val) {(*val)++;}return 0;
}

运行输出

wj@wj:/usr/share/bcc/examples/tracing$ sudo python3 task_switch.py 
[sudo] wj 的密码: 
task_switch[  879->    0]=1
task_switch[    0->14938]=2
task_switch[14959->    0]=1
task_switch[    0->14964]=2
task_switch[    0->   71]=2
task_switch[    0->15021]=1
task_switch[14969->14939]=1
task_switch[11713->    0]=1
task_switch[   52->    0]=1
task_switch[    0->  809]=4
task_switch[ 2402->    0]=6
task_switch[  928->    0]=1
task_switch[ 5247->    0]=3
task_switch[    0->  437]=3
task_switch[    0-> 7458]=6
task_switch[    0->14986]=1
task_switch[11411->    0]=3
task_switch[ 2674->    0]=5
task_switch[15064->    0]=1
task_switch[ 8767->    0]=48
task_switch[14939->14969]=1
task_switch[14998->    0]=1
task_switch[    0->14921]=2
task_switch[14986->14959]=2
task_switch[    0->15194]=1
task_switch[    0->   16]=1
task_switch[    0->   15]=14
task_switch[  901->15194]=1
task_switch[   22->    0]=1
task_switch[ 1816->    0]=7
task_switch[    0->   40]=1
task_switch[14959->14986]=1
task_switch[    0->  901]=1
task_switch[14577->    0]=1
task_switch[    0-> 5247]=3
task_switch[   58->    0]=1
task_switch[14938->    0]=2
task_switch[    0->11411]=3
task_switch[   34->    0]=1
task_switch[15194->    0]=2
task_switch[    0->   58]=1
task_switch[    0->   28]=1
task_switch[ 7458->    0]=7
task_switch[    0->15010]=3
task_switch[  926->    0]=1
task_switch[14921->    0]=2
task_switch[   46->    0]=1
task_switch[14964->    0]=3
task_switch[15030->    0]=3
task_switch[   15->    0]=14
task_switch[   40->    0]=1
task_switch[    0->14374]=5
task_switch[    0->15064]=1
task_switch[15129->    0]=1
task_switch[    0-> 8767]=47
task_switch[    0->15129]=1
task_switch[  809->    0]=3
task_switch[14374->    0]=5
task_switch[    0-> 2674]=5
task_switch[    0->   34]=1
task_switch[    0->  926]=1
task_switch[    0->15211]=100
task_switch[14969->    0]=1
task_switch[    0->14969]=1
task_switch[    0->11713]=1
task_switch[  437->    0]=3
task_switch[  835->    0]=11
task_switch[ 2035->    0]=11
task_switch[ 8767->   29]=10
task_switch[    0->14577]=1
task_switch[    0-> 1816]=7
task_switch[    0->14998]=1
task_switch[    0->  928]=1
task_switch[15010->    0]=3
task_switch[    0-> 2402]=6
task_switch[    0->14981]=1
task_switch[    0-> 2142]=1
task_switch[  953->    0]=1
task_switch[   29-> 8767]=10
task_switch[  835-> 8767]=1
task_switch[    0->  835]=12
task_switch[   28->    0]=1
task_switch[    0->  953]=1
task_switch[    0-> 2035]=11
task_switch[14981->14964]=1
task_switch[  809-> 7458]=1
task_switch[ 1702->    0]=1
task_switch[    0->   52]=1
task_switch[   16->    0]=1
task_switch[    0->  879]=1
task_switch[    0->15030]=3
task_switch[15211->    0]=100
task_switch[    0->   22]=1
task_switch[   71->    0]=2
task_switch[15021->    0]=1
task_switch[    0->   46]=1
task_switch[ 2142->    0]=1

监控CPU直方图

tools/cpudist: Summarize on- and off-CPU time per task as a histogram.

tools/cpudist:将每个任务的 CPU 开启和关闭时间总结为直方图。

wj@wj:/usr/share/bcc/tools$ sudo python3 ./cpudist
Tracing on-CPU time... Hit Ctrl-C to end.
^Cusecs               : count     distribution0 -> 1          : 5        |*                                       |2 -> 3          : 38       |********                                |4 -> 7          : 106      |***********************                 |8 -> 15         : 134      |******************************          |16 -> 31         : 156      |***********************************     |32 -> 63         : 177      |****************************************|64 -> 127        : 142      |********************************        |128 -> 255        : 63       |**************                          |256 -> 511        : 79       |*****************                       |512 -> 1023       : 21       |****                                    |1024 -> 2047       : 7        |*                                       |2048 -> 4095       : 1        |                                        |4096 -> 8191       : 1        |                                        |
wj@wj:/usr/share/bcc/tools$ 

缓存命中率监控:cachestat

  • tools/cachestat: Trace page cache hit/miss ratio. Examples.

sudo python3 ./cachestat

cachetop

sudo python3 ./cachetop

以上都是自定义在 examples 和 tools 中的工具。如果需要自己开发 bcc 程序,那应该怎么样使用呢?可以参考如下链接。

BCC开发指南

https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md

相关文章:

eBPF BCC开源工具简介

目录 官方链接 编译安装 ubuntu版本 安装 examples tools hello_world.py demo 运行报错 网上目前的解决办法 错误分析过程 python版本检测 libbcc库检查 python3 bcc库检查 正常输出 监控进程切换 运行输出 监控CPU直方图 缓存命中率监控&#xff1a;caches…...

Linux上后台运行进程(nohub、screen和tmux )

文章目录 Linux上后台运行进程&#xff08;nohub、screen和tmux &#xff09;nohupscreen虚拟终端安装screen使用 tmux终端复用器[个人推荐]安装tmux使用 Linux上后台运行进程&#xff08;nohub、screen和tmux &#xff09; 命令行的典型使用方式是&#xff0c;打开一个终端窗…...

javaee实验:搭建maven+spring boot开发环境,开发“Hello,Spring Boot”应用

目录 mavenspringboot实验目的实验内容环境的搭建 在开发中&#xff0c;maven和spring都是非常常用、非常重要的管理工具和框架&#xff0c;今天就在这里使用idea进行环境的搭建和创建第一个spring程序 maven 1.1maven是一个跨平台的项目管理工具&#xff08;主要管理jar包&am…...

重新思考边缘负载均衡

本文介绍了Netflix在基于轮询的负载均衡的基础上&#xff0c;集成了包括服务器使用率在内的多因素指标&#xff0c;并对冷启动服务器进行了特殊处理&#xff0c;从而优化了负载均衡逻辑&#xff0c;提升了整体业务性能。原文: Rethinking Netflix’s Edge Load Balancing[1] 我…...

构建一个CAN报文周期任务类

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、can周期任务类构建总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 最近想着有时间实现总线报文收发的动态的配置&#xff0c;…...

深入理解计算机系统CS213 - Lecture 02

Bits, Bytes, and Integer 1.位运算与条件运算 &&#xff0c;|&#xff0c;^&#xff0c;~ 是做位运算。诸位01运算。 &&&#xff0c;||&#xff0c;&#xff01;是判断条件真假&#xff0c;而后返回0或1。 2. 位移 x << y&#xff1a;左移y位&#xff…...

【KVM】KVM介绍及功能概述

前言 大家好&#xff0c;我是秋意零。 今天介绍的内容是KVM的概述&#xff0c;以及它所支持的基本功能。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平台同名&#xff0c; 秋意零 账号创作者、 云社区 创建者&#x1f…...

centos7安装MySQL

引言 在安装与卸载的时候&#xff0c;用户全部要切换为root 在使用MySQL的时候&#xff0c;尽量使用root权限&#xff0c;便于使用&#xff08;root权限不会开的可以去百度找一下自己服务器类型的开启方式&#xff09;在本文章我将使用xshell7进行操作&#xff0c;你也可以使用…...

leetcode做题笔记215. 数组中的第K个最大元素

给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4], k 2…...

Linux Vim撤销和恢复撤销快捷键

使用 Vim 编辑文件内容时&#xff0c;经常会有如下 2 种需求&#xff1a; 对文件内容做了修改之后&#xff0c;却发现整个修改过程是错误或者没有必要的&#xff0c;想将文件恢复到修改之前的样子。 将文件内容恢复之后&#xff0c;经过仔细考虑&#xff0c;又感觉还是刚才修改…...

【BUG】记一次Maven install 报错 Could not find artifact ...:pom:0.0.1-SNAPSHOT

问题描述 创建一个maven多模块项目&#xff0c;执行install报错Could not find artifact …:pom:0.0.1-SNAPSHOT&#xff0c;然后点击clean也是报错。 原因分析&#xff1a; 从错误日志发现提示无法从远程maven仓库下载父模块&#xff0c;一看应该是哪里配置了强制从远程仓库…...

逆向学习记录(4)adb

adb用于PC和手机端通讯。 常用命令如下&#xff1a; 如果不是模拟器&#xff08;模拟器一般都有自己的adb&#xff09;&#xff0c;adb会出现在Andirod的SDK中&#xff0c;路径为&#xff1a;Android/SDK/platform-tools。 最好加入环境变量中。...

Windows Server 2016使用MBR2GPT.EXE教程!

什么是MBR2GPT.exe&#xff1f; MBR2GPT.exe是微软提供的专业工具&#xff0c;可在命令提示符下运行。使用该工具可以将引导磁盘从MBR转换为GPT分区样式&#xff0c;而无需修改或删除所选磁盘上的任何内容。 在Windows Server 2019和Windows 10&#xff08;1703…...

SpringBoot项目多环境开发

1.yml文件&#xff08;旧&#xff09; 说明&#xff1a;旧的写法。 #应用环境 spring:profiles:active: dev --- #设置环境#生产环境 spring:profiles: pro server:port: 81--- #开发环境 spirng:profiles: dev server:port: 81--- #测试环境 spring:profiles: test server:p…...

godot4实现一个单例类,作为公共数据共享类

在 Godot 4 中&#xff0c;你可以通过创建一个自动加载的脚本来实现单例类&#xff0c;用于作为公共的数据总线。你需要做的是&#xff1a; 1. 创建一个新的 GDScript 文件&#xff0c;例如 GlobalData.gd&#xff0c;并在其中定义你想要共享的变量和函数。 2. 然后&#xff0…...

AcWing - 5287. 数量 - 组合数求解+思维

最多只有k个位置满足&#xff0c;ai ! i 所以从0-k进行遍历&#xff0c;对于kj&#xff1a; 0时&#xff0c;所有位置上的数字都等于i&#xff0c;只有一种 1时&#xff0c;没有 2时&#xff0c;排列只有两种&#xff0c;1 2 或者 2 1&#xff0c;只有一种情况满足 同理3和4可以…...

《实战:如何搭建一个完整的 Vue2.0 项目》- 7、Vue2.x 项目 webpack 4 升级 5(半自动升级)

1.自动升级 先全局安装升级插件 npm i npm-check npm-check-updates -g检查依赖 npm-check更新检查后的依赖并展示版本号&#xff0c;此时 package.json还没有更新 npm-check-updates升级 package.json&#xff0c;下图显示更新版本&#xff0c;此时 package.json文件已变更…...

Python教程---Python基础语法2

1.变量和字面量(常量) 字面量就是一个一个的值,比如:1,2,3,4,5,6,‘HELLO’ 字面量所表示的意思就是它的字面的值,在程序中可以直接使用字面量 变量(variable)变量可以用来保存字面量,并且变量中保存的字面量是不定的变量本身没有任何意思,它会根据不同的字面量…...

Conda创建软件安装环境

Conda 安装软件并创建环境 Python创建虚拟环境 conda create -n env_name python3.11 进入创建的虚拟环境 conda activate env_name 安装软件 conda install -c bioconda software_name...

MySQL | MySQL 为什么不推荐使用JOIN

MySQL 为什么不推荐使用JOIN MySQL 不推荐使用 JOIN 的说法是过于简化的。实际上&#xff0c;在某些情况下使用 JOIN 是非常有用的&#xff0c;但在其他情况下可能会带来性能问题、复杂性和可维护性问题以及重复数据等问题。 首先我们需要知道JOIN语句是用于将多个表中的数据…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...