【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA)

news2024/12/25 0:28:58

【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA)

什么是弹性伸缩

「Autoscaling即弹性伸缩,是Kubernetes中的一种非常核心的功能,它可以根据给定的指标(例如 CPU 或内存)自动缩放Pod副本,从而可以更好地管理和利用计算资源,提高系统的可用性和性能,同时减少开销和成本。弹性伸缩可以解决服务负载存在较大波动或资源实际使用与预估之间的差距。」

在Kubernetes集群中提供了三种弹性伸缩技术:

  • 「CA(Cluster Autoscaler)」:Node级别自动扩/缩容

  • 「HPA(Horizontal Pod Autoscaler)」:Pod个数自动扩/缩容

  • 「VPA(Vertical Pod Autoscaler)」:Pod配置自动扩/缩容,主要是CPU、内存配置

「Node自动扩/缩容」

Cluster AutoScaler定期检测是否有充足的资源来调度新创建的Pod,当资源不足时会调用Cloud Provider创建新的Node。Cluster AutoScaler也会定期监测 Node的资源使用情况,当一个Node长时间资源利用率都很低时(低于50%)自动将其所在虚拟机从集群中删除。此时,原来的Pod会自动调度到其他Node上面。

Node的增减可能会影响整个kubernetes集群的稳定性,一旦出现问题会影响整个集群上部署的所有业务程序,所以,生产中针对Node节点的扩缩容一般还是谨慎使用,当确实需要对Node进行扩缩容时,往往通过人工执行脚本完成。

「Pod的垂直扩/缩容(VPA)」

VPA全称Vertical Pod Autoscaler,即Pod的垂直自动伸缩,它根据容器资源使用率自动设置CPU和内存的requests,从而允许在节点上进行适当的调度,以便为每个Pod提供适当的资源。它既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。

「目前,VPA技术成熟度还不够,是Kubernetes比较新的功能,更新正在运行的Pod资源配置是VPA的一项试验性功能,会导致Pod的重建和重启,而且有可能被调度到其他的节点上。」

「Pod的水平扩/缩容(HPA)」

HPA全称Horizontal Pod Autoscaler,即Pod的水平自动伸缩,根据资源利用率或者自定义指标自动调整Pod的副本数,实现Pod的扩容、缩容,让部署的规模接近于实际服务的负载。

HPA弹性伸缩原理

Horizontal Pod Autoscaler功能最初是在Kubernetes 1.1中引入并不断发展,目前HPA已经支持了autoscaling/v1autoscaling/v2beta1autoscaling/v2beta2三个大版本。

常规场景下,比如晚上业务压力较小情况下,可以使用kubectl scale指令将Pod副本数设置为1;当白天上班高分期业务压力大时使用kubectl scale指令将Pod的副本数设置为3,但这些操作都是人为介入执行的。而HPA控制器则是基于业务的指标判断业务忙闲自动基于算法计算出当前多少Pod副本数运行比较合适,自动调整Pod的副本数。

8366363f74e827cd2723dd45c7862989.png

Kubernetes HPA v2相对于v1版本进行了一些重大改进。其中最显著的改进是引入了「多指标」自动扩缩容,即可以同时根据多种指标(如 CPU使用率、内存使用率、网络负载等)来进行自动扩缩容决策。此外,HPA v2还增加了支持「自定义指标」的能力,使得用户可以根据自己的需求定义和使用自己的指标。总的来说,Kubernetes HPA v2是一个更加成熟、更加灵活和可定制的自动扩缩容机制。

「HPA弹性伸缩的核心机制:自动根据业务忙闲来调整业务工作负载的副本数。这里主要涉及到两个关键点:」

  • 「如何识别业务的忙闲程度」

  • 「使用控制Pod副本数调整」

e72f53ede7e5d0aeea35baa4d57f9af0.png

「我们先来看下第一个问题:如何识别业务的忙闲程度?」

之前介绍kubernetes集群监控时介绍过metrics-server组件可以从集群中所有节点的kubelet组件中cAdvisor上获取到底层容器运行时指标,然后聚合后就可以通过kubectl top node/pod查看CPU、内存资源使用情况,也可以通过kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes 接口访问访问获取。所以,HPA控制器可以通过metrics-server组件获取Pod的CPU、内存使用率识别业务忙闲。

