K8S 启动探测、就绪探测、存活探测
先来思考一个问题:
在 Deployment 执行滚动更新 web 应用的时候,总会出现一段时间,Pod 对外提供网络访问,但是页面访问却发生404,这个问题要如何解决呢?学完今天的内容,相信你会有自己的答案。
一、理论介绍
1.1、探测类型(探针类型)
官网介绍如下:
探测或者探针都可以,英文都是 probe:
1、启动探测 startupProbe
- 检查容器内的应用是否已启动。
- 如果配置了启动探测,它会禁用存活探测和就绪探测,直到启动探测成功为止。
- 如果启动探测失败,kubelet 会将容器杀死,并依据容器重启策略进行重启。
- 如果容器没有提供启动探测,则默认状态为 Success(成功)。
- 这类探针仅在启动时执行,不像存活探针和就绪探针那样周期性地运行。
2、就绪探测 readinessProbe
- 决定何时容器准备好开始接受流量。
- 如果就绪探测失败,kubelet 会将该 Pod 从所有对应服务的端点(endpoint)中移除。
- 如果容器没有提供就绪探测,则默认状态为 Success(成功)。
3、存活探测 livenessProbe
- 检测容器是否正常运行。
- 如果一个容器的存活探针失败多次,kubelet 将依据容器重启策略进行重启。
- 如果容器没有提供存活探测,则默认状态为 Success(成功)。
注意的点:
- 启动探测 和 存活探测 都有可能重启容器。
- 启动探测只运行一次,就绪探测跟存活探测周期性地运行着。
- 存活探测 跟 就绪探测 是并行的。
- 如果三个都配置,启动顺序:
- 就绪探测 和 存活探测的区别
readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。 livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。
1.2、探测结果
1.3、检查机制(探测模式)
检查机制三种探针都一样,都有四种:
(因为三种探针都是 go 语言 Probe类型,所以它们探针类型都一样)
1、exec
- 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
2、grpc
- 使用 gRPC 执行一个远程过程调用。
3、httpGet
- 对容器的 IP 地址上指定端口和路径执行 HTTP
GET
请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。4、tcpSocket
- 对容器的 IP 地址上的指定端口执行 TCP 检查。如果能够建立 TCP 连接,则表明容器健康。
1.4、探针属性介绍
探针主要属性介绍:
(因为三种探针都是 go 语言 Probe 类型,所以它们属性都一样)
kubectl explain pod.spec.containers.startupProbe
其中,exec、grpc、httpGet、tcpSocket 是检查机制,就不多说了。
1、failureThreshold
- 连续探测失败多少次,会被认为是失败。默认值是 3,最小值为 1。
2、initialDelaySeconds
- 容器启动多少秒,探针才开始工作。
3、periodSeconds
- 执行探测的时间间隔(单位是秒),默认为 10s,单位“秒”,最小值是1
4、successThreshold
- 连续探测几次成功,才认为探测成功,默认为 1,在启动探针和存活探针中必须为1,最小值为1。
5、timeoutSeconds
- 探针执行检测请求后,等待响应的超时时间,默认为1,单位“秒”。
1.5、环境准备
假设有如下三个节点的 K8S 集群:
k8s31master 是控制节点
k8s31node1、k8s31node2 是工作节点
容器运行时是 containerd
1.5.1、镜像准备
docker pull tomcat:8.5-jre8-alpine
docker pull busybox:1.28
1.5.2、镜像导出
docker save -o tomcat-8.5-jre8-alpine.tar.gz docker.io/library/tomcat:8.5-jre8-alpine
docker save -o busybox-1.28.tar.gz docker.io/library/busybox:1.28
15.3、镜像导入工作节点 containerd
# k8s31node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep tomcat
[root@k8s31node1 ~]# ctr -n=k8s.io images import busybox-1.28.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep busybox# k8s31node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep tomcat
[root@k8s31node2 ~]# ctr -n=k8s.io images import busybox-1.28.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep busybox
说明:
- ctr 是 containerd 命令
- ctr images import:导入镜像
- -n=k8s.io:K8S 镜像存储命名空间
三、启动探测 startupProbe
3.1、exec 模式
3.1.1、探测成功
- pod-startupprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-exec
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:exec:command:- "/bin/sh"- "-c"- "ps -ef|grep tomcat"initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3
initialDelaySeconds:容器启动后多久才开始探测,这里为了演示方便,故意调成 20 秒。实际业务,需要根据服务启动的平均时间来设置。假设容器启动要 10 秒,initialDelaySeconds 设置为 5 秒,太早探测,容易多次探测失败。
initialDelaySeconds 设置为 20 秒,则容易空等,不利于服务的吞吐。
periodSeconds:执行探测的时间间隔为 20 秒。
timeoutSeconds:探针执行检测请求后,等待响应的超时时间为 10 秒。
successThreshold:连续探测 1 次成功,才认为探测成功。所以如果成功,会执行 2 次探测。
failureThreshold:连续探测失败 3 次,才认为是失败。
command:要在容器里面执行的命令行。
- /bin/sh:因为有 | 管道操作,所以需要显示地调起 shell 解释器。
- -c:command 的意思,后接命令行字符串。
- ps -ef|grep tomcat:打印出 tomcat 进程信息。
- 整个命令其实是在容器中执行 /bin/sh -c "ps -ef|grep tomcat"
- 执行并监控
kubectl apply -f pod-startupprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
运行 5s 的时候,K8S 已经确认并创建 Pod,但是这个时候,启动探测还没通过,Pod 没有一个容器 READY。20s 的时候,第一次启动探测,因为需要连续两次成功,才算成功,所以间隔 20s 又探测一次,整个 Pod 启动,用时 40s。
- 查看 pod 事件
kubectl describe pod pod-startupprobe-exec
会发现启动探测的信息在这里。
3.1.2、探测失败(容器重启)
- 删除原来 pod 并修改 yaml 文件
kubectl delete -f pod-startupprobe-exec.yaml
vim pod-startupprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-exec
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:exec:command:- "false"initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3
command:
- "false" # 这一行返回非0的状态,启动探测会失败。
- 执行并监控
kubectl apply -f pod-startupprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
可以看到容器在不停地重启,RESTARTS 在不停增加。
这是因为我们容器 pod.spec.containers.restartPolicy 默认为 Always。
倘若大家配置为 Never,那它就不重启了,这个大家可以试一下。
- 查看 pod 事件
kubectl describe pod pod-startupprobe-exec
可以看到,K8S 会提示,启动探测失败。
- 删除 pod
kubectl delete -f pod-startupprobe-exec.yaml
3.2、tcpSocket 模式
- pod-startupprobe-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-tcpsocket
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:tcpSocket:port: 8080initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3
tcpSocket 有两个参数:
- host:默认 pod IP。也就是下图 10.244.165.44
- port:必填,容器端口。
tcpSocket 类似于执行一个 telnet 10.244.165.44 8080
tomcat 也是能接收 tcp 请求的,因为 tomcat 底层用的 socket 连接。
kubectl explain pod.spec.containers.startupProbe.tcpSocket
- 执行并监控
kubectl apply -f pod-startupprobe-tcpsocket.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
- 删除 pod
kubectl delete -f pod-startupprobe-tcpsocket.yaml
3.3、httpGet
- pod-startupprobe-httpget.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-httpget
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:httpGet:path: /port: 8080initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3
httpGet 有三个重要参数:
- host:默认 pod IP。也就是下图 10.244.165.45
- path:我们服务定义的路径,像 tomcat 就是根路径 /
- port:必填,容器端口。
httpGet 类似于执行一个 curl http://10.244.165.45:8080/
kubectl explain pod.spec.containers.startupProbe.httpGet
- 执行并监控
kubectl apply -f pod-startupprobe-httpget.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
- 删除 pod
kubectl delete -f pod-startupprobe-httpget.yaml
四、存活探测 livenessProbe
4.1、exec 模式(容器重启)
我们来看一个 K8S 官网的例子 pod-livenessprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-exec
spec:containers:- name: livenessimage: busybox:1.28imagePullPolicy: IfNotPresentargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5
args:容器启动的时候执行命令
- /bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"
- 容器启动的时候创建一个 /tmp/healthy 文件,然后睡眠 30 秒,到时间后删除文件 /tmp/healthy。接着睡眠 600 秒,防止容器退出。
command:
- kubelet 在容器内执行命令
cat /tmp/healthy
来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。- 这个容器生命的前 30 秒,
/tmp/healthy
文件是存在的。 所以在这最开始的 30 秒内,执行命令cat /tmp/healthy
会返回成功代码。 30 秒之后,执行命令cat /tmp/healthy
就会返回失败代码。
- 执行并监控
kubectl apply -f pod-livenessprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
前 30 秒因为文件 /tmp/healthy 存在,存活探针探测成功。我们设置的探测间隔 periodSeconds 是 5 秒,所以在第 35 秒的时候,存活探针探测失败,又因为 failureThreshold 失败阈值我们没有设置,默认是 3,所以又要再探测 2 次,再加 10 秒,差不多 45 秒,这个时候 Pod 开始重启。
- 在 30 秒内,查看 Pod 的事件
kubectl describe pod pod-livenessprobe-exec
探测成功。
- 35 秒之后,再来看 Pod 的事件
kubectl describe pod pod-livenessprobe-exec
探测失败。45 秒的时候,容器开始重启。从这边也能看出,存活探针是周期性启动的。
- 删除 pod
kubectl delete -f pod-livenessprobe-exec.yaml
4.2、httpGet 模式
我们来看一个官方的例子。
4.2.1、镜像拉取
由于国内无法访问 registry.k8s.io,所以我找了一个镜像中转站。
docker pull myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40
# 查看是否下载完成
docker images | grep agnhost
4.2.2、镜像导出
docker save -o agnhost-2.40.tar.gz myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40
4.2.3、镜像导入工作节点 containerd
# k8s31node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import agnhost-2.40.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep agnhost# k8s31node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import agnhost-2.40.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep agnhost
4.2.4、Demo 演示
pod-livenessprobe-httpget.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-http
spec:containers:- name: livenessimage: myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40imagePullPolicy: IfNotPresentargs:- livenesslivenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 2periodSeconds: 2
- args:容器启动时设置参数 liveness。
initialDelaySeconds
字段告诉 kubelet 在执行第一次探测前应该等待 2 秒。periodSeconds
字段指定了 kubelet 每隔 2 秒执行一次存活探测。- kubelet 会向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。 如果服务器上
/healthz
路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。- 返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。
容器内服务的源码:容器存活期间的最开始 10 秒钟,/healthz
处理程序返回 200 的状态码。之后处理程序返回 500 的状态码。
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {duration := time.Now().Sub(started)if duration.Seconds() > 10 {w.WriteHeader(500)w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))} else {w.WriteHeader(200)w.Write([]byte("ok"))}
})
kubelet 在容器启动之后 2 秒开始执行健康检查。所以前几次健康检查都是成功的。 但是 10 秒之后,健康检查会失败,并且 kubelet 会杀死容器再重新启动容器。
- 执行并监控
kubectl apply -f pod-livenessprobe-httpget.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
- 在 10 秒内,查看 Pod 的事件
kubectl describe pod pod-livenessprobe-http
- 10 秒之后,再来看 Pod 的事件
kubectl describe pod pod-livenessprobe-http
存活探针已经失败,并且容器被重新启动了。
4.2.5、删除 pod
kubectl delete -f pod-livenessprobe-httpget.yaml
4.3、tcpSocket 模式
pod-livenessprobe-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-tcp
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 5
- 执行并监控
kubectl apply -f pod-livenessprobe-tcpsocket.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
- 进入容器,关闭 tomcat
[root@k8s31master ~]# kubectl exec -it pod-livenessprobe-tcp -- /bin/bash
# 关闭 tomcat
bash-4.4# /usr/local/tomcat/bin/shutdown.sh
关闭 tomcat 之后,容器状态为 Completed,然后 kubelet 检测到容器 8080 端口没有存活,重启容器。
- 删除 pod
kubectl delete -f pod-livenessprobe-tcpsocket.yaml
五、就绪探测 readinessProbe
5.1、exec 模式(容器不会重启)
pod-readinessprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-readinessprobe-exec
spec:containers:- name: readinessimage: busybox:1.28imagePullPolicy: IfNotPresentargs:- /bin/sh- -c- sleep 20; touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600readinessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5
args:容器启动的时候执行命令
- /bin/sh -c "sleep 20; touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600"
- 容器启动的时候先睡眠 20 秒,到时间后创建一个 /tmp/healthy 文件,然后睡眠 10 秒,到时间后删除文件 /tmp/healthy。接着睡眠 600 秒,防止容器退出。
command:
- kubelet 在容器内执行命令
cat /tmp/healthy
来进行探测。如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是就绪的,可以对外提供服务。 如果这个命令返回非 0 值,kubelet 会隔 5 秒重新探测。- 这个容器生命的前 20 秒,
/tmp/healthy
文件是不存在的。所以在这最开始的 20 秒内,执行命令cat /tmp/healthy
会返回失败代码,容器 READY 个数为 0 。20 秒之后,执行命令cat /tmp/healthy
就会返回成功代码,这个时候容器 READY 个数就会变为 1。再过了 10 秒,/tmp/healthy
文件被删除,就绪探测失败,容器 READY 个数重新变为 0,然后隔 5 秒重新探测一次。在整个过程中,容器不会重启。
- 执行并监控
kubectl apply -f pod-readinessprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
因为 readinessProbe 不会重启,所以经常要跟 livenessProbe 搭配使用。
- 在 20 秒内,查看 Pod 的事件
kubectl describe pod pod-readinessprobe-exec
- 20 秒到 30 秒,查看 Pod 的事件
kubectl describe pod pod-readinessprobe-exec
- 30 秒以后,查看 Pod 的事件
kubectl describe pod pod-readinessprobe-exec
实际的 Age 时间与我们预期的会有一些出入。不过监控 -w 里面的时间,跟我们分析的是吻合的。
- 删除 pod
kubectl apply -f pod-readinessprobe-exec.yaml
5.2、httpGet 模式
pod-readinessprobe-http.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-readinessprobe-http
spec:containers:- name: readinessimage: myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40imagePullPolicy: IfNotPresentargs:- livenessreadinessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 5periodSeconds: 3
- 执行并监控
kubectl apply -f pod-readinessprobe-http.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思
就绪探测 5 秒之后开始,容器存活期间的最开始 10 秒钟,
/healthz
处理程序返回 200 的状态码,容器 READY 变为 1/1。之后容器内处理程序返回 500 的状态码,容器 READY 变为 0/1,之后每隔 3 秒重新探测一次。
- 删除 pod
kubectl delete -f pod-readinessprobe-http.yaml
六、开头问题解答
在 Deployment 执行滚动更新的时候,总会出现一段时间,Pod 对外提供网络访问,但是访问却发生404,这个问题要如何解决呢?
问题的原因,是因为 Pod 已经成功启动,但是 Pod 内的容器中应用程序还在启动中导致。
可以使用就绪探针,去检测系统中,页面元素适中、接口响应时间在平均时间的页面或接口,使用 httpGet 模式去探测它,成功了才加到系统 EndPoint 中。
相关文章:
K8S 启动探测、就绪探测、存活探测
先来思考一个问题: 在 Deployment 执行滚动更新 web 应用的时候,总会出现一段时间,Pod 对外提供网络访问,但是页面访问却发生404,这个问题要如何解决呢?学完今天的内容,相信你会有自己的答案。 …...
rust学习-rust中的保留字
rust学习-rust中的保留字 已使用的保留字未来可能使用的保留字 保留字是语言中预定义的标识符,不能用作变量名、函数名或其他自定义标识符,Rust的保留字大致可以分为两类:已使用的保留字和未来可能使用的保留字 已使用的保留字 as࿱…...
-bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录
终端报错: -bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录原因:由于文件行尾符不匹配导致的。当脚本文件在Windows环境中创建或编辑后,行尾符为CRLF(即回车和换行,\r\n)…...
【C】memory 详解
<memory.h> 是一个 C 标准库头文件,提供了一组内存管理函数,用于分配、释放和操作动态内存。这些函数主要操作的是未初始化的内存块,是早期 C 编程中常用的内存操作工具。 尽管在现代 C 编程中更推荐使用<cstring>或<memory&…...
Android实训九 数据存储和访问
实训9 数据存储和访问 一、【实训目的】 1、 SharedPreferences存储数据; 2、 借助Java的I/O体系实现文件的存储, 3、使用Android内置的轻量级数据库SQLite存储数据; 二、【实训内容】 1、实现下图所示的界面,实现以下功能: 1ÿ…...
Redis vs. 其他数据库:深度解析,如何选择最适合的数据库?
一、如何为项目选择合适的数据库? 选择合适的数据库是一个复杂的过程,需要综合考虑多个因素。下面几个维度来详细阐述: 1.数据模型 关系型数据库(RDBMS):适用于高度结构化、关联性强的数据,如电…...
docker 安装 mysql 详解
在平常的开发工作中,我们经常需要用到 mysql 数据库。那么在docker容器中,应该怎么安装mysql数据库呢。简单来说,第一步:拉取镜像;第二步:创建挂载目录并设置 my.conf;第三步:启动容…...
C++实现设计模式---桥接模式 (Bridge)
桥接模式 (Bridge) 桥接模式 是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立变化。桥接模式的核心思想是使用组合(而非继承)来扩展功能。 意图 将抽象部分与实现部分分离,使它们都可以独立地变…...
LangChain + llamaFactory + Qwen2-7b-VL 构建本地RAG问答系统
单纯仅靠LLM会产生误导性的 “幻觉”,训练数据会过时,处理特定知识时效率不高,缺乏专业领域的深度洞察,同时在推理能力上也有所欠缺。 正是在这样的背景下,检索增强生成技术(Retrieval-Augmented Generati…...
pycharm 运行远程环境问题 Error:Failed to prepare environment.
问题排查 拿到更详细的报错信息: Help > Diagnostic Tools > Debug Log Settings section: 添加下面的配置 com.intellij.execution.configurations.GeneralCommandLine 重显报错,我这里是再次运行代码打开 Help | Collect Logs and Diagnosti…...
Level2逐笔成交逐笔委托毫秒记录:今日分享优质股票数据20250124
逐笔成交逐笔委托下载 链接: https://pan.baidu.com/s/1UWVY11Q1IOfME9itDN5aZA?pwdhgeg 提取码: hgeg Level2逐笔成交逐笔委托数据分享下载 通过Level2逐笔成交与逐笔委托的详细数据,这种以毫秒为单位的信息能揭示许多关键点,如庄家意图、误导性行为…...
最新最详细的配置Node.js环境教程
配置Node.js环境 一、前言 (一)为什么要配置Node.js?(二)NPM生态是什么(三)Node和NPM的区别 二、如何配置Node.js环境 第一步、安装环境第二步、安装步骤第三步、验证安装第四步、修改全局模块…...
【Address Overfitting】解决过拟合的三种方法
目录 1. 收集更多数据实践方法:适用场景:优缺点: 2. 特征选择方法介绍:实践示例:适用场景:优缺点: 3. 正则化(Regularization)正则化类型:实践示例࿱…...
【缘于J2ME】
我与 J2ME 的不解之缘 那年我 25 岁,如今已即将退休。 在那个娱乐生活并不丰富的年代,每每响起「小霸王其乐无穷啊」,小伙伴们就会摩拳擦掌、轮番上阵,而我却痴迷于 G-BASIC 编程。 最大的乐趣就是对着仅有的两页说明,…...
c#使用log4Net配置日志文件
1.# 写一个通用类 LogHelper using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using log4net;namespace WindowsFormsApplication22 {public class LogHelper{static ILog mylog LogManager.GetLogge…...
[ACTF2020 新生赛]Include1
题目 点击tips后: 使用PHP伪协议直接读取flag /?filephp://filter/readconvert.base64-encode/resourceflag.php base64解码 拿下flag flag{6cce5a3d-997a-4c8a-ba07-f6652ee462a9}...
【数据结构】树的基本:结点、度、高度与计算
树是数据结构中一种重要的非线性结构,广泛应用于计算机科学的各个领域,例如文件系统、数据库索引、编译器等。理解树的各种性质,如结点数、度、高度等,对于解决实际问题至关重要。 本文将会探讨树的基本概念,以及给出几…...
1.24 共享内存和信号灯集
使用共享内存信号灯集实现两个进程之间相互对话。 程序代码: #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stst.h> #include <fcntl.h> #…...
正则表达式以及Qt中的使用
目录 一、正则表达式 1、基本匹配: 2、元字符: 2.1 .运算符: 2.2 字符集: 2.3 重复次数: 2.4 量词{} 2.5 特征标群() 2.6 或运算符 2.7 \反斜线转码特殊字符 2.8 锚点 3、简写字符 4、零宽度断言 4.1 正…...
STM32简介
STM32简介 STM32是ST公司基于ARMCortex-M内核开发的32位微控制器 (Microcontroller) MCU微控制器、MPU微处理器、CPU中央处理器 1.应用领域 STM32常应用于嵌入式领域。 如智能车:循迹小车 读取光电传感器或者摄像头的数据,…...
【设计模式-行为型】访问者模式
一、什么是访问者模式 说起来访问者模式,其实很少用。我一直在思考该用什么样的例子把这个设计模式表述清晰,最近突然想到一个例子也许他就是访问者。港片有过很辉煌的年代,小的时候一直在看港片觉得拍的非常好,而且演员的演技也在…...
上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天冲高回落,深成指、创业板指午后翻绿。大金融板块全天强势,天茂集团…...
docker部署jenkins
环境: centos7.9 jenkins/jenkins:lts-jdk11 1、拉去jenkins镜像,请指明版本号 [rootlocalhost ~]# docker pull jenkins/jenkins:lts 开始拉取 拉取完成 [rootlocalhost ~]# docker pull jenkins/jenkins:lts lts: Pulling from jenkins/jenkins 0a9…...
初阶数据结构:链表(二)
目录 一、前言 二、带头双向循环链表 1.带头双向循环链表的结构 (1)什么是带头? (2)什么是双向呢? (3)那什么是循环呢? 2.带头双向循环链表的实现 (1)节点结构 (2…...
Django实现数据库的表间三种关系
Django实现数据库的表间三种关系 1. 一对多(One-to-Many)关系示例:关系说明:查询示例: 2. 一对一(One-to-One)关系示例:关系说明:查询示例: 3. 多对多&#x…...
AI导航工具我开源了利用node爬取了几百条数据
序言 别因今天的懒惰,让明天的您后悔。输出文章的本意并不是为了得到赞美,而是为了让自己能够学会总结思考;当然,如果有幸能够给到你一点点灵感或者思考,那么我这篇文章的意义将无限放大。 背景 随着AI的发展市面上…...
概率密度函数(PDF)分布函数(CDF)——直方图累积直方图——直方图规定化的数学基础
对于连续型随机变量,分布函数(Cumulative Distribution Function, CDF)是概率密度函数(Probability Density Function, PDF)的变上限积分,概率密度函数是分布函数的导函数。 如果我们有一个连续型随机变量…...
OpenHarmony OTA升级参考资料记录
OpenHarmony 作为一个开源分布式操作系统,通过其强大的 OTA(Over-The-Air)升级能力,为开发者和厂商提供了一套灵活而安全的系统升级方案。 OTA升级方式 根据升级包的应用方式,OpenHarmony 的 OTA 升级可以分为两种:本地升级和网络OTA升级。 本地升级 本地升级是将已制作…...
从 Spark 到 StarRocks:实现58同城湖仓一体架构的高效转型
作者:王世发,吴艳兴等,58同城数据架构部 导读: 本文介绍了58同城在其数据探查平台中引入StarRocks的实践,旨在提升实时查询性能。在面对传统Spark和Hive架构的性能瓶颈时,58同城选择StarRocks作为加速引擎&…...
网络知识小科普--5
81、什么是组播路由? 组播路由是一种有针对性的广播形式,将消息发送到所选择的用户组,而不是将其发送到子网上的所有用户。 82、加密在网络上的重要性是什么? 加密是将信息转换成用户不可读的代码的过程。然后使用秘密密钥或密码将其翻译或解密回其…...
【JWT】jwt实现HS、RS、ES、ED签名与验签
JWT 实现 HS、RS、ES 和 ED 签名与验签 签名方式算法密钥类型签名要点验签要点HSHMAC-SHA256对称密钥- 使用 crypto/hmac 和对称密钥生成 HMAC 签名- 将 header.payload 作为数据输入- 使用同一密钥重新计算 HMAC 签名- 比较计算结果与接收到的签名是否一致RSRSA-SHA256公钥 …...
cherry USB 键盘分析
文章目录 cherry USB 键盘分析描述符结构设备描述符配置描述符集合配置描述符接口 1 描述符HID 描述符端点 IN 描述符接口 2 描述符HID 描述符端点 IN 描述符端点 OUT 描述符字符串描述符语言 ID (字符串索引为 0)厂商字符串(字符串索引为 1)产品字符串(字符串索引为 2)HID 报告…...
R语言学习笔记之高效数据操作
一、概要 数据操作是R语言的一大优势,用户可以利用基本包或者拓展包在R语言中进行复杂的数据操作,包括排序、更新、分组汇总等。R数据操作包:data.table和tidyfst两个扩展包。 data.table是当前R中处理数据最快的工具,可以实现快…...
高阶C语言|数组名的深度解析(数组名结合sizeof与strlen的详解)
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴…...
Vue3 v-bind 和 v-model 对比
1. 基本概念 1.1 v-bind 单向数据绑定从父组件向子组件传递数据简写形式为 : 1.2 v-model 双向数据绑定父子组件数据同步本质是 v-bind 和 v-on 的语法糖 2. 基础用法对比 2.1 表单元素绑定 <!-- v-bind 示例 --> <template><input :value"text&quo…...
科家多功能美发梳:科技赋能,重塑秀发新生
在繁忙的都市生活中,头皮健康与秀发养护成为了现代人不可忽视的日常课题。近日,科家电动按摩梳以其卓越的性能和创新设计,赢得了广大消费者的青睐。这款集科技与美学于一身的美发梳,不仅搭载了2亿负离子、6000次/分钟的声波振动等前沿技术,更融入了650nm聚能环红光与415nm强劲蓝…...
systemverilog中的force,release和assign
1 assign assign 语句用于为 wire 类型的信号提供连续赋值。它建立了一个驱动源,根据右侧表达式的值持续驱动 wire 信号。 module Example;wire a, b, c;assign c a & b; endmodule 2 force force 用于强制将一个信号的值设定为某个特定值,会覆盖…...
9【如何面对他人学习和生活中的刁难】
我们在学习的过程中,会遇到很多来自于他人的刁难与嘲讽,如果处理不好,这会大大影响我们的心情,从而影响学习的效率 我建议,如果你学习或生活中也遇到了类似的问题,不要去生气,更不要发生冲突&a…...
新项目传到git步骤
1.首先创建远程仓库,创建一个空白项目,即可生成一个克隆URL,可以是http也可以是SSH,copy下这个地址 2.找到项目的本机目录,进入根目录,打开git bash here命令行 3.初始化: git init 4.关联远程地址: git remote add origin "远程仓库的URL" 5.查看关联 git re…...
docker搭建redis集群(三主三从)
本篇文章不包含理论解释,直接开始集群(三主三从)搭建 环境 centos7 docker 26.1.4 redis latest (7.4.2) 服务器搭建以及环境配置 请查看本系列前几篇博客 默认已搭建好三个虚拟机并安装配置好docker 相关博客…...
DDD架构实战第七讲总结:分层模型和代码组织
云架构师系列课程之DDD架构实战第七讲总结:分层模型和代码组织 一、引言 在前几讲中,我们介绍了领域驱动设计(DDD)的基本构造块和生命周期模型中的聚合。本讲将重点讨论如何将这些构造块和代码组织起来,探讨分层架构和六边形模型,以及如何组织代码结构。 二、工厂和资…...
LabVIEW太阳能照明监控系统
在公共照明领域,传统的电力照明系统存在高能耗和维护不便等问题。利用LabVIEW开发太阳能照明监控系统,通过智能控制和实时监测,提高能源利用效率,降低维护成本,实现照明系统的可持续发展。 项目背景 随着能源危机…...
C# 结构体
总目录 前言 在 C# 编程中,结构体(struct)是一种非常重要的数据结构,它为我们提供了一种轻量级的存储和操作数据的方式。本教程将带你深入了解结构体的概念、特点、使用方法,以及一些使用结构体的最佳实践。 一、什么…...
C++小病毒-1.0勒索(更新次数:1)
内容供学习使用,不得转卖,代码复制后请1小时内删除,此代码会危害计算机安全,谨慎操作 在C20环境下,并在虚拟机里运行此代码!,病毒带来后果自负! 使用时请删除在main()里的注释,并修改位置至C:\\(看我代码注释)//可以改成WIN Main() #include <iostream> #i…...
RabbitMQ---面试题
常见面试题 1.MQ的作用及应用场景 类似问题:项目什么情况下用到了MQ,为什么要用MQ MQ的主要应用场景,消息队列的应用场景,为什么说消息队列可以削峰 首先MQ是一种用来接收和转发消息的队列,常见的应用常见如下&…...
CSS中相对定位和绝对定位详解
文章目录 CSS中相对定位和绝对定位详解一、引言二、相对定位1、相对定位的概念1.1、代码示例 三、绝对定位1、绝对定位的概念1.1、代码示例 四、相对定位与绝对定位的区别五、使用示例六、总结 CSS中相对定位和绝对定位详解 一、引言 在CSS布局中,定位是一种强大的…...
【深度学习基础】多层感知机 | 权重衰减
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
[cg] 使用snapgragon 对UE5.3抓帧
最近想要抓opengl 的api,renderdoc在起应用时会闪退(具体原因还不知道),试了下snapgraon, 还是可以的 官网需要注册登录后下载,官网路径:Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…...
Java 集合框架介绍
Java学习资料 Java学习资料 Java学习资料 在 Java 编程中,集合框架是一个强大且常用的工具,它为存储和操作一组对象提供了统一的体系结构。通过集合框架,我们能够高效地管理数据,提升程序的灵活性和可维护性。 一、集合框架的概…...
【博客之星】2024年度创作成长总结 - 面朝大海 ,春暖花开!
没关系的,大家都会做错选择,会 莫名其妙掉眼泪,走在路上会突然崩溃, 但这并不影响我们去看看晚霞, 再次爱上这个世界。 面朝大海 ,春暖花开! about meReviewLife about me 现在我是一名24级计算机类的…...