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

2023-11-01

【云原生•监控】基于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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Grafana 仪表板不显示 pod 名称,而是显示 pod_name

    我已经在 kubernetes 集群上部署了应用程序 并使用 prometheus 和 grafana 进行监控 对于使用 Grafana 仪表板进行 kubernetes pod 监控 Kubernetes集群监控 通过Prometheu
  • Guice 忽略注入构造函数参数上的 @Nullable

    我正在使用 Guice v 3 0 并且有一个值被注入到构造函数中 该值可以为 null 因此我在构造函数中使用 Nullable 来自 javax annotations 注释了该参数 public MyClass Parameter1
  • Oracle Java 教程 - 回答问题时可能出现错误

    我是 Java 新手 正在阅读 Oracle 教程 每个部分之后都有问题和答案 我不明白一个答案中的一句话 见下面的粗体线 来源是https docs oracle com javase tutorial java javaOO QandE
  • HAProxy SSL终止+客户端证书验证+curl/java客户端

    我希望使用我自己的自签名证书在 HAProxy 上进行 SSL 终止 并使用我创建的客户端证书验证客户端访问 我通过以下方式创建服务器 也是 CA 证书 openssl genrsa out ca key 1024 openssl req
  • 将SQL数据引入jquery availabletag

    我正在尝试制作自动完成文本框 但如何将 SQL 数据包含到 jquery 可用标记并循环它 我无法根据以下代码执行该功能 任何帮助 将不胜感激 谢谢 这是我的预期输出 预期结果演示 http jsfiddle net VvETA 71 jq
  • 从 MS Access 中提取 OLE 对象(Word 文档)

    我有一个 Microsoft Access 数据库 其中包含一个包含 Microsoft Word 文档的 OLE 对象字段 我试图找到代码来检索保存在 OLE 对象中的文件 以便用户可以从我的 JavaFx 应用程序中的按钮下载它 但没有
  • 您建议使用哪种压缩(GZIP 是最流行的)servlet 过滤器?

    我正在寻找一个用于大容量网络应用程序的 GZIP servlet 过滤器 我不想使用容器特定的选项 要求 能够压缩响应负载 XML Faster 已在大批量应用的生产中得到验证 应适当设置适当内容编码 跨容器移植 可选择解压缩请求 谢谢 我
  • 如何在java Spring Boot中实现通用服务类?

    我有许多具有重复代码的服务 我想知道如何实现通用服务 以便我的所有服务都可以扩展它 服务接口示例 重复代码 Service public interface IUserService List
  • Java中的断点和逐步调试?

    抱歉我的问题名称很奇怪 我不知道如何寻找这个 因为我不知道这些东西是如何称呼的 Visual Studio 中至少有一个功能 您可以单击代码左侧并设置一个大红点的起点 然后运行程序 您可以通过按 f8 或 f5 实际上是不同的 f 来跟踪步
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 从直方图计算平均值和百分位数?

    我编写了一个计时器 可以测量任何多线程应用程序中特定代码的性能 在下面的计时器中 它还会在地图中填充花费了 x 毫秒的调用次数 我将使用这张图作为我的直方图的一部分来进行进一步的分析 例如调用花费了这么多毫秒的百分比等等 public st
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • 在 Java 中通过 XSLT 分解 XML

    我需要转换具有嵌套 分层 表单结构的大型 XML 文件
  • 如何删除日期对象的亚秒部分

    当 SQL 数据类型为时间戳时 java util Date 存储为 2010 09 03 15 33 22 246 如何在存储记录之前将亚秒设置为零 例如 在本例中为 246 最简单的方法是这样的 long time date getTi
  • 通过 appassembler-maven-plugin 生成的脚本无法在 Spring Boot 应用程序中找到主类

    我使用 appassembler maven plugin 生成的启动脚本有问题 我有一个基本的 spring boot 应用程序 只有一个类 SpringBootApplication public class ScriptDemoApp
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • 如何停止执行的 Jar 文件

    这感觉像是一个愚蠢的问题 但我似乎无法弄清楚 当我在 Windows 上运行 jar 文件时 它不会出现在任务管理器进程中 我怎样才能终止它 我已经尝试过 TASKKILL 但它对我也不起作用 On Linux ps ef grep jav
  • 避免 Java 中的重复导入:继承导入?

    有没有办法 继承 导入 Example 常见枚举 public enum Constant ONE TWO THREE 使用此枚举的基类 public class Base protected void register Constant
  • 使用Java绘制维恩图

    我正在尝试根据给定的布尔方程绘制维恩图 例如 a AND b AND c我想在 Android 手机上执行此操作 因此我需要找到一种使用 Java 来执行此操作的方法 我找到了一个完美的小部件 它可以完成我在这方面寻找的一切布尔代数计算器
  • 无需登录即可直接从 Alfresco 访问文件/内容

    我的场景是这样的 我有一个使用 ALFRESCO CMS 来显示文件或图像的 Web 应用程序 我正在做的是在 Java servlet 中使用用户名和密码登录 alfresco 并且我可以获得该登录的票证 但我无法使用该票证直接从浏览器访

随机推荐

  • 如何使用Python进行桌面应用开发?

    Python提供了多个库和框架来进行桌面应用开发 以下是使用Python进行桌面应用开发的常用方法之一 PyQt PyQt是一个用于开发跨平台桌面应用的Python库 它提供了丰富的GUI组件和工具 以下是使用PyQt创建桌面应用的基本步骤
  • Linux上启用kvm嵌套虚拟化功能

    kvm支持嵌套虚拟化 即可以在虚拟机中创建虚拟机 本文主要介绍如何在使用Intel处理器的CentOS7中开启KVM的嵌套虚拟化功能 kvm主要是通过内核模块来实现的 因此我们查看系统是否开启了kvm嵌套虚拟化 只需要 cat sys mo
  • 代码随想录算法训练营 个人总结

    训练营周期 2023 5 10 7 8 共计60天 LeetCode记录 参加训练营之前 就有想刷LeetCode的想法 一方便没有头绪地不知道按什么顺序刷题 另一方面也没有找到很好的讲解材料 都是自己看LeetCode页面上讨论模块下的高
  • Spark SQL数据源 - 基本操作

    目录 一 基本操作 二 默认数据源 一 默认数据源Parquet 二 案例演示读取Parquet文件 1 在Spark Shell中演示 2 通过Scala程序演示 一 基本操作 Spark SQL提供了两个常用的加载数据和写入数据的方法
  • git上创建自己的仓库并将新项目推上去

    1 在github上创建仓库 创建后复制地址 2 先进入项目文件夹 通过命令 git init 把这个目录变成git可以管理的仓库 git init 3 把文件添加到版本库中 使用命令 git add 添加到暂存区里面去 不要忘记后面的小数
  • 【华为OD机试真题2023B卷 JAVA&JS】找单词

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 找单词 时间限制 1秒 内存限制 32768K 语言限制 不限 题目描述 给一个字符串和一个二维字符数组 如果该字符串存在于该数组中 则按字符串的字符顺序输出字符串每个字符所在单元格的
  • matlab newff函数弃用了,MATLAB神经网络函数NEWFF()新旧用法差异

    摘要 在Matlab R2010a版中 如果要创建一个具有两个隐含层 且神经元数分别为5 3的前向BP网络 使用旧的语法可以这样写 net1 newff minmax P 5 3 1 注意minmax 函数的使用 还有对输出层神经元数 1
  • 论文笔记:用于动态薄膜干涉测量的高光谱成像《Hyperspectral imaging for dynamic thin film interferometry》

    论文地址 Hyperspectral imaging for dynamic thin film interferometry Scientific Reports 目录 论文简介 阻因 现有方法及缺陷 文章贡献 理论依据 实验 实验结果与
  • php curlopt_header,php curl中CURLOPT_HTTPHEADER 这个参数的含义

    php curl中CURLOPT HTTPHEADER 这个参数的含义是 CURLOPT HTTPHEADER 一个用来设置HTTP头字段的数组 Content Type 表示后面的文档属于什么MIME类型 charset表示浏览器可接受的
  • Unity之使UI显示在最上层

    一 原理 Camera Depth 摄像机深度 深度值越小 越浅 越浮于表面 越近 前 Sorting Layer 排序层级 Order In Layer 在排序层中的层级 Render Queue 在Shader中对Tags的Queue进
  • 哗啦啦收银系统配置

    步骤 一 安装哗啦啦收银系统二 安装小票驱动三 创建店铺 进入收银系统 详情请参考我的个人博客 哗啦啦系统后台新增店铺 四 修改打印机模板五 修改打印机名称 准备 小票驱动 安装包 打印模板 功能包 一 安装哗啦啦收银系统 二 安装小票驱动
  • Python IDLE的下载,安装与使用教程

    本次是windows下的IDLE Linux IDLE是没有的 可以直接使用相应的Python 解释器 首先我们现在先进入Python的官网 https www python org 去下载一个Python IDLE程序安装包 找到Down
  • JDBC编码六步走

    JDBC介绍 Java Database Connectivity 简称JDBC 是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口 JDBC的本质 JDBC是SUN公司制定的一套连接数据库的接口 interface 而接口都
  • 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区

    1 Get方法长度限制 Http Get方法提交的数据大小长度并没有限制 HTTP协议规范没有对URL长度进行限制 这个限制是特定的浏览器及服务器对它的限制 如 IE对URL长度的限制是2083字节 2K 35 下面就是对各种浏览器和服务器
  • numpy+matplotlib画正余弦函数图像

    coding utf 8 import matplotlib pyplot as plt import numpy as np import math x np arange 0 10 0 1 print x size y1 np zero
  • chatGPT的优点

    ChatGPT 的优点有以下几点 语言能力强 ChatGPT 是一个大型的语言模型 它能够理解和生成多种语言 具有很强的语言处理能力 记忆力强 ChatGPT 被训练过大量的文本数据 因此它对文本的记忆力也很强 能够快速回答用户的问题 智能
  • PageHelper分页原理(源码)

    PageHelper分页原理 PageHelper是我们经常使用的一个分页插件 之前咱们一直处于使用阶段的 今天咱们去探究一下其中的原理 SQL语句实现分页查询知识 就不在赘述了 LIMIT i a i 是指查询的索引值 默认是0 a 是指
  • CH7-IO

    实验7 1 批量操作文件功能 任务介绍 1 任务描述 在日常工作中 经常会遇到批量操作系统文件的事情 通常情况下 只能手动重复的完成批量文件的操作 这样很是费时费力 本案例要求编写一个文件管理器 实现文件的批量操作 文件管理器具体功能要求如
  • mysql架构与存储引擎

    文章目录 一 MySQL体系架构 1 1 网络连接层 1 2 服务层 MySQL Server 1 3 存储引擎层 Pluggable Storage Engines 1 4 系统文件层 File System 1 4 1 日志文件 1 4
  • 【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA)

    云原生 监控 基于Prometheus实现自定义指标弹性伸缩 HPA 什么是弹性伸缩 Autoscaling即弹性伸缩 是Kubernetes中的一种非常核心的功能 它可以根据给定的指标 例如 CPU 或内存 自动缩放Pod副本 从而可以更