使用 BPF 监控 Kubernetes 集群(k8s BPF 工具 kubectl-trace认知

写在前面


  • 学习中遇到,整理分享,博文内容涉及:
  • kubectl-trace 安装,在节点,容器中如何使用
  • 需要注意的问题:job 闪完成,一直 Pending 状态解决
  • 理解不足小伙伴帮忙指正

不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树


kubectl-trace 安装

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$curl -L -o kubectl-trace.tar.gz https://github.com/iovisor/kubectl-trace/releases/download/v0.1.0-rc.1/kubectl-trace_0.1.0-rc.1_linux_amd64.tar.gz
└─$pwd
/root/ansible/trace
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$ls
kubectl-trace.tar.gz
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$tar -xvf kubectl-trace.tar.gz
LICENSE
README.md
kubectl-trace
trace-runner
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$mv kubectl-trace /usr/local/bin/kubectl-trace
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$

查看版本,检查安装是否成功

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace version
git commit: d34d1d586b110af718aeadc9f3213c78e543a961
build date: 2019-09-19 23:00:13 +0800 CST

如何使用

这里我们看一下帮助文档

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace run --help
Execute a bpftrace program on resourcesUsage:trace run (POD | TYPE/NAME) [-c CONTAINER] [--attach] [flags]Examples:# Count system calls using tracepoints on a specific nodekubectl trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'# Execute a bpftrace program from file on a specific nodekubectl trace run node/kubernetes-node-emt8.c.myproject.internal -f read.bt# Run an bpftrace inline program on a pod containerkubectl trace run pod/nginx -c nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"kubectl trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"# Run a bpftrace inline program on a pod container with a custom image for the init container responsible to fetch linux headerskubectl trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --init-imagename=quay.io/custom-init-image-name --fetch-headers"# Run a bpftrace inline program on a pod container with a custom image for the bpftrace container that will run your program in the clusterkubectl trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --imagename=quay.io/custom-bpftrace-image-name"
...............
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$

在节点上使用

在使用之前,可能需要做一些准备工作,提前拉去镜像

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$ansible k8s_node  -m shell -a "docker pull quay.io/iovisor/kubectl-trace-bpftrace:latest" -i host.yaml
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$ansible k8s_node  -m shell -a "docker pull quay.io/iovisor/kubectl-trace-init:latest" -i host.yaml

使用 tracepoints 在特定节点上计算系统调用次数(帮助文档中的Demo,这里实际上是动态跟踪):

kubectl trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'

kprobe:do_sys_open 是一个 bpftrace 的探针(probe),用于跟踪 Linux 内核中的 do_sys_open 系统调用。

实际上kprobe 是一种用于在内核函数入口处执行的探针类型,属于动态跟踪do_sys_open 是一个内核函数,它在打开文件时被调用。而 tracepoint 属于静态跟踪

实际的 动态跟踪 Demo

运行方式,这里使用编码方式,传递字符串

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace run node/vms103.liruilongs.github.io -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'
trace a659c18c-e50c-11ee-ba0d-000c290e5d5f created

会启动一个 job 在对应的 节点上

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get jobs
NAME                                                 COMPLETIONS   DURATION   AGE
kubectl-trace-a659c18c-e50c-11ee-ba0d-000c290e5d5f   0/1           20s        20s
webhook-cert-setup                                   0/1           124d       124d

获取 pod 信息

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get jobs | grep  a659c18c-e50c-11ee-ba0d-000c290e5d5f
kubectl-trace-a659c18c-e50c-11ee-ba0d-000c290e5d5f   0/1           29s        29s
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get pods | grep  a659c18c-e50c-11ee-ba0d-000c290e5d5f
kubectl-trace-a659c18c-e50c-11ee-ba0d-000c290e5d5f-7292n   1/1     Running   0             65s

查看 Job 日志,即上面的 跟踪日志

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl logs kubectl-trace-a659c18c-e50c-11ee-ba0d-000c290e5d5f-7292n --tail=3
dockerd: /docker/data/overlay2/b212e7a41dd9417f549f234ce768a3fd0fc0e0baf
dockerd: /docker/data/image/overlay2/imagedb/content/sha256/1f0ce7a730e7
dockerd: /docker/data/image/overlay2/imagedb/metadata/sha256/1f0ce7a730e
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$

静态跟踪 Demo

这里的静态跟踪实际上是帮助文档中讲的 tracepoint 内核跟踪点,需要注意部分机器可能需要添加 --fetch-headers

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl trace run vms105.liruilongs.github.io -e "tracepoint:syscalls:sys_enter_execve { @[comm] = count() }" --fetch-headers
trace 305a7d60-e5a0-11ee-ba88-000c290e5d5f created
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods -w
NAME                                                       READY   STATUS     RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running    1 (2d16h ago)   18d
kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f-ctfl6   0/1     Init:0/1   0               4s
kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f-ctfl6   0/1     PodInitializing   0               15s
kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f-ctfl6   1/1     Running           0               21s
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$

查看日志信息

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl logs kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt
Defaulted container "kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f" out of: kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f, kubectl-trace-init (init)
if your program has maps to print, send a SIGINT using Ctrl-C, if you want to interrupt the execution send SIGINT two times
Attaching 1 probe...

在跟踪节点传递结束信息(重新打个页面执行)

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.105 -m shell -a "pgrep bpftrace" -i host.yaml
192.168.26.105 | CHANGED | rc=0 >>
37312
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.105 -m shell -a "kill -2 37312" -i host.yaml
192.168.26.105 | CHANGED | rc=0 >>

对应的跟踪日志信息输出

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl logs kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f-ctfl6  -f
Defaulted container "kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f" out of: kubectl-trace-305a7d60-e5a0-11ee-ba88-000c290e5d5f, kubectl-trace-init (init)
if your program has maps to print, send a SIGINT using Ctrl-C, if you want to interrupt the execution send SIGINT two times
Attaching 1 probe...@[bash]: 1
@[systemd-udevd]: 1
@[calico]: 2
@[containerd]: 6
@[nsenter]: 15
@[kubelet]: 18
@[kube-proxy]: 34
@[runc:[2:INIT]]: 207
@[exe]: 207
@[runc]: 208
@[containerd-shim]: 220
@[calico-node]: 303
@[cri-dockerd]: 313
@[dockerd]: 3907

pod 状态为完成

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods
NAME                                                       READY   STATUS      RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running     1 (2d16h ago)   18d
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   0/1     Completed   0               31m

运行方式通过 文件的方式,使用 bpftrace 自带的脚步执行

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace run vms105.liruilongs.github.io -f  opensnoop.bt --fetch-headers
trace e0b7df1e-e5a1-11ee-898f-000c290e5d5f created
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get pods | grep e0b7df1e-e5a1-11ee-898f-000c290e5d5f
kubectl-trace-e0b7df1e-e5a1-11ee-898f-000c290e5d5f-wv8w2   0/1     PodInitializing   0               12s
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace logs e0b7df1e-e5a1-11ee-898f-000c290e5d5f
if your program has maps to print, send a SIGINT using Ctrl-C, if you want to interrupt the execution send SIGINT two times
Attaching 6 probes...
Tracing open syscalls... Hit Ctrl-C to end.
PID    COMM               FD ERR PATH
1038   dockerd           133   0 /docker/data/image/overlay2/imagedb/content/sha256/4873874c08ef
1038   dockerd           133   0 /docker/data/image/overlay2/imagedb/content/sha256/4873874c08ef
1038   dockerd            -1   2 /docker/data/image/overlay2/imagedb/metadata/sha256/4873874c08e
1316   kubelet            17   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.stat
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.usage
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.max_u
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.failc
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.limit
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.memsw
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.memsw
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.memsw
1316   kubelet            19   0 /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.memsw
............................

bpftrace 自带了opensnoop.bt,这个工具可以同时对每个系统调用的开始和结束位置进行跟踪,然后将结果分列输出:

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$cat opensnoop.bt
#!/usr/bin/bpftrace
/** opensnoop    Trace open() syscalls.*              For Linux, uses bpftrace and eBPF.** Also a basic example of bpftrace.** USAGE: opensnoop.bt** This is a bpftrace version of the bcc tool of the same name.** Copyright 2018 Netflix, Inc.* Licensed under the Apache License, Version 2.0 (the "License")** 08-Sep-2018  Brendan Gregg   Created this.*/BEGIN
{printf("Tracing open syscalls... Hit Ctrl-C to end.\n");printf("%-6s %-16s %4s %3s %s\n", "PID", "COMM", "FD", "ERR", "PATH");
}tracepoint:syscalls:sys_enter_open,
tracepoint:syscalls:sys_enter_openat
{@filename[tid] = args->filename;
}tracepoint:syscalls:sys_exit_open,
tracepoint:syscalls:sys_exit_openat
/@filename[tid]/
{$ret = args->ret;$fd = $ret >= 0 ? $ret : -1;$errno = $ret >= 0 ? 0 : - $ret;printf("%-6d %-16s %4d %3d %s\n", pid, comm, $fd, $errno,str(@filename[tid]));delete(@filename[tid]);
}END
{clear(@filename);
}

容器中使用

容器相关的这里不做演示,下面是帮助文档的 Demo

在 Pod 容器上运行内联的 bpftrace 程序:

kubectl trace run pod/nginx -c nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"

在 Pod 容器上使用自定义镜像运行内联的 bpftrace 程序:

kubectl trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }" --imagename=quay.io/custom-bpftrace-image-name