Kubernestes 1.7引入了聚合层(Aggregator),允许第三方应用程序通过注册自己为API插件来扩展Kubernestes API。metrics-server组件注册到聚合层然后就可以像访问kube-apiserver接口一样访问metrics-server后端服务的接口。

Kubernetes在kube-apiserver服务中引入了一个API聚合层,用于将扩展API的访问请求转发到用户服务的功能。比如,当你访问apis/metrics.k8s.io/v1beta1的时候,aggregator组件会基于groupversion转发到后端metrics-server服务上,聚合层只是相当于代理层。通过这种方式,我们就可以很方便地扩展KubernetesAPI

从metrics-server获取CPU、内存指标比较单一,kubernetes集群监控事实标准是prometheus,如果可以从prometheus获取指标用来识别业务忙闲程度,弹性伸缩灵活性就会大大增加。prometheus-adapter组件就可以实现这个功能,它从prometheus拉取指标转换成kubernetes api接口识别的数据格式,并将其注册到聚合层,这样kubernetes集群中其它服务就可以通过/apis/访问。

「再来看第二个问题:如何控制Pod副本数调整?」

HPA控制器会定期执行每个HPA对象的reconcile方法,主要包含如何操作:

  • 获取当前指标数据:从metrics-server获取CPU使用率、内存使用率或从prometheus-adapter获取自定义指标数据;

  • Pod副本数计算:将获取的指标数据和目标期望比较,判断是要扩容、缩容还是不变,若不需要要进行扩缩容调整就直接返回当前副本数,否则才使用HPA metrics 目标类型对应的算法来计算出deployment的目标副本数;

  • 更新Pod副本数:如果上步骤计算出的Pod目标副本数与当前副本数量不一致时,即需要进行扩/缩容的情况,则HPA控制器就向Deploymen发起scale操作,调整当前副本数,完成扩/缩容操作;

  • 监控调整效果:最终实现尽可能将deployment下的每个pod的最终metrics指标(平均值)基本维持到用户期望的水平,HPA会继续监控新的Pod副本数量对指标数据的影响,并根据需要进行进一步的调整。

reconcile定时间隔默认15秒,可以通过horizontal-pod-autoscaler-sync-period配置。

基于CPU指标的HPA

HPA v1版本支持CPU使用率、内存使用率的弹性伸缩,内存使用率一般缓存影响很难真实反映系统负载,所以,一般使用CPU使用率指标来进行弹性伸缩。容器的CPU使用率可以通过聚合层API代理到后端metrics-server服务,metrics-server向所有的kubelet组件发送请求,通过cAdvisor收集到所有容器的CPU、内存运行信息,这样HPA控制器就可以获取到Pod的CPU使用率,然后基于CPU使用率进行弹性伸缩。

2dc24d9cf5f4bc1e403ce6fcba3960f3.png

「1、基于Deployment创建Pod:」

#vi deploy-for-hpa_cpu.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-php
  template:
    metadata:
      labels:
        app: nginx-php
    spec:
      containers:
      - image: lizhenliang/nginx-php
        name: java
        resources: 
           requests:
             memory: "300Mi"
             cpu: "250m"
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx-php

「2、创建:」

[root@k8s-01 autoscaling]# kubectl apply -f deploy-for-hpa_cpu.yml -n demo01
[root@k8s-01 autoscaling]# kubectl get pod -n demo01
NAME                                  READY   STATUS    RESTARTS   AGE
web-84885d5959-fbtxt                 1/1     Running   0          29s

「3、HPA策略文件:」

# vi hpa_for_cpu.yml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  #扩/缩容副本范围
  maxReplicas: 3
  minReplicas: 1
  #指定扩容的Deployment
  scaleTargetRef: 
    apiVersion: apps/v1
    kind: Deployment
    name: web
  targetCPUUtilizationPercentage: 60

targetCPUUtilizationPercentage: 60 表示:当Pod整体的资源利用率超过60%的时候,会进行扩容。

「4、创建HPA:」

