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

解析 Ingress-Nginx 故障:排查思路与方法

文章目录

  • 一、什么是Ingress-Nginx
  • 二、故障排除
    • 1.1Ingress-Controller日志和事件
      • 检查 Ingress 资源事件
      • 检查 Nginx 配置
      • 检查使用的服务是否存在
      • 调试日志
    • 1.2对 Kubernetes API 服务器的认证
      • 服务认证
      • 服务账户
      • Kube-Config
    • 1.3使用GDB和Nginx
    • 1.4在 Nginx 4.2.5 或其他版本(Helm 图表版本)上遇到的图像相关问题
    • 1.5无法监听端口(80/443)
      • 创建一个测试pod
    • 1.6使用root创建测试pod

一、什么是Ingress-Nginx

Ingress-nginx 是 Kubernetes 的一个 Ingress 控制器,它可以将外部的 HTTP 和 HTTPS 流量路由到集群内部的服务。Ingress 是 Kubernetes 中的一个 API 对象,它管理外部访问到集群服务的规则。Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟主机等功能。
Ingress-nginx 控制器是 Ingress 资源的一种实现,它根据定义在 Ingress 资源中的规则,动态地配置 Nginx 服务器,以路由流量。这使得你可以很方便地在 Kubernetes 集群中实现复杂的流量路由规则。

二、故障排除

1.1Ingress-Controller日志和事件

有许多方法可以对 ingress-controller 进行故障排除。以下是获取更多信息的基本故障排除方法。

检查 Ingress 资源事件

$ kubectl get ing -n <namespace-of-ingress-resource>
NAME           HOSTS      ADDRESS     PORTS     AGE
cafe-ingress   cafe.com   10.0.2.15   80        25s$ kubectl describe ing <ingress-resource-name> -n <namespace-of-ingress-resource>
Name:             cafe-ingress
Namespace:        default
Address:          10.0.2.15
Default backend:  default-http-backend:80 (172.17.0.5:8080)
Rules:Host      Path  Backends----      ----  --------cafe.com/tea      tea-svc:80 (<none>)/coffee   coffee-svc:80 (<none>)
Annotations:kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{},"name":"cafe-ingress","namespace":"default","selfLink":"/apis/networking/v1/namespaces/default/ingresses/cafe-ingress"},"spec":{"rules":[{"host":"cafe.com","http":{"paths":[{"backend":{"serviceName":"tea-svc","servicePort":80},"path":"/tea"},{"backend":{"serviceName":"coffee-svc","servicePort":80},"path":"/coffee"}]}}]},"status":{"loadBalancer":{"ingress":[{"ip":"169.48.142.110"}]}}}Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  CREATE  1m    ingress-nginx-controller  Ingress default/cafe-ingressNormal  UPDATE  58s   ingress-nginx-controller  Ingress default/cafe-ingress

检查 Nginx 配置