需要注意的问题

job 闪完成

在编译或构建过程中,表示缺少了必要的头文件,job 启 Pod 之后会马上闪退

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl trace run node/vms103.liruilongs.github.io -f opensnoop.bt
trace fc86c785-e513-11ee-8e04-000c290e5d5f created
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get pods | grep fc86c785-e513-11ee-8e04-000c290e5d5f
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     ContainerCreating   0             8s
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl get pods kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm -w
NAME                                                       READY   STATUS      RESTARTS   AGE
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     Completed   0          19s
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     Completed   0          20s
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     Completed   0          21s
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     Terminating   0          26s
kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm   0/1     Terminating   0          26s
^C┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$
┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$kubectl logs  kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm
Error from server (NotFound): pods "kubectl-trace-fc86c785-e513-11ee-8e04-000c290e5d5f-g67gm" not found

日志信息

if your program has maps to print, send a SIGINT using Ctrl-C, if you want to interrupt the execution send SIGINT two ││ times                                                                                                                │
│/bpftrace/include/clang_workarounds.h:14:10: fatal error: 'linux/types.h' file not found                              ││exit status 1

执行环境

┌──[root@vms100.liruilongs.github.io]-[~/ansible/trace]
└─$hostnamectlStatic hostname: vms100.liruilongs.github.ioIcon name: computer-vmChassis: vmMachine ID: e93ae3f6cb354f3ba509eeb73568087eBoot ID: 51ad5f1933914654affd2dcf9ebca862Virtualization: vmwareOperating System: CentOS Linux 7 (Core)CPE OS Name: cpe:/o:centos:centos:7Kernel: Linux 5.4.266-1.el7.elrepo.x86_64Architecture: x86-64