[root@k8s-01 autoscaling]# kubectl apply -f hpa_for_cpu.yml -n demo01
horizontalpodautoscaler.autoscaling/web created
[root@k8s-01 autoscaling]# kubectl get hpa -n demo01
NAME              REFERENCE                       TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
web               Deployment/web                  0%/60%    1         3         1          44s

TARGETS一栏显示指标情况,前面0%表示当前Pod得到整体CPU资源使用率,因为没有任何HTTP请求,所以是0%;60%则是扩/缩容阈值。

MINPODS、MAXPODS:指定hpa扩/缩容

「5、压测:」

[root@k8s-01 autoscaling]# yum install httpd-tools
[root@k8s-01 autoscaling]# kubectl get svc -n demo01
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
web                  ClusterIP   10.96.237.204   <none>        80/TCP     5d20h
[root@k8s-01 autoscaling]# ab -n 100000 -c 100  http://10.96.237.204/status.php

「6、观察扩/缩容:」

压测几十秒后,查看hpa后发现整体CPU使用率173%,超过60%目标值,但是replicas还是1,并没有扩容:

[root@k8s-01 autoscaling]# kubectl get hpa -n demo01
NAME              REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
metrics-app-hpa   Deployment/sample-httpserver2   200m/2     1         3         1          46h
web               Deployment/web                  173%/60%   1         3         1          75s

再等会查看到replicas=3,触发了扩容操作:

[root@k8s-01 autoscaling]# kubectl get hpa -n demo01
NAME              REFERENCE                       TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
metrics-app-hpa   Deployment/sample-httpserver2   200m/2    1         3         1          46h
web               Deployment/web                  15%/60%   1         3         3          76s

查看Pod信息:

[root@k8s-01 autoscaling]# kubectl get pod -n demo01
NAME                                 READY   STATUS    RESTARTS   AGE
web-84885d5959-d9l4h                 1/1     Running   0          90s
web-84885d5959-fbtxt                 1/1     Running   0          6m9s
web-84885d5959-xgn4n                 1/1     Running   0          90s

kubectl describe hpa信息,可以看到有一条副本数扩到3的消息事件:

198c1adbd66c3202aaab4d34cef185ff.png

停止压测后,CPU使用率压力会降下来,大概等个几分钟后,又会触发缩容操作,replicas又会被设置成1:

[root@k8s-01 autoscaling]# kubectl get hpa -n demo01         
NAME              REFERENCE                       TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
web               Deployment/web                  0%/60%    1         3         1          7m59s

kubectl describe hpa查看hpa信息,会发现有两条缩容消息事件,一条显示是副本数从3缩容到2消息事件,另一条显示副本数从2缩容到1消息事件:

54c0e34e74c688ec30d826663a3c76d0.png

基于Prometheus自定义指标的HPA

基于metrics-server组件获取的CPU使用率、内存使用率弹性伸缩灵活性稍差,如果想根据自定义指标,如HTTP请求的QPS、5XX错误数等,在云原生领域监控基本就是Prometheus。自定义指标由Prometheus来提供,再利用prometheus-adpater聚合到apiserver,实现从metric-server组件获取CPU、内存同样的效果。

基于Prometheus自定义指标的HPA核心流程如下图:

c361fe82a97a53f5fc15290e8e797daa.png

prometheus-adapter组件部署

「1、安装prometheus-adapter组件:」