$ kubectl get pods -n <namespace-of-ingress-controller>
NAME                                        READY     STATUS    RESTARTS   AGE
ingress-nginx-controller-67956bf89d-fv58j   1/1       Running   0          1m$ kubectl exec -it -n <namespace-of-ingress-controller> ingress-nginx-controller-67956bf89d-fv58j -- cat /etc/nginx/nginx.conf
daemon off;
worker_processes 2;
pid /run/nginx.pid;
worker_rlimit_nofile 523264;
worker_shutdown_timeout 240s;
events {multi_accept        on;worker_connections  16384;use                 epoll;
}
http {
....

检查使用的服务是否存在

$ kubectl get svc --all-namespaces
NAMESPACE     NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
default       coffee-svc             ClusterIP   10.106.154.35    <none>        80/TCP          18m
default       kubernetes             ClusterIP   10.96.0.1        <none>        443/TCP         30m
default       tea-svc                ClusterIP   10.104.172.12    <none>        80/TCP          18m
kube-system   default-http-backend   NodePort    10.108.189.236   <none>        80:30001/TCP    30m
kube-system   kube-dns               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP   30m
kube-system   kubernetes-dashboard   NodePort    10.103.128.17    <none>        80:30000/TCP    30m

调试日志

通过使用标志 --v=XX,可以增加日志的级别。这是通过编辑部署来完成的。

$ kubectl get deploy -n <namespace-of-ingress-controller>
NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
default-http-backend       1         1         1            1           35m
ingress-nginx-controller   1         1         1            1           35m$ kubectl edit deploy -n <namespace-of-ingress-controller> ingress-nginx-controller
# Add --v=X to "- args", where X is an integer

–v=2 显示了关于 nginx 配置更改的详细信息,这些信息是通过 diff 显示的
–v=3 显示了关于服务、Ingress规则、端点更改的详细信息,并且它会以 JSON 格式输出 nginx 配置
–v=5 将 NGINX 配置为调试模式

1.2对 Kubernetes API 服务器的认证

许多组件参与了认证过程,第一步是确定问题的来源,即问题是出在服务认证上,还是出在 kubeconfig 文件上。
这两种认证都必须有效:
在这里插入图片描述

服务认证

Ingress 控制器需要从 apiserver 获取信息。因此,需要进行认证,这可以通过几种方式实现:

  1. 服务账户:这是推荐的方式,因为无需进行任何配置。Ingress 控制器将使用系统提供的信息与 API 服务器进行通信。详见 ‘服务账户’ 部分。
  2. Kubeconfig 文件:在一些 Kubernetes 环境中,服务账户可能不可用。在这种情况下,需要手动配置。可以使用 --kubeconfig 标志启动 Ingress 控制器二进制文件。该标志的值是一个文件路径,该文件指定了如何连接到 API 服务器。使用 --kubeconfig 不需要 --apiserver-host 标志。文件的格式与 kubectl 用于连接 API 服务器的 ~/.kube/config 相同。详见 ‘kubeconfig’ 部分。
  3. 使用 --apiserver-host 标志:使用这个标志 --apiserver-host=http://localhost:8080 可以指定一个未加密的 API 服务器,或者使用 kubectl proxy 访问远程 Kubernetes 集群。请不要在生产环境中使用这种方法。
    在下面的图表中,你可以看到所有选项的完整认证流程,从左下角的浏览器开始。
    在这里插入图片描述

服务账户

如果使用服务账户连接 API 服务器,ingress-controller 期望文件 /var/run/secrets/kubernetes.io/serviceaccount/token 存在。它提供了一个秘密令牌,该令牌是与 API 服务器进行身份验证所必需的。
可以使用以下命令进行验证:

# start a container that contains curl
$ kubectl run -it --rm test --image=curlimages/curl --restart=Never -- /bin/sh# check if secret exists
/ $ ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt     namespace  token
/ $# check base connectivity from cluster inside
/ $ curl -k https://kubernetes.default.svc.cluster.local
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "forbidden: User \"system:anonymous\" cannot get path \"/\"","reason": "Forbidden","details": {},"code": 403
}/ $# connect using tokens
}/ $ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local
&& echo
{"paths": ["/api","/api/v1","/apis","/apis/",... TRUNCATED"/readyz/shutdown","/version"]
}
/ $# when you type `exit` or `^D` the test pod will be deleted.

如果它不起作用,可能有两个原因:
令牌的内容无效。使用 kubectl get secrets | grep service-account 找到秘密名称,并使用 kubectl delete secret 删除它。它将自动重新创建。
您的 Kubernetes 安装非标准,包含令牌的文件可能不存在。API 服务器将挂载包含此文件的卷,但前提是 API 服务器配置为使用 ServiceAccount 准入控制器。如果您遇到此错误,请验证您的 API 服务器是否正在使用 ServiceAccount 准入控制器。如果您手动配置 API 服务器,可以使用 --admission-control 参数设置此项。
请注意,您也应使用其他准入控制器。在配置此选项之前,您应阅读关于准入控制器的信息。

Kube-Config