解决办法: 添加 --fetch-headers 尝试 https://github.com/iovisor/kubectl-trace/issues/177

┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl trace run vms105.liruilongs.github.io -e "tracepoint:syscalls:sys_enter_execve { @[comm] = count() }" --fetch-headers
trace 3d9981a0-e59b-11ee-a570-000c290e5d5f created
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods
NAME                                                       READY   STATUS     RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running    1 (2d16h ago)   18d
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   0/1     Init:0/1   0               12s
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods -w
NAME                                                       READY   STATUS     RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running    1 (2d16h ago)   18d
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   0/1     Init:0/1   0               33s
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   0/1     Init:0/1   0               41s
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods -w
NAME                                                       READY   STATUS     RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running    1 (2d16h ago)   18d
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   0/1     Init:0/1   0               64s
┌──[root@vms100.liruilongs.github.io]-[~/ansible]
└─$kubectl get pods
NAME                                                       READY   STATUS    RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running   1 (2d16h ago)   18d
kubectl-trace-3d9981a0-e59b-11ee-a570-000c290e5d5f-wwprt   1/1     Running   0               16m

一直 Pending 状态

这里需要注意,如果是 master 节点做分析,需要把对应的 master 的污点去掉,负责无法调度

┌──[root@vms100.liruilongs.github.io]-[~]
└─$kubectl trace run vms102.liruilongs.github.io -e "tracepoint:syscalls:sys_enter_execve { @[comm] = count() }"
trace 4f30d986-e595-11ee-a5ef-000c290e5d5f created
┌──[root@vms100.liruilongs.github.io]-[~]
└─$kubectl get pods
NAME                                                       READY   STATUS    RESTARTS        AGE
hello-webhook-deployment-7f599b95c4-hjx86                  1/1     Running   1 (2d15h ago)   18d
kubectl-trace-4f30d986-e595-11ee-a5ef-000c290e5d5f-xw6qm   0/1     Pending   0               7s
┌──[root@vms100.liruilongs.github.io]-[~]
└─$kubectl describe pods kubectl-trace-4f30d986-e595-11ee-a5ef-000c290e5d5f-xw6qm
..................
Events:Type     Reason            Age   From               Message----     ------            ----  ----               -------Warning  FailedScheduling  23s   default-scheduler  0/6 nodes are available: 3 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 5 node(s) didn't match Pod's node affinity/selector. preemption: 0/6 nodes are available: 6 Preemption is not helpful for scheduling.
┌──[root@vms100.liruilongs.github.io]-[~]
└─$kubectl trace delete 4f30d986-e595-11ee-a5ef-000c290e5d5f
trace job kubectl-trace-4f30d986-e595-11ee-a5ef-000c290e5d5f deleted
trace configuration kubectl-trace-4f30d986-e595-11ee-a5ef-000c290e5d5f deleted