[root@k8s-01 ~]# helm repo add stable http://mirror.azure.cn/kubernetes/charts
"prometheus-community" has been added to your repositories
[root@k8s-01 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈ Happy Helming!⎈ 
[root@k8s-01 ~]# helm repo list
NAME                    URL                                               
stable                  http://mirror.azure.cn/kubernetes/charts   

[root@k8s-01 ~]# helm install prometheus-adapter stable/prometheus-adapter --namespace monitoring --set prometheus.url=http://prometheus,prometheus.port=9090
NAME: prometheus-adapter
LAST DEPLOYED: Tue Aug  1 23:44:08 2023
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
prometheus-adapter has been deployed.
In a few minutes you should be able to list metrics using the following command(s):

  kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1

curl http://192.168.31.160:32478/metrics

「2、查看组件安装是否成功:」

[root@k8s-01 ~]# kubectl get pod -n monitoring
NAME                                      READY   STATUS    RESTARTS   AGE
prometheus-adapter-76d8fb4549-6vzzg       1/1     Running   0          3m25s

[root@k8s-01 ~]# kubectl get apiservices                                                 
NAME                                   SERVICE                          AVAILABLE   AGE
...
v1beta1.custom.metrics.k8s.io          monitoring/prometheus-adapter   True        2m28s

[root@k8s-01 ~]# kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 |jq|more
{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "custom.metrics.k8s.io/v1beta1",
  "resources": [
    {
      "name": "namespaces/file_descriptors",
      "singularName": "",
      "namespaced": false,
      "kind": "MetricValueList",
      "verbs": [
        "get"
      ]
    },
    {
      "name": "namespaces/kube_ingress_annotations",
      "singularName": "",
      "namespaced": false,
      "kind": "MetricValueList",
      "verbs": [
        "get"
      ]
    },
...

查看prometheus-adapter组件的日志,注意不要出现类似http://prometheus:9090/api/v1/series?match%5B%5D=%7B__name__%3D~%22%5Econtainer_.%2A%22%2Ccontainer%21%3D%22POD%22%2Cnamespace%21%3D%22%22%2Cpod%21%3D%22%22%7D&start=1690905427.938  timeout 这样错误。

helm卸载操作如下:

[root@k8s-01 ~]# helm ls -n kube-system
NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION
prometheus-adapter      kube-system     1               2023-08-01 23:44:08.027994527 +0800 CST deployed        prometheus-adapter-4.3.0        v0.11.0    
[root@k8s-01 ~]# helm uninstall prometheus-adapter -n kube-system
release "prometheus-adapter" uninstalled

部署golang应用

「1、初始化golang项目工程:」

[root@swarm-manager ~]# mkdir metrics
[root@swarm-manager ~]# cd metrics/
[root@swarm-manager metrics]# go mod init metrics

「2、编写metrics.go:」

package main

import (
 "github.com/prometheus/client_golang/prometheus"
 "github.com/prometheus/client_golang/prometheus/promhttp"
 "net/http"
 "strconv"
)

func main() {
 metrics := prometheus.NewCounterVec(
  prometheus.CounterOpts{
   Name: "http_requests_total",
   Help: "Number of total http requests",
  },
  []string{"status"},
 )
 prometheus.MustRegister(metrics)

 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  path := r.URL.Path
  statusCode := 200
  switch path {
  case "/metrics":
   promhttp.Handler().ServeHTTP(w, r)
  default:
   w.WriteHeader(statusCode)
   w.Write([]byte("Hello World!"))
  }
  metrics.WithLabelValues(strconv.Itoa(statusCode)).Inc()
 })
 http.ListenAndServe(":3000", nil)
}

该go项目主要通过/metrics端点暴露http_requests_total指标。

「3、本地编译打包:」

[root@swarm-manager metrics]# go mod tidy
[root@swarm-manager metrics]# go build -o metrics metrics.go

「4、创建镜像,并推送docker hub上:」

编写Dockerfile:

FROM golang:latest
MAINTAINER simon "30743905@qq.com"
RUN mkdir -p /app
WORKDIR /app
COPY ./metrics /app
EXPOSE 3000

RUN chmod +x ./metrics
ENTRYPOINT ["./metrics"]

构建镜像:

docker build -t metrics .

「5、k8s部署:」

# sample-httpserver-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: sample-httpserver
  name: sample-httpserver
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-httpserver
  strategy: {}
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/path: /metrics
        prometheus.io/port: "3000"
      labels:
        app: sample-httpserver
    spec:
      containers:
        - image: addozhang/httpserver-n-metrics:latest
          name: httpserver-n-metrics
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: '300Mi'
---
apiVersion: v1
kind: Service
metadata:
  name: sample-httpserver
  labels:
    app: sample-httpserver
spec:
  ports:
  - name: web
    port: 3000
    targetPort: 3000
  selector:
    app: sample-httpserver

「6、接口获取指标正常:」

[root@k8s-01 demo01]# kubectl get svc -n demo01     
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
nginx-service       ClusterIP   None            <none>        80/TCP     249d
sample-httpserver   ClusterIP   10.96.153.13    <none>        3000/TCP   32s
tomcat-service      ClusterIP   None            <none>        8080/TCP   249d
web                 ClusterIP   10.96.237.204   <none>        80/TCP     47h
[root@k8s-01 demo01]# curl 10.96.153.13:3000/metrics
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 3.5147e-05
go_gc_duration_seconds{quantile="0.25"} 3.8423e-05
go_gc_duration_seconds{quantile="0.5"} 4.1267e-05
go_gc_duration_seconds{quantile="0.75"} 5.0566e-05
go_gc_duration_seconds{quantile="1"} 9.0761e-05
go_gc_duration_seconds_sum 0.001240037
go_gc_duration_seconds_count 25
......

「7、prometheus配置抓取job:」

- job_name: 'app'
  kubernetes_sd_configs:
  - role: pod
  relabel_configs:
  - action: keep
    source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    regex: true
  - source_labels: [__meta_kubernetes_namespace]
    target_label: namespace
  - source_labels: [__meta_kubernetes_pod_name]
    target_label: pod

「8、指标抓取验证:」

在prometheus target可以查看到部署的应用指标接入成功:

91f52114846051b040c282a73c2eef89.png

使用PromQL查询:sum(rate(http_requests_total[30s])) by (pod)

9332f9b415918a2e72d3379d04458dcd.png

hpa资源创建

「1、创建hpa:」

# vi app-hpa-v2.yml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: metrics-app-hpa 
  namespace: demo01
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sample-httpserver
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_qps
      target:
        type: AverageValue
        averageValue: 2000m   # 2000m 即2个/秒

「2、prometheus-adapter组件配置自定义指标的计算规则,告诉prometheus-adapter如何从prometheus获取指标并计算出我们需要的指标:kubectl edit cm prometheus-adapter -n monitoring

02a429fd2f3a377398f4569c11f05584.png

prometheus-adapter不能动态加载配置,需要kubectl delete pod prometheus-adapter-xx,让Pod重启加载最新配置。

「3、可以访问api-server获取到prometheus-adapter计算生成的新指标:」

[root@k8s-01 ~]# kubectl get --raw '/apis/custom.metrics.k8s.io/v1beta1/namespaces/demo01/pods/*/http_requests_qps' | jq         
{
  "kind": "MetricValueList",
  "apiVersion": "custom.metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/demo01/pods/%2A/http_requests_qps"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Pod",
        "namespace": "demo01",
        "name": "sample-httpserver-695f994dbd-s2s2g",
        "apiVersion": "/v1"
      },
      "metricName": "http_requests_qps",
      "timestamp": "2023-08-02T15:32:56Z",
      "value": "66m",
      "selector": null
    }
  ]
}

「注意:这里的 value: 66m,值的后缀“m” 标识 milli-requests per seconds,所以这里的 66m 的意思是 0.06/s 每秒0.06个请求。」

「4、prometheus-adapter有了指标数据,就可以创建hpa基于该指标:kubectl apply -f app-hpa-v2.yml

# vi app-hpa-v2.yml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: metrics-app-hpa
  namespace: demo01
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sample-httpserver
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_qps
      target:
        type: AverageValue
        averageValue: 2000m   # 2000m 即2个/秒

「5、查看hpa从prometheus-adapter组件获取指标正常:」

b00a55bd5ab1c9a174b890851e13289b.png

当前Pod副本数为1:

e41825a97e333b6c93f74d934a5ac76a.png

「6、接口压测:」

[root@k8s-01 ~]# kubectl get svc -n demo01
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
nginx-service       ClusterIP   None            <none>        80/TCP     249d
sample-httpserver   ClusterIP   10.96.153.13    <none>        3000/TCP   8m11s
[root@k8s-01 ~]# ab -n 100000 -c 30  http://10.96.153.13:3000/metrics
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.96.153.13 (be patient)
Completed 10000 requests
Completed 20000 requests

「7、弹性伸缩验证:」

查看hpa状态,targets一栏显示当前指标到达10900m左右,斜杠后面2表示到达2就要弹性伸缩,10900m/1000=10左右,明显超过2,则replicas一栏显示当前进行扩容到最大副本数3:

c0d1ee3e13dd8020d14faecff26015a7.png

查看hpa描述信息,可以看到有条Event清晰描述出有图http_requests_qps指标超过target设置的2,副本数设置为3:

acc6137b7849f980d0d50c4407362bc8.png

再来看pod信息,发现副本数确实扩容到3个:

94fc76122bee05b7b6005f7a8e5ffd20.png

「8、弹性缩容验证:」

停止接口压测后,hpa指标下降,200m明显小于2,当大概平稳5分钟后,hpa开始进行缩容,将副本数从3降到1:

00748c1582b01ceb6dda671dfa734330.png

查看hpa描述信息,同样印证了hpa发生缩容:

6bc8dee56ef174e56aeadb62d7ebfda7.png

再来确认下Pod已经变成1个了:

a2937dd117994b64784a29cc5544b49a.png

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

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

相关文章

new function是什么?(小写function)

参考链接&#xff1a;https://juejin.cn/post/7006232342398238733

【SpringBoot笔记】定时任务(cron)

定时任务就是在固定的时间执行某个程序&#xff0c;闹钟的作用。 1.在启动类上添加注解 EnableScheduling 2.创建定时任务类 在这个类里面使用表达式设置什么时候执行 cron 表达式&#xff08;也叫七子表达式&#xff09;&#xff0c;设置执行规则 package com.Lijibai.s…

地震预警系统全平台开通攻略

大家好&#xff0c;我是熊哥。 最近地震频发&#xff0c;做为一个有社为责任感的人&#xff0c;我认为我有必要为大家总结这一份安全手册&#xff1b;做为一个小V有必要让更多的人看见&#xff0c;积德攒人品。希望大家平安健康。 效果 在地震来临前&#xff0c;手机、电视会…

每天一道leetcode:剑指 Offer 59 - II. 队列的最大值(中等)

今日份题目&#xff1a; 请定义一个队列并实现函数 max_value 得到队列里的最大值&#xff0c;要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。 若队列为空&#xff0c;pop_front 和 max_value 需要返回 -1 示例1 输入: ["MaxQueue",&qu…

centos7实现负载均衡

目录 一、基于 CentOS 7 构建 LVS-DR 集群。 1.1 配置lvs负载均衡服务 1.1.1 下载ipvsadm 1.1.2 增加vip 1.1.3 配置ipvsadm 1.2 配置rs1 1.2.1 编写测试页面 1.2.2 手工在RS端绑定VIP、添加路由 1.2.3 抑制arp响应 1.3 配置rs2 1.4 测试 二、配置nginx负载…

Springboot后端通过路径映射获取本机图片资源

项目场景&#xff1a; 项目中对图片的处理与查看是必不可少的&#xff0c;本文将讲解如何通过项目路径来获取到本机电脑的图片资源 如图所示&#xff0c;在我的本机D盘的图片测试文件夹(文件夹名字不要有中文)下有一些图片&#xff0c; 我们要在浏览器上访问到这些图片&#…

Flutter系列文章-实战项目

在本篇文章中&#xff0c;我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识&#xff0c;包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用&#xff0c;可以根据用户输入的城市名获取该城市的天气信息&#xff0c;并将用户查询的城市列表保存到本地…

灵活利用ChatAI,减轻工作任务—语言/翻译篇

前言 ChatAI在语言和翻译方面具有重要作用。它能够帮助用户进行多语言交流、纠正错误、学习新语言、了解不同文化背景&#xff0c;并提供文本翻译与校对等功能。通过与ChatAI互动&#xff0c;我们能够更好地利用技术来拓展自己在语言领域的能力和知识&#xff0c;实现更加无障…

P11-Transformer学习1.1-《Attention Is All You Need》

Transformer目录:《Transformer Paper》1.0 CV Transformer必读论文5篇_汉卿HanQ的博客-CSDN博客 前文参考:Transformer1.0-预热_汉卿HanQ的博客-CSDN博客 全文1w3字左右&#xff0c;按照论文翻译个人理解精读&#xff0c;如果对你有所帮助&#xff0c;欢迎点个赞哦&#xff…

【C语言】初识C语言+进阶篇导读

✨个人主页&#xff1a; Anmia.&#x1f389;所属专栏&#xff1a; C Language &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 本篇目的是面向编程新手&#xff0c;没接触过编程的人。以及C进阶的导读。 内容是C语言重要知识点的简单解释&#xff0c;不做详解。给…

征稿 | 第三届粤港澳大湾区人工智能与大数据论坛(AIBDF 2023)

第三届粤港澳大湾区人工智能与大数据论坛&#xff08;AIBDF 2023&#xff09; 2023 3rd Guangdong-Hong Kong-Macao Greater Bay Area Artificial Intelligence And Big Data Forum 本次高端论坛围绕建设国家数字经济创新发展试验区进行选题。全面贯彻落实党的二十大精神&…

001-Spring boot 启动内置Web容器分析

目录 代码入口上下文容器 加载web容器 代码入口 上下文容器 SpringApplication.run(App.class); //追踪下去发现 context createApplicationContext();createApplicationContext()&#xff1a; return this.applicationContextFactory.create(this.webApplicationType);这里…

linux手动安装 golangci-lint-1.53.3-linux-386.rpm

首先还是 去下载对应的 rpm 包 https://github.com/golangci/golangci-lint/releases 然后上传到 服务器/usr/local 目录下 执行安装命令 sudo rpm -ivh golangci-lint-1.53.3-linux-386.rpm 查看版本 golangci-lint --version

14.3.5 LVM 的 LV 磁盘快照

什么是 LV 磁盘快照&#xff1f;快照就是将当时的系统信息记录下来&#xff0c;就好像照相记录一般&#xff01; 未来若有任何数据更动了&#xff0c;则原始数据会被搬移到快照区&#xff0c;没有被更动的区域则由快照区与文件系统共享。 图14.3.3、LVM快照区域的备份示意图 左…

微信小程序的项目解构

视频链接 黑马程序员前端微信小程序开发教程&#xff0c;微信小程序从基础到发布全流程_企业级商城实战(含uni-app项目多端部署)_哔哩哔哩_bilibili 接口文档 https://www.escook.cn/docs-uni-shop/mds/1.start.html 1&#xff1a;微信小程序宿主环境 1&#xff1a;常见的宿…

Openlayers实战:判断共享单车是否在电子围栏内

共享单车方便了我们的日常生活,解决了后一公里的行程问题。为了解决共享单车乱放的问题,运营部门规划出一些围栏,配合到电子地图上即为电子围栏,只有放在围栏内才能停车结算,在我们的Openlayers实战示例中,即模拟这一场景。 效果图 源代码 /* * @Author: 大剑师兰特(x…

电脑怎么查看连接过的WIFI密码(测试环境win11,win10也能用)

电脑怎么查看连接过的WIFI密码 方法一&#xff1a;适用于正在连接的WIFI密码的查看 打开设置 点击“网络和Internet”&#xff0c;在下面找到“高级网络设置”点进去 在下面找到 “更多网络适配器选项” 点进去 找到 WLAN &#xff0c;然后双击它 5.然后点击“无线属性” 6.…

2023-08-08 LeetCode每日一题(任意子数组和的绝对值的最大值)

2023-08-08每日一题 一、题目编号 1749. 任意子数组和的绝对值的最大值二、题目链接 点击跳转到题目位置 三、题目描述 给你一个整数数组 nums 。一个子数组 [numsl, numsl1, …, numsr-1, numsr] 的 和的绝对值 为 abs(numsl numsl1 … numsr-1 numsr) 。 请你找出 …

ffplay简介

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 ffplay播放器的意义 ffplay.c是FFmpeg源码⾃带的播放器&#xff0c;调⽤FFmpeg和SDL API实现⼀个⾮常有⽤的播放器。 ffplay实现了播…

c++文件流详细笔记

c++流 IO :向设备输入数据和输出数据 C++的IO流 设备: 文件控制台特定的数据类型(stringstream)c++中,必须通过特定的已经定义好的类, 来处理IO(输入输出) 文件流 文件流: 对文件进行读写操作 头文件: 类库: ifstream 对文件输入(读文件) ofstream 对文件输出(写…