如果你想使用 kubeconfig 文件进行认证,请遵循部署程序,并在部署的 args 部分添加标志 --kubeconfig=/etc/kubernetes/kubeconfig.yaml。

1.3使用GDB和Nginx

我们可以使用 gdb 和 nginx 一起执行配置的转储。这使我们能看到正在使用的配置以及旧的配置。
注意:以下内容基于 nginx 的文档。

  1. SSH 连接到工作节点
$ ssh user@workerIP
  1. 获取运行nginx的Docker容器
$ docker ps | grep ingress-nginx-controller
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
d9e1d243156a        registry.k8s.io/ingress-nginx/controller   "/usr/bin/dumb-init …"   19 minutes ago      Up 19 minutes   k8s_ingress-nginx-controller_ingress-nginx-controller-67956bf89d-mqxzt_kube-system_079f31ec-aa37-11e8-ad39-080027a227db_0
  1. 执行进入容器
$ docker exec -it --user=0 --privileged d9e1d243156a bash
  1. 确保nginx在–with-debug模式下运行
$ nginx -V 2>&1 | grep -- '--with-debug'
  1. 获取容器上运行的进程列表
$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 20:23 ?        00:00:00 /usr/bin/dumb-init /nginx-ingres
root         5     1  0 20:23 ?        00:00:05 /ingress-nginx-controller --defa
root        21     5  0 20:23 ?        00:00:00 nginx: master process /usr/sbin/
nobody     106    21  0 20:23 ?        00:00:00 nginx: worker process
nobody     107    21  0 20:23 ?        00:00:00 nginx: worker process
root       172     0  0 20:43 pts/0    00:00:00 bash
  1. 将gdb附加到nginx主进程
$ gdb -p 21
....
Attaching to process 21
Reading symbols from /usr/sbin/nginx...done.
....
(gdb)
  1. 复制并粘贴以下内容
set $cd = ngx_cycle->config_dump
set $nelts = $cd.nelts
set $elts = (ngx_conf_dump_t*)($cd.elts)
while ($nelts-- > 0)
set $name = $elts[$nelts]->name.data
printf "Dumping %s to nginx_conf.txt\n", $name
append memory nginx_conf.txt \$elts[$nelts]->buffer.start $elts[$nelts]->buffer.end
end
  1. 通过按CTRL+D退出GDB
  2. 打开nginx_conf.txt
cat nginx_conf.txt

注意:从GitHub和BitBucket Server(源SCMs)迁移依赖于从GitLab(目标)发出的传入(Ingress)REST API连接。
"./congregate.sh list" 是一个命令,它从源系统收集元数据,为迁移的后续步骤做准备。列表操作会从这些系统中提取所有的元数据,通常需要管理员令牌或只读所有凭据才能成功。要设置这些,请运行 "./congregate.sh configure",或者修改由客户提供的SCM和/或CI源主机名和凭据的data/congregate.conf。如果你直接编辑 .conf 文件,一定要参考 congregate 配置模板,以正确格式化它。
列表操作可能需要相当长的时间,这直接取决于源系统中的数据量。要调整列表的并发性,你可以在列表命令中添加 --processes=16(仅适用于GitHub)。如果不设置这个,它将使用基于硬件的进程数的 processes=nproc。当进程超过16个时要小心,因为这将增加对源系统造成不必要伤害的机会(如果他们的API速率限制没有设置,可能会导致稳定性问题)。
如果你需要重新列出并且不想覆盖之前列出的任何数据,可以使用 --partial 运行它。额外的 --skip-* 参数允许你跳过用户、组、项目和 ci。
如果你正在从带有SCM源的CI源迁移数据,列表操作也会执行一个映射功能,将CI任务映射到SCM仓库。这个功能将定位构建配置XML的迁移到仓库,以备将来转换为 gitlab-ci.yml。
为迁移准备数据的过程与使用基于git的工作流准备数据的过程相同。现在我们已经运行了"./congregate.sh list"命令,将所有数据获取到本地文件系统(本地MongoDB和.json文件的组合),我们需要选择要迁移的用户,项目和组。任何形式的stage命令的输出将会是data目录中的staged_groups.json,staged_projects.json和staged_users.json文件。
在shell中运行stage(无UI)时,我们需要确定当前迁移范围内的项目和组ID。我们可以通过几种不同的方式进行分阶段。
stage-projects
要从项目的名称(客户应该已经提供)获取项目ID,你可以运行 cat data/projects.json | grep <ProjectName> -A10 -B10 命令,其中ProjectName是要迁移的存储库(github和bitbucket)或项目(gitlab)的名称。从那里你将看到可以为以下命令记下的ID ./congregate.sh stage-projects 13 78 951 446。注意,你可以在stage-projects动词后面空格分隔地列出多个项目id。要强制此命令写入staged_projects.json和其他staged json文件,请使用–commit标志。
stage-groups
这个过程与stage-projects非常相似,但你需要在groups.json文件中搜索组id。运行 cat data/projects.json | grep <GroupName> -A10 -B10 命令。然后运行 ./congregate.sh stage-groups 78 651 997 --commit 来生成staged_*.json文件。