在实际生产中可以考虑通过 sidecar 边车的方式运行,监视 pod 中的所有容器。这里不做分享,感兴趣小伙伴可以研究下 _

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃


https://github.com/iovisor/kubectl-trace

https://medium.com/@calavera/spy-on-your-kubernetes-cluster-with-bpf-b09032bd1cdc

https://github.com/iovisor/kubectl-trace/issues/177


© 2018-2024 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS使用catkin_make编译单个功能包和所有功能包

编译功能包: catkin_make -DCATKIN_WHITELIST_PACKAGES"需要单独编译的包名"但是如再次使用catkin_make编译所有功能包时会出现只编译上次设置的单独功能包,如果想要再次使用catkin_make编译所有功能包,需要执行: cat…

c++异构计算获取计算进度

异步运行任务,并定期检查任务是否已完成。如果没有,您希望打印出任务的进度。但是,您提供的代码存在一些问题: 1。“TaskRun”类未在您提供的代码段中定义。请确保其定义正确,并且“run”方法是“TaskRun”的成员函数…

springboot项目讲解

技术栈 vue(前端) springboot(后端主框架) mybatis(ORM,用于后端和数据库的映射,即java对象转换成表) mysql (关系型数据库) 顶层结构 .idea: idea缓存文件(不需要管) src:代码核心文件夹 —main&#xf…

【PINet车道线检测】代码复现过程

《Key Points Estimation and Point Instance Segmentation Approach for Lane Detection》 论文:https://arxiv.org/abs/2002.06604 代码:GitHub - koyeongmin/PINet 论文解读:http://t.csdnimg.cn/AOV91 这是篇关于自动驾驶中车道检测技…

代码随想录算法训练营第50天 | 123.买卖股票的最佳时机III ,188.买卖股票的最佳时机IV

动态规划章节理论基础: https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 123.买卖股票的最佳时机III 题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/ 思…

如何本地部署1Panel面板

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、…

PTA一笔画

作者 张志梅 单位 青岛大学 小丁最近迷恋上一个游戏,传说中的“一笔画”游戏。 那么什么是一笔画?如下图,顾名思义就是一笔可以完成的图。一笔画最基本的要求是在画图的过程中,笔不能离开纸,且笔所画过的线不能重复…

Springboot和Spring Cloud版本对应

Spring在不断地升级,各个版本存在一些不兼容的地方,为了避免出现问题,最好注意使用正确的版本。 官网的对应关系:https://start.spring.io/actuator/info 如下图: 下面附一下创建项目的工具: Spring官方…

【洛谷 P9242】[蓝桥杯 2023 省 B] 接龙数列 题解(线性DP+二维数组)

[蓝桥杯 2023 省 B] 接龙数列 题目描述 对于一个长度为 K K K 的整数数列: A 1 , A 2 , … , A K A_{1},A_{2},\ldots,A_{K} A1​,A2​,…,AK​,我们称之为接龙数列当且仅当 A i A_{i} Ai​ 的首位数字恰好等于 A i − 1 A_{i-1} Ai−1​ 的末位数字…

代码随想录算法训练营第53天 | 1143.最长公共子序列 ,1035.不相交的线 ,53. 最大子序和

动态规划章节理论基础: https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1143.最长公共子序列 题目链接:https://leetcode.cn/problems/longest-common-subsequence/description/ 思路&…

13|连接数据库:通过链和代理查询鲜花信息

新的数据库查询范式 提出问题:用户用自然语言提出一个问题,例如“去年的总销售额是多少?”。LLM 理解并转译:LLM 首先会解析这个问题,理解其背后的意图和所需的信息。接着,模型会根据解析的内容&#xff0c…

KY61 放苹果(用Java实现)

描述 把 M 个同样的苹果放在 N 个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法? 注意:5、1、1 和 1、5、1 是同一种分法,即顺序无关。 输入描述: 输入包含多组数据。 每组数据包含两个正整…

2024年零基础转行软件测试真的可以吗?“我“该如何做?

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 零基础的学生&…

博图西门子HMI下载报错—缺少面板映像,下载失败解决办法

一、报错展示 二、解决过程 1、第一种: 在安装博图(V17)时,需要下载各类软件,这时钩选全部能够选择的软件。然后进行下载。但是在这里我遇到了下载软件时,无法选择红框中的文件。那么就需要单独去西门子官网下载。 2、第二种&am…

MQ之Spring AMQP学习

Spring AMQP学习 Spring AMQP AMQP是Advanced Message Queuing Protocol的缩写。AMQP是用于在应用程序之间传递消息的开放标准,该协议与语言和平台无关,更符合微服务中独立性的要求。 Spring AMQP是基于AMQP协议定义的一套API规范,提供了模…

广告业务知识-术语

一、广告专业术语 最近做了些广告业务,梳理下,分广告术语、业务架构、数据架构三篇。 1.广告基础术语 填充率 Fi Rate :广告请求量为 200 次,广告系统返回 100 次广告,则填充率 Fi Rate 100/20050%。 Impression:曝…

ByteArrayOutputStream流

介绍: ByteArrayOutputStream 对byte类型数据进行写入的类 相当于一个中间缓冲层,将类写入到文件等其他outputStream。它是对字节进行操作,属于内存操作流 一源码解析: public class ByteArrayOutputStream extends OutputStre…

微信小程序接口请求出错:request:fail url not in domain list:xxxxx

一、微信小程序后台和开发者工具配的不一样导致了这个错误 先说结论: 开发者工具配置了https://www.xxx.cn/prod-api/ 微信后台配置了 https://www.xxx.cn 一、最开始 开发者工具配置了https://www.xxx.cn:7500 微信后台配置了 https://www.xxx.cn 报错:reques…

关系数据库:关系数据结构基础与概念解析

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

外包2月,技术倒退警钟长鸣。。。。。

曾经的我,作为一名大专生,在湖南某软件公司从事功能测试工作近四年。日复一日的工作让我陷入舒适区,不思进取。直到今年8月,我才意识到自己的技术停滞不前,女友的离开更是让我痛定思痛,决定改变现状&#x…