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

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,这个问题要如何解决呢?学完今天的内容,相信你会有自己的答案。 …...

    2024年度总结——理想的风,吹进现实

    2024年悄然过去,留下了太多美好的回忆,不得不感慨一声时间过得真快啊!旧年风雪尽,新岁星河明。写下这篇博客,记录我独一无二的2024年。这一年,理想的风终于吹进现实! 如果用一句话总结这一年&am…...

    Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类

    前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能…...

    hadoop==docker desktop搭建hadoop

    hdfs map readuce yarn https://medium.com/guillermovc/setting-up-hadoop-with-docker-and-using-mapreduce-framework-c1cd125d4f7b 清理资源 docker-compose down docker system prune -f...

    Linux下的编辑器 —— vim

    目录 1.什么是vim 2.vim的模式 认识常用的三种模式 三种模式之间的切换 命令模式和插入模式的转化 命令模式和底行模式的转化 插入模式和底行模式的转化 3.命令模式下的命令集 光标移动相关的命令 复制粘贴相关命令 撤销删除相关命令 查找相关命令 批量化注释和去…...

    C25.【C++ Cont】初识运算符的重载和sort函数

    目录 1.为什么要引入运算符重载 2.运算符重载写法 格式 例子 示例代码 运行结果 3.sort函数 两种声明 声明1:默认情况 参数 示例代码1:排整型 示例代码2:排浮点数 ​编辑 示例代码3:排字符串 声明2:自定义情况 参数 comp比较函数的两种写法 写法1:创建比较函…...

    粒子群算法 笔记 数学建模

    引入: 如何找到全局最大值:如果只是贪心的话,容易被局部最大解锁定 方法有:盲目搜索,启发式搜索 盲目搜索:枚举法和蒙特卡洛模拟,但是样例太多花费巨量时间 所以启发式算法就来了,通过经验和规…...

    深入理解若依RuoYi-Vue数据字典设计与实现

    深入理解若依数据字典设计与实现 一、Vue2版本主要文件目录 组件目录src/components:数据字典组件、字典标签组件 工具目录src/utils:字典工具类 store目录src/store:字典数据 main.js:字典数据初始化 页面使用字典例子&#xf…...

    实战网络安全:渗透测试与防御指南

    📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 在数字化时代,网络安全已成为企业和个人不可忽视的重要课题。网络攻击的复杂性与日俱增,从数据泄露…...

    SpringBoot+Electron教务管理系统 附带详细运行指导视频

    文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1.查询课程表代码2.保存学生信息代码3.用户登录代码 一、项目演示 项目演示地址: 视频地址 二、项目介绍 项目描述:这是一个基于SpringBootElectron框架开发的教务管理系统。首先&#xff…...

    正在更新丨豆瓣电影详细数据的采集与可视化分析(scrapy+mysql+matplotlib+flask)

    文章目录 豆瓣电影详细数据的采集与可视化分析(scrapy+mysql+matplotlib+flask)写在前面数据采集0.注意事项1.创建Scrapy项目`douban2025`2.用`PyCharm`打开项目3.创建爬虫脚本`douban.py`4.修改`items.py`的代码5.修改`pipelines.py`代码6.修改`settings.py`代码7.启动`doub…...

    Ubuntu-手动安装 SBT

    文章目录 前言Ubuntu-手动安装 SBT1. SBT是什么?1.1. SBT 的特点1.2. SBT 的基本功能1.3. SBT 的常用命令 2. 安装2.1. 下载2.2. 解压 sbt 二进制包2.3. 确认 sbt 可执行文件的位置2.4. 设置执行权限2.5. 创建符号链接2.6. 更新 PATH 环境变量2.7. 验证 sbt 安装 前言 如果您觉…...

    详解最基本的数据顺序存储结构:顺序表

    新的一年,我觉得这张图很合适!有梦想,敢拼,马上就是除夕了,希望新的一年我们逢考必过,事事顺心,看见朝阳的你是不是嘴角微微上扬! 本篇从0基础白话文讲述顺序表的概念、用法、注意事…...

    STM32使用VScode开发

    文章目录 Makefile形式创建项目新建stm项目下载stm32cubemx新建项目IED makefile保存到本地arm gcc是编译的工具链G++配置编译Cmake +vscode +MSYS2方式bilibiliMSYS2 统一环境配置mingw32-make -> makewindows环境变量Cmake CmakeListnijia 编译输出elfCMAKE_GENERATOR查询…...

    前端react后端java实现提交antd form表单成功即导出压缩包

    前端&#xff08;React Ant Design&#xff09; 1. 创建表单&#xff1a;使用<Form>组件来创建你的表单。 2. 处理表单提交&#xff1a;在onFinish回调中发起请求到后端API&#xff0c;并处理响应。 import React from react; import { Form, Input, Button } from ant…...

    vue2中trhee.js加载模型展示天空盒子

    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/13b9193d6738428791fc1ff112e03627.png 加载模型的时候需要把模型放在public文件下面 创建场景 this.scene new THREE.Scene()创建相机 this.camera new THREE.PerspectiveCamera(45,this.viewNode.clientWidth / t…...

    安装Office自定义项,安装期间出错

    个人博客地址&#xff1a;安装Office自定义项&#xff0c;安装期间出错 | 一张假钞的真实世界 卸载PowerDesigner后&#xff0c;打开“WPS文字”时出现下图错误&#xff1a; 解决方法&#xff1a; 按“WinR”快捷键&#xff0c;打开【运行】框&#xff0c;在对话框中输入“re…...

    代码审查中的自动化与AI应用

    代码审查&#xff08;Code Review&#xff09;作为软件开发中的一项重要实践&#xff0c;通常被认为是提高代码质量、减少bug和提升团队协作的重要手段。随着开发规模的不断扩大&#xff0c;手动代码审查在效率、准确性、以及可扩展性上都存在明显的局限性。尤其是在敏捷开发和…...

    蓝桥杯模拟算法:蛇形方阵

    P5731 【深基5.习6】蛇形方阵 - 洛谷 | 计算机科学教育新生态 我们只要定义两个方向向量数组&#xff0c;这种问题就可以迎刃而解了 比如我们是4的话&#xff0c;我们从左向右开始存&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4 到5的时候y就大于4了就是越界了&…...

    PostGIS笔记:PostgreSQL 数据库与用户 基础操作

    数据库基础操作包括数据模型的实现、添加数据、查询数据、视图应用、创建日志规则等。我这里是在Ubuntu系统学习的数据库管理。Windows平台与Linux平台在命令上几乎无差异&#xff0c;只是说在 Windows 上虽然也能运行良好&#xff0c;但在性能、稳定性、功能扩展等方面&#x…...

    Nginx中部署多个前端项目

    1&#xff0c;准备前端项目 tlias系统的前端资源 外卖项目的前端资源 2&#xff0c;nginx里面的html文件夹中新建&#xff0c;tlias和sky两个文件夹。 切记这是在nginx/html下创建的 mkdir sky mkdir tlias 把tlias和sky的资源都放到对应的文件夹中 3&#xff0c;编辑配置ngi…...

    人力资源管理HR系统的需求设计和实现

    该作者的原创文章目录&#xff1a; 生产制造执行MES系统的需求设计和实现 企业后勤管理系统的需求设计和实现 行政办公管理系统的需求设计和实现 人力资源管理HR系统的需求设计和实现 企业财务管理系统的需求设计和实现 董事会办公管理系统的需求设计和实现 公司组织架构…...

    2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文

    模型设计思路与创新点&#xff1a; 建模的时候应该先确定我们需要建立什么类的模型&#xff1f;优化类还是统计类&#xff1f;这个题需要大量的数据分析&#xff0c;因此我们可以建立一个统计学模型。 统计学建模思路&#xff1a;观察规律&#xff0c;建立模型&#xff0c;参…...

    【太阳——几何计算】

    题目 代码 #include <bits/stdc.h> using namespace std; using PII pair<int, int>; using ll long long; const int N 1e5 10; set<PII> s; bool st[N]; struct node {int x, y, id; } arr[2 * N]; int main() {int n, X, Y;cin >> n >> …...

    嵌入式MCU面试笔记2

    目录 串口通信 概论 原理 配置 HAL库代码 1. 初始化函数 2. 数据发送和接收函数 3. 中断和DMA函数 4. 中断服务函数 串口通信 概论 我们知道&#xff0c;通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。 比较常见的串…...

    云原生时代,如何构建高效分布式监控系统

    文章目录 一.监控现状二.Thanos原理分析SidecarQuerierStoreCompactor 三.Sidecar or ReceiverThanos Receiver工作原理 四.分布式运维架构 一.监控现状 Prometheus是CNCF基金会管理的一个开源监控项目&#xff0c;由于其良好的架构设计和完善的生态&#xff0c;迅速成为了监控…...

    mysql从全备文件中提取单库或单表进行恢复——筑梦之路

    前提条件 与业务确认涉及业务、数据库IP、数据误删除时间点、数据删除涉及的SCHEMA、数据表&#xff0c;确认该数据库为MySQLdump备份方式&#xff0c;备份策略为每日凌晨1点进行数据库全备份&#xff0c;备份保留7天&#xff0c;业务误删除数据时间点为当日10点左右&#xff0…...

    渗透测试技法之口令安全

    一、口令安全威胁 口令泄露途径 代码与文件存储不当&#xff1a;在软件开发和系统维护过程中&#xff0c;开发者可能会将口令以明文形式存储在代码文件、配置文件或注释中。例如&#xff0c;在开源代码托管平台 GitHub 上&#xff0c;一些开发者由于疏忽&#xff0c;将包含数据…...

    火语言RPA--配置文件读取

    &#x1f6a9;【组件功能】&#xff1a;读取配置文件信息以字典类型输出。 配置预览 配置说明 要读取的文件 支持T或# 读取配置文件的路径及名称&#xff0c;绝对路径。 配置文件类型 INI或XML两种选项供选择。 编码 写入配置文件的编码&#xff0c;以列表方式供选择&am…...

    电子应用设计方案104:智能家庭AI弹簧床系统设计

    智能家庭 AI 弹簧床系统设计 一、引言 智能家庭 AI 弹簧床系统旨在为用户提供更加舒适、个性化的睡眠体验&#xff0c;通过结合人工智能技术和先进的床垫设计&#xff0c;实时监测和调整睡眠环境&#xff0c;以满足不同用户的需求。 二、系统概述 1. 系统目标 - 自动适应用户…...