stage-wave
对于大型迁移,客户通常希望在电子表格中定义迁移波次,以便congregate可以读取并同时分阶段多个不同的组和项目,而无需进行项目和组id的初步调查。要设置这个,我们需要在data/congregate.conf中添加几行,看起来像模板中的那些。此配置模板引用waves.csv文件。关于此配置如何工作的更详细描述在下面的配置部分。
一旦我们有了这个,你可以运行 ./congregate.sh stage-wave <WaveName> --commit 来分阶段所有由电子表格定义的项目和组。
使用UI进行分阶段
如果你是在完整的桌面环境中运行congregate(没有SSH或BASH进入在集群上运行的容器),你可以使用UI在列出数据后进行分阶段,方法是使用 ./congregate.sh ui &。这将让你有能力选择你想要为迁移分阶段的特定组,项目和用户。一旦你选中了所有的框,你可以点击stage来生成迁移的最后一步所需的staged_*.json文件。

1.4在 Nginx 4.2.5 或其他版本(Helm 图表版本)上遇到的图像相关问题

  1. 如果你在使用 helm 图表安装 Nginx 时遇到以下错误(无论是通过 helm 命令或 helm_release terraform 提供程序)
Warning  Failed     5m5s (x4 over 6m34s)   kubelet            Failed to pull image "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0@sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47": rpc error: code = Unknown desc = failed to pull and unpack image "registry.k8s.io/ingress-nginx/kube-webhook-certgen@sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47": failed to resolve reference "registry.k8s.io/ingress-nginx/kube-webhook-certgen@sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47": failed to do request: Head "https://eu.gcr.io/v2/k8s-artifacts-prod/ingress-nginx/kube-webhook-certgen/manifests/sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47": EOF

请按照以下步骤操作。

  1. 在故障排查过程中,你也可以执行以下命令来测试你的本地机器与仓库详情的连通性。
curl registry.k8s.io/ingress-nginx/kube-webhook-certgen@sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47 > /dev/nullcurl -I https://eu.gcr.io/v2/k8s-artifacts-prod/ingress-nginx/kube-webhook-certgen/manifests/sha256:549e71a6ca248c5abd51cdb73dbc3083df62cf92ed5e6147c780e30f7e007a47

在代理中实现了重定向,以确保拉取图像。

  1. 这是建议将以下图像仓库列入白名单的解决方案:
*.appspot.com    
*.k8s.io        
*.pkg.dev
*.gcr.io

关于上述仓库的更多详细信息:a. *.k8s.io -> 为了确保你能从registry.k8s.io拉取任何图像 b. *.gcr.io -> GCP服务用于图像托管。这是GCP建议允许并确保用户可以从他们的容器注册服务拉取图像的域的一部分。c. *.appspot.com -> 这是Google的域,用于GCR的域的一部分。

1.5无法监听端口(80/443)

这个错误的一个可能原因是缺乏绑定到端口的权限。端口80,443和任何其他< 1024的端口是Linux特权端口,历史上只能由root绑定。ingress-nginx-controller使用CAP_NET_BIND_SERVICE linux能力来允许作为普通用户(www-data / 101)绑定这些端口。这涉及两个组件:1. 在镜像中,/nginx-ingress-controller文件添加了cap_net_bind_service能力(例如,通过setcap)2. 在部署的containerSecurityContext中,将NET_BIND_SERVICE能力添加到容器中。
个/某些节点上遇到这个问题,而其他节点没有,尝试在受影响的节点上清除并拉取镜像的新副本,以防底层层次的损坏导致可执行文件失去能力。

创建一个测试pod

当遇到这个错误时,/nginx-ingress-controller进程会退出/崩溃,这使得很难排查容器内部发生的情况。为了解决这个问题,启动一个运行"sleep 3600"的等效容器,并进入它进行进一步的排查。
例如:

apiVersion: v1
kind: Pod
metadata:name: ingress-nginx-sleepnamespace: defaultlabels:app: nginx
spec:containers:- name: nginximage: ##_CONTROLLER_IMAGE_##resources:requests:memory: "512Mi"cpu: "500m"limits:memory: "1Gi"cpu: "1"command: ["sleep"]args: ["3600"]ports:- containerPort: 80name: httpprotocol: TCP- containerPort: 443name: httpsprotocol: TCPsecurityContext:allowPrivilegeEscalation: truecapabilities:add:- NET_BIND_SERVICEdrop:- ALLrunAsUser: 101restartPolicy: NevernodeSelector:kubernetes.io/hostname: ##_NODE_NAME_##tolerations:- key: "node.kubernetes.io/unschedulable"operator: "Exists"effect: NoSchedule

如果适用/需要,请更新命名空间
将 ##NODE_NAME## 替换为有问题的节点(如果问题不仅限于一个节点,则删除 nodeSelector 部分)
将 ##CONTROLLER_IMAGE## 替换为您的 ingress-nginx 部署中使用的相同镜像
确认 securityContext 部分与您的集群中用于 ingress-nginx-controller pods 的设置匹配
应用这个 YAML 并打开一个连接到 pod 的 shell。尝试手动运行控制器进程:

$ /nginx-ingress-controller

你应该会从 ingress 控制器 pod 的日志中获取到相同的错误。
确认 capabilities 是否正确应用到 pod 中:

$ grep CapBnd /proc/1/status
CapBnd: 0000000000000400

上述值只启用了 net_bind_service(根据 YAML 中的 security context,它添加了该功能并丢弃了所有其他功能)。如果你得到一个不同的值,那么你可以在另一个 Linux 箱子上解码它(这个容器中没有 capsh),如下所示,然后找出为什么指定的 capabilities 没有传播到 pod/容器中。

$ capsh --decode=0000000000000400
0x0000000000000400=cap_net_bind_service

1.6使用root创建测试pod

(注意,这可能会受到 PodSecurityPolicy、PodSecurityAdmission/Standards、OPA Gatekeeper 等的限制,如果是这种情况,你将需要进行适当的测试工作,例如,在没有这些限制的新命名空间中部署。)为了进一步测试,你可能需要安装额外的工具等。通过以下方式修改 pod yaml:
将 runAsUser 从 101 改为 0
从 capabilities 中删除 “drop…ALL” 部分。
在进入此容器后尝试以下操作:
尝试以 www-data(101)用户身份运行控制器:

$ chmod 4755 /nginx-ingress-controller
$ /nginx-ingress-controller

检查错误,看看是否仍然存在在端口监听的问题,或者是否已经通过了这个问题,转而出现了由于运行上下文耗尽导致的其他预期错误。
安装 libcap 包并检查文件上的 capabilities:

$ apk add libcap
(1/1) Installing libcap (2.50-r0)
Executing busybox-1.33.1-r7.trigger
OK: 26 MiB in 41 packages
$ getcap /nginx-ingress-controller
/nginx-ingress-controller cap_net_bind_service=ep

(如果缺失,参见上文关于在服务器上清除图像并重新拉取的部分)
使用 strace 跟踪可执行文件,查看当它失败时正在执行的系统调用:

$ apk add strace
(1/1) Installing strace (5.12-r0)
Executing busybox-1.33.1-r7.trigger
OK: 28 MiB in 42 packages
$ strace /nginx-ingress-controller
execve("/nginx-ingress-controller", ["/nginx-ingress-controller"], 0x7ffeb9eb3240 /* 131 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x29ea690)      = 0
...

相关文章:

解析 Ingress-Nginx 故障:排查思路与方法

文章目录 一、什么是Ingress-Nginx二、故障排除1.1Ingress-Controller日志和事件检查 Ingress 资源事件检查 Nginx 配置检查使用的服务是否存在调试日志 1.2对 Kubernetes API 服务器的认证服务认证服务账户Kube-Config 1.3使用GDB和Nginx1.4在 Nginx 4.2.5 或其他版本&#xf…...

2024 楚慧杯 re wp

go_bytes 附件拖入ida 输入长度为0x28&#xff0c;每两位字符的4bit拼接 与一个常量值经过运算后的值进行异或&#xff0c;并且判断是否相等 脚本 bouquet 附件拖入ida。简单去一下花 构建了一个二叉树&#xff0c;然后递归调用函数 重新排列一下再层序遍历读出即可 zistel 附件…...

【物联网技术与应用】实验10:蜂鸣器实验

实验10 蜂鸣器实验 【实验介绍】 蜂鸣器是音频信号装置。蜂鸣器可分为有源蜂鸣器和无源蜂鸣器。 【实验组件】 ● Arduino Uno主板* 1 ● USB数据线* 1 ● 有源蜂鸣器* 1 ● 无源蜂鸣器* 1 ● 面包板* 1 ● 9V方型电池* 1 ● 跳线若干 【实验原理】 如图所示&#x…...

单片机:实现矩阵键盘控制LCD屏幕(附带源码)

单片机实现矩阵键盘控制LCD屏幕 矩阵键盘&#xff08;Matrix Keypad&#xff09;是一种常用的输入设备&#xff0c;广泛应用于嵌入式系统中。在许多嵌入式应用中&#xff0c;我们常常需要通过按键输入来控制系统的功能。结合LCD显示屏&#xff0c;我们可以实现一个简单的界面&…...

鸿蒙Next之包体积极限优化

鸿蒙应用包大小优化全解析 在鸿蒙应用开发中&#xff0c;减小应用包大小对于提升应用下载和安装体验起着关键作用。通过压缩、精简或复用应用中的代码与资源&#xff0c;能有效降低包体积&#xff0c;减少空间占用并加快下载与安装速度。下面详细介绍一下鸿蒙应用包大小优化的…...

Android实战经验篇-log工具

详细代码实现及系列文章请转如下链接 Android实战经验篇-系列文章汇总 Android Display Graphics系列文章-汇总 一、基础知识 1.1 Logging简述 我们写的第一个计算机C程序一般是printf(“Hello world!”);这就是一个log输出。Linux内核有Kernel log以及配套的Log工具&#x…...

DPU编程技术解析与实践应用

一、引言 1.1 研究背景与目的 随着信息技术的飞速发展&#xff0c;数据中心在现代社会中的地位日益凸显&#xff0c;成为支撑各行业数字化转型的关键基础设施。在数据中心内部&#xff0c;数据的处理速度、效率和安全性成为了影响整体性能的核心要素。为了应对不断增长的数据…...

红帽认证的含金量和价值如何?怎么报名红帽认证考试?

红帽企业 Linux&#xff08;RHEL&#xff09;是由红帽公司提供的一款商业支持、专为生产环境设计的Linux发行版。随着IT系统和工作负载日益复杂化&#xff0c;底层基础设施及操作系统必须兼具可靠性、可扩展性&#xff0c;并能有效促进性能提升。红帽认证在全球范围享有盛誉&am…...

VS Code Copilot 与 Cursor 对比

选手简介 VS Code Copilot&#xff1a;算是“老牌”编程助手了&#xff0c;虽然Copilot在别的编辑器上也有扩展&#xff0c;不过体验最好的还是VS Code&#xff0c;毕竟都是微软家的所以功能集成更好一些&#xff1b;主要提供的是Complete和Chat能力&#xff0c;也就是代码补全…...

蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)

一、工程模版创建流程 第一步 创建新项目 第二步 选择型号和管脚封装 第三步 RCC使能 外部时钟&#xff0c;高速外部时钟 第四步晶振时钟配置 由数据手册7.1可知外部晶振频率为24MHz 最后一项设置为80 按下回车他会自动配置时钟 第五步&#xff0c;如果不勾选可能程序只会…...

取多个集合的交集

1.我们取多个集合的交集&#xff0c;先把各个集合放入list中 List < Set < String > > listnew ArrayList<>();HashSet<String> set1new HashSet<>();set1.add( "A" );set1.add("B" );set1.add("C" );HashSet<…...

如何实现电子发票XML文件的合规性存档?

随着国家税务改革的推进&#xff0c;企业对电子发票的管理和存档要求越来越高。尤其是《财政部 国家税务总局关于进一步深化增值税发票管理改革的通知》&#xff08;财会〔2023〕18号文&#xff09;的发布&#xff0c;明确规定了电子发票的存档要求。这为企业在财务管理中的电子…...

IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档

IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档 一、引言 在现代制造业和工业管理领域&#xff0c;IOT&#xff08;物联网&#xff09;、MES&#xff08;制造执行系统&#xff09;、WMS&#xff08;仓库管理系统&#xff09;、MOM&#xff08;制造运营管理系统&#xff…...

IntelliJ IDEA Docker集成

一、概述 Docker是一种用于在隔离和可复制环境中部署和运行可执行文件的工具。这可能很有用&#xff0c;例如&#xff0c;在与生产相同的环境中测试代码。 IntelliJ IDEA集成了Docker功能&#xff0c;并为创建Docker映像、运行Docker容器、管理Docker Compose应用程序、使用公…...

【react项目】从零搭建react项目[nodejs安装]

〇、模板git下载地址 下载即用的模板地址&#xff1a; http:https://e.coding.net/uijiio/init_app/react_init_app.git ssh:gite.coding.net:uijiio/init_app/react_init_app.git 目前更新至:登录与主页跳转&#xff0c;主页包含菜单和容器区 一、搭建基础空白React项目 1.准备…...

【专题】2024年悦己生活消费洞察报告汇总PDF洞察(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p38654 在当今时代背景下&#xff0c;社会发展日新月异&#xff0c;人们的生活方式与消费观念正经历深刻变革。MoonFox 月狐数据的《2024 年悦己生活消费洞察报告》聚焦于这一充满活力与变化的消费领域。随着就业、婚姻等社会压力的…...

Github——网页版上传文件夹

第一步&#xff1a;创建一个新的仓库或进入已存在的仓库页面 第二步&#xff1a;点进对应的文件夹下&#xff0c;然后 点击 “Upload files” 第三步&#xff1a;将文件夹拖拽到上传区域 打开资源管理器&#xff0c;将要上传的文件夹从计算机中拖拽到上传区域。 注意&#xf…...

LMDeploy 量化部署进阶实践

1 配置LMDeploy环境 1.1 InternStudio开发机创建与环境搭建 打开InternStudio平台&#xff0c;进入如下界面创建环境 在终端中&#xff0c;让我们输入以下指令&#xff0c;来创建一个名为lmdeploy的conda环境&#xff0c;python版本为3.10&#xff0c;创建成功后激活环境并安…...

MFC/C++学习系列之简单记录9——简单加法

MFC/C学习系列之简单记录9——简单加法 前言界面设计控件添加添加变量添加事件 后台代码总结 前言 基本的一些使用已经了解&#xff0c;那么就做个简单的加法来练手吧&#xff01; 界面设计 控件添加 在工具箱中选择Edit control和Static Text两个控件&#xff0c;分别设置为…...

二分查找题目:两球之间的磁力

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;两球之间的磁力 出处&#xff1a;1552. 两球之间的磁力 难度 5 级 题目描述 要求 在代号为地球 C-137 的世界中&#xff0c;Rick 发现如果他将两个…...

OpenCV相机标定与3D重建(28)估计两个三维点集之间的最优平移变换函数estimateTranslation3D()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算两个3D点集之间的最优平移。 它计算 [ x y z ] [ X Y Z ] [ b 1 b 2 b 3 ] \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} \begin{bmatri…...

UE5仿漫威争锋灵蝶冲刺技能

这两天玩了一下漫威争锋Marvel Rivals&#xff0c;发现是UE5做的&#xff0c;对里面一些角色技能挺感兴趣的&#xff0c;想简单复刻一下技能功能&#xff0c;顺便复习一下学过的知识 首先把摄像机设置调整一下 CameraBoom里搜索lag 把摄像机延迟关掉 &#xff0c;这样摄像机就…...

CSS盒子模型(溢出隐藏,块级元素和行级元素的居中对齐,元素样式重置)

overflow&#xff1a;值 规定了内容溢出元素框时所发生的事情 visible&#xff1a;内容不会被修剪&#xff0c;会显示在元素框之外&#xff0c;默认值 overflow: visible; hidden&#xff1a;内容会被修剪&#xff0c;溢出内容不可见 overflow: hidden; scroll&#xff1a;内…...

语音增强的损失函数选择

一、最优尺度不变信噪比&#xff08;OSISNR&#xff09;损失函数 参考&#xff1a;论文解读 --Optimal scale-invariant signal-to-noise ratio and curriculum learning for monaural multi-spea   最优尺度不变信噪比&#xff08;OSI-SNR&#xff09;是一种用于评估信号质量…...

【python自动化六】UI自动化基础-selenium的使用

selenium是目前用得比较多的UI自动化测试框架&#xff0c;支持java&#xff0c;python等多种语言&#xff0c;目前我们就选用selenium来做UI自动化。 1.selenium安装 安装命令 pip install selenium2.selenium的简单使用 本文以chrome浏览器为例&#xff0c;配套selenium中c…...

【习题答案】让您的应用拥有领先的位置服务能力

判断题 1.在使用&#xff08;逆&#xff09;地理编码前&#xff0c;需要使用isGeocoderAvailable检查服务状态。 正确(True) 错误(False) 2.当同时配置定位场景和优先级策略时&#xff0c;会优先使用优先级策略。 正确(True) 错误(False) 单选题 1.获取精准定位需要申请哪个权…...

java中list和map区别

在Java中&#xff0c;List和Map是两种不同类型的集合接口&#xff0c;它们用于不同的场景并且具有不同的特性和用途。以下是List和Map的主要区别&#xff1a; 1. 数据结构 List&#xff1a;是一个有序的集合&#xff0c;允许重复元素。它实现了Collection接口&#xff0c;并且…...

java后端传时间戳给前端的三种方式

一. 后端传时间戳给前端的几种方式 使用System.currentTimeMillis() 这是最简单的方式&#xff0c;返回自1970年1月1日&#xff08;UTC&#xff09;以来的毫秒数&#xff0c;可以直接传递给前端。 long timestamp1 System.currentTimeMillis();使用java.time.Instant Java…...

【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…...

oracle: create new database

用database configuration Assistant 引导创建数据库。记得给system,sys 设置自己的口令&#xff0c;便于添加新操作用户。 创建操作用户&#xff1a; -- 别加双引号&#xff0c;否则&#xff0c;无法用 create user geovindu identified by 888888; create user geovin identi…...