借助 Pyroscope 对 Amazon EKS 容器服务进行 Continuous Profiling 诊断应用性能

news2024/11/16 16:54:54

3590b0761c042a08bb69a5cb0a430bcb.gif

Continuous Profiling 的现状

在可观测领域,Trace、Log、Metrics 作为“三大支柱”,帮助工程师更方便的洞察应用的内部问题。然而,对于开发人员而言,经常还需要深入应用程序,找出造成瓶颈的根本原因。在可观测的“三大支柱”中,往往通过日志来收集这些信息。不过,这种方法往往非常耗时,又缺乏足够的细节帮助开发人员定位应用的性能问题。

一种比较有效的方法是使用 Profiling 技术。Profiling 是一种分析程序复杂性的动态方法,旨在运行时收集应用系统信息来研究系统运行状况,定位性能热点,例如 CPU 利用率或函数调用的频率和持续时间。通过分析可以准确定位应用程序的哪些部分消耗了最多的资源或者时间,从而优化整体系统性能。Profiling 技术的使用一般有以下几种形式:

  • 系统工具:如 linux 的 strace/perf、Solaris 的 DTrace,这类工具的使用需要很强的 C 和操作系统基础,往往需要能够理解 OS 级别的系统调用;

  • Languages Native:通过编程语言 Profiling 库方式提供,例如 golang 的 net/http/pprof、runtime/pprof,需要工程师将这些 package 引入到程序中,并通过专门的工具进行查看分析。Amazon CodeGuru Profiler 也提供 Java/Python 语言的 agent,为 Java 和 Python 应用提供 Profiling;

  • 使用 eBPF:eBPF Profiling 是使用 Infrastructure 的思路来解决应用的观测问题,eBPF 是当前 Linux 内核非常热门的技术,使用 eBPF profiling 可以不需要对代码进行修改,就能够从内核获取整个系统的堆栈跟踪(eBPF 的用途远远不止 Profiling)。

需要注意的是,在使用 Golang/Java/C/C++等编译型语言时,eBPF profiler 能够获得与非 eBPF profiler 非常相似的信息。但对于 Python 等解释型语言,运行时的堆栈跟踪无法从内核轻松访问,Languages Native 在这种场景下有更好的效果。鉴于 Languages Native 和 eBPF 的优劣势,一般商业产品会同时提供这两种方式的接入。

另一方面,原始的 Profiling 信息往往难以阅读理解,为解决这个问题,“Systems Performance: Enterprise and the Cloud”(中文翻译“性能之巅”)的作者 Brendan Gregg 发明了 FlameGraph(火焰图),通过分层的方式对 Profiling 中的应用堆栈跟踪、持续时长进行可视化,以便直观且快速准确地识别执行频率最高、最耗费资源的代码路径。主流的 Profiling 工具几乎都使用 FlameGraph 的方式做可视化。火焰图的解读可以参考:性能调优利器:火焰图。

  • 性能调优利器:火焰图:

    https://www.infoq.cn/article/a8kmnxdhbwmzxzsytlga

e6fd3707de86ee581ab1e52359ab337a.png

仅仅有 Profiling 往往是不够的,在现代应用的场景中,不可变基础设施被大量使用,以 Kubernetes 为例,往往故障发生后应用已经崩溃,Liveness Probe 检查失败,紧随着 Pod 被销毁,新的应用 Pod 将取代被销毁的 Pod 提供服务,如果没有及时的进行Profiling,应用堆栈调用信息将随着 Pod 生命周期终止而丢失。另外,针对内存溢出 OOM 这样的问题,往往需要对照不同时间的 Profiling 数据,才能发现问题。Continuous Profiling 为 Profiling 增加了时间维度,通过了解程序 Profiling 信息随时间的变化,帮助定位、调试和修复与性能相关的问题。

如何在 Amazon EKS 里使用 Pyroscope

Pyroscope 架构简介

Pyroscope 是一家提供开源 Continuous Profiling 服务的公司,2023年3月被 Grafana 收购,并将 Grafana 自己的 Phlare 融合到 Pyroscope。与 Trace 可观测支柱的技术实现类似,Pyroscope 也同时支持 SDK-Instrumentation 和 Auto-Instrumentation 生产 Profiling 数据,采用 Push 和 Pull 结合的方式采集数据,并做存储和展示。本文以 Pyroscope 为例,介绍演示如何使用 Pyroscope 工具实现现代化应用的 Continuous Profiling,洞察现代应用的性能。

d12333d4920d38c12981984549527b96.png

Pyroscope 的部署分两部分,Pyroscope Server 端和 Client 端:

  • Server 部分主要对 Client 上报上来的数据做收集、处理、存储、展示,并对外提供 API 接口,可以使用 Grafana 对 Pyroscope Profiling 数据以火焰图的方式展示。

  • Client 端是个 Grafana Agent,Agent 可以使用 eBPF 技术采集 Profiling 后再 push 到 Server 端,或使用 Agent pull 的方式直接从应用采集 Profiling 数据。除了使用 Agent,用户也可以使用 SDK 将生成的 Profiling 数据直接 push 到 server 端。

在 EKS 中安装 Pyroscope

要在 EKS 中使用 Pyroscope,需要先安装 Pyroscope 服务。安装步骤如下:

1、准备 S3 桶用于 Pyroscope 的持久化

Pyroscope 支持使用 S3 对数据的持久化,Pyroscope 使用 Thanos’ object store client,由于文档未说明是否支持 IRSA 鉴权,这里可以为 Pyroscope 创建单独的 IAM User 用于访问 S3 桶,建议保管好该用户的 AK/SK,避免泄漏,同时为 Pyroscope 使用的 S3 桶设置精细的 IAM Policy。注意替换以下模版的〈YOUR-S3-BUCKET〉。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Pyroscope",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetObjectTagging",
                "s3:PutObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::<YOUR-S3-BUCKET>/*",
                "arn:aws:s3:::<YOUR-S3-BUCKET>"
            ]
        }
    ]
}

左滑查看更多

2、使用以下命令为 Pyroscope 创建 kubernetes namespace

kubectl create namespace pyroscope

3、安装 Pyroscope helm repo

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

左滑查看更多

4、下载 Pyroscope 的模版,调整部署参数。Pyroscope 支持分布式部署,提供单独 minio 作为后端的持久化对象存储,分布式部署模式下不支持在 helm 的模版里修改使用 S3 作为长期持久化层,因此这里使用单体架构的部署方式。

curl -Lo pyroscope-values.yaml \
https://raw.githubusercontent.com/grafana/pyroscope/main/operations/pyroscope/helm/pyroscope/values.yaml

左滑查看更多

Pyroscope server 是个 statefulset 有状态应用,通过配置 replicaCount 调整 Pyroscope server 服务实例数量。

pyroscope:
  replicaCount: 3

如果在生产中运行,建议修改 Pyroscope server Pod 使用资源的 limit 和 request。

resources:
    {}

默认情况下,Pyroscope ingester 模块接受到 Profiling 数据后,会将近期的数据保留在内存里,达到阀值或超过 3 小时,Pyroscope 将数据持久化到块存储,由于可以使用 S3 来分层,pv 不需要设置太大。

persistence:
    enabled: True
    accessModes:
      - ReadWriteOnce
    size: 10Gi
    annotations: {}

在配置了对象存储的情况下,完整的数据块将被 upload 到 S3上进行持久化。可以借助 S3 Intelligent-Tiering 降低这部分的数据持久化成本。注意根据自己的环境调整以下 S3 配置的参数。

config: |
    storage:
      backend: s3
      s3:
        region: <YOUR-S3-REGION>
        endpoint: s3.<YOUR-S3-REGION>.amazonaws.com
        bucket_name: <YOUR-S3-BUCKET>
        access_key_id: <YOUR-ACCESS-KEY>
        secret_access_key: <YOUR-SECRET-KEY>

左滑查看更多

默认情况下 Pyroscope 搭建了 minio 对象存储用于长期数据持久化,通过以下设置关闭 minio 服务,直接使用 S3:

minio:
  enabled: false

左滑查看更多

5、修改完部署配置后,执行 helm install 安装 Pyroscope server 端

helm -n pyroscope install pyroscope grafana/pyroscope --values pyroscope-values.yaml

左滑查看更多

命令输出大致如下:

NAME: pyroscope
LAST DEPLOYED: Tue Sep  5 09:10:31 2023
NAMESPACE: pyroscope
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thanks for deploying Grafana Pyroscope.


# Pyroscope UI & Grafana


Pyroscope database comes with a built-in UI, to access it from your localhost you can use:


```
kubectl --namespace pyroscope port-forward svc/pyroscope 4040:4040
```


You can also use Grafana to explore Pyroscope data.
For that, you'll need to add the Pyroscope data source to your Grafana instance and configure the query URL accordingly.
See https://grafana.com/docs/grafana/latest/datasources/grafana-pyroscope/ for more details.


The in-cluster query URL for the data source in Grafana is:


```
http://pyroscope.pyroscope.svc.cluster.local.:4040
```


# Collecting profiles.




The Grafana Agent has been installed to scrape and discover pprof profiles endpoint via pod annotations.


As an example, to start collecting memory and cpu profile using the 8080 port, add the following annotations to your workload:


```
profiles.grafana.com/memory.scrape: "true"
profiles.grafana.com/memory.port: "8080"
profiles.grafana.com/cpu.scrape: "true"
profiles.grafana.com/cpu.port: "8080"
```




To learn more supported annotations, read our guide https://grafana.com/docs/pyroscope/next/deploy-kubernetes/#optional-scrape-your-own-workloads-profiles


There are various ways to collect profiles from your application depending on your needs.
Follow our guide to setup profiling data collection for your workload:


https://grafana.com/docs/pyroscope/next/configure-client/

左滑查看更多

注意输出的信息

http://pyroscope.pyroscope.svc.cluster.local.:4040

需要用于配制 Grafana Datasource。

6、Pyroscope 使用 Grafana 做数据的查询和展示,默认情况 Grafana 不支持火焰图,需要在 helm 安装时使用以下的参数开启该 feature。

helm upgrade -n pyroscope --install grafana grafana/grafana \
  --set image.repository=grafana/grafana \
  --set image.tag=main \
  --set env.GF_FEATURE_TOGGLES_ENABLE=flameGraph \
  --set env.GF_AUTH_ANONYMOUS_ENABLED=true \
  --set env.GF_AUTH_ANONYMOUS_ORG_ROLE=Admin \
  --set env.GF_DIAGNOSTICS_PROFILING_ENABLED=true \
  --set env.GF_DIAGNOSTICS_PROFILING_ADDR=0.0.0.0 \
  --set env.GF_DIAGNOSTICS_PROFILING_PORT=6060 \
  --set-string 'podAnnotations.pyroscope\.grafana\.com/scrape=true' \
  --set-string 'podAnnotations.pyroscope\.grafana\.com/port=6060'

左滑查看更多

7、安装完 Grafana

安装 Grafana 会生成登录的 secret 信息,默认账户为 admin,密码需要使用以下命令获取:

kubectl get secret --namespace pyroscope grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

左滑查看更多

使用以下命令执行 port-forward(亦可以通过 ingress 或 loadbalancer 的形式使用负载均衡器进行服务暴露),将 Grafana UI 映射到 localhost 进行访问。

export POD_NAME=$(kubectl get pods --namespace pyroscope -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace pyroscope port-forward $POD_NAME 3000

左滑查看更多

这里将 port-forward 到本地 3000 端口,在浏览器中使用 localhost:3000 访问 Grafana,使用 admin 用户名和获取的 secret 登录,在 Datasource 中选择 Grafana Pyroscope 类型。

9026d7379d2b454a768b661a6156e6f4.png

在 URL 中填写:

http://pyroscope.pyroscope.svc.cluster.local.:4040

保存该数据源。

c45882a8ac120a8dbdff1b4fb0f8b302.png

在 Grafana explorer 中,选择 Pyroscope 数据源,使用以下的标签过滤 Profiling 数据,执行 Run query,可以看到 Grafana 展示 pyroscope-0 这个 Pod 的火焰图信息。

66ace98484633e50af6c5ec68606fee5.png

到这里为止,Pyroserver server 搭建完成,且只能访问 Pyroserver server 自身的 Profiling 火焰图信息。如果要展示应用的 Profiling 信息,还需要在代码引入 SDK 进行开发或在节点上安装 eBPF agent,再将生成的 Profiling 信息 push 到 Pyroserver server。

使用 Pyroscope eBPF agent 自动 Profiling

1、创建 agent 配置

Pyroscope eBPF agent 以 daemonset 的方式部署在每一个 EKS 节点上,使用 Kubernetes 的服务发现机制获取 Pod 列表,通过配置规则对采集的数据执行 relabel。这里参考 Grafana agent 编写了个配置,注意根据自己环境设置 endpoint 的 URL,将配置保存为pyroscope-ebpf-values.yaml。

agent:
  mode: 'flow'
  configMap:
    create: true
    content: |
      discovery.kubernetes "all_pods" {
        selectors {
          field = "spec.nodeName=" + env("HOSTNAME")
          role = "pod"
        }
        role = "pod"
      }
      discovery.relabel "local_pods" {
        targets = discovery.kubernetes.all_pods.targets
        rule {
          action = "replace"
          replacement = "${1}/${2}"
          separator = "/"
          source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"]
          target_label = "service_name"
        }
      }
      pyroscope.ebpf "instance" {
        forward_to = [ pyroscope.write.endpoint.receiver ]
        targets = discovery.kubernetes.local_pods.targets
      }
      pyroscope.write "endpoint" {
        endpoint {
          url = "http://pyroscope.pyroscope.svc.cluster.local:4040"
        }
      }


  securityContext:
    privileged: true
    runAsGroup: 0
    runAsUser: 0


controller:
  hostPID: true

左滑查看更多

也可以根据需要和 relabel 的规则,参考该配置手册进行配置修改:

https://grafana.com/docs/pyroscope/latest/configure-client/grafana-agent/ebpf/

2、安装 Pyroscope eBPF agent

helm install -n pyroscope pyroscope-ebpf grafana/grafana-agent -f pyroscope-ebpf-values.yaml

左滑查看更多

3、在 Grafana 上查询 eBPF 生成的应用火焰图

由于我的环境中已经部署了 istio,agent 在采集后对 profiling 数据标签做了转换,可以直接使用以下标签进行查询:

7debba3a1b21bb4bcbbaa9697fd8275c.png

可以看到 istio 的 jaeger 程序的火焰图信息:

7625f6235fd6546b24a08361653406be.png

可以看到 eBPF 无需对 jaeger 进行代码修改,就能持续的采集 jaeger 程序的 profiling 信息,并在 Grafana 上进行火焰图的展示。

使用 SDK 对应用 Profiling

除了使用 eBPF 对应用持续 profiling,Pyroscope 也支持使用 SDK 的方式 profiling。

这是一段 Pyroscope 提供的 go 的示例代码,该程序使用 goroutine 持续运行 fastFunction 和 slowFunction 两个函数,在函数里调用 work,分别循环 800000000 和 200000000 次,生成 profiling 信息并附加上 label 方便查询,生成的 profiling 数据传输给 PYROSCOPE_ENDPOINT 进行存储和查询展示。除了 golang,Pyroscope 也为其他开发语言提供了相应的 SDK。

package main


import (
    "context"
    "fmt"
    "os"
    "runtime"
    "runtime/pprof"
    "sync"


    "github.com/grafana/pyroscope-go"
)


//go:noinline
func work(n int) {
    // revive:disable:empty-block this is fine because this is a example app, not real production code
    for i := 0; i < n; i++ {
    }
    fmt.Printf("work\n")
    // revive:enable:empty-block
}


var m sync.Mutex


func fastFunction(c context.Context, wg *sync.WaitGroup) {
    m.Lock()
    defer m.Unlock()


    pyroscope.TagWrapper(c, pyroscope.Labels("function", "fast"), func(c context.Context) {
        work(200000000)
    })
    wg.Done()
}


func slowFunction(c context.Context, wg *sync.WaitGroup) {
    m.Lock()
    defer m.Unlock()


    // standard pprof.Do wrappers work as well
    pprof.Do(c, pprof.Labels("function", "slow"), func(c context.Context) {
        work(800000000)
    })
    wg.Done()
}


func main() {
    runtime.SetMutexProfileFraction(5)
    runtime.SetBlockProfileRate(5)
    pyroscope.Start(pyroscope.Config{
        ApplicationName:   os.Getenv("SERVICE_NAME"),
        ServerAddress:     os.Getenv("PYROSCOPE_ENDPOINT"),
        Logger:            pyroscope.StandardLogger,
        AuthToken:         os.Getenv("PYROSCOPE_AUTH_TOKEN"),
        TenantID:          os.Getenv("PYROSCOPE_TENANT_ID"),
        BasicAuthUser:     os.Getenv("PYROSCOPE_BASIC_AUTH_USER"),
        BasicAuthPassword: os.Getenv("PYROSCOPE_BASIC_AUTH_PASSWORD"),
        ProfileTypes: []pyroscope.ProfileType{
            pyroscope.ProfileCPU,
            pyroscope.ProfileInuseObjects,
            pyroscope.ProfileAllocObjects,
            pyroscope.ProfileInuseSpace,
            pyroscope.ProfileAllocSpace,
            pyroscope.ProfileGoroutines,
            pyroscope.ProfileMutexCount,
            pyroscope.ProfileMutexDuration,
            pyroscope.ProfileBlockCount,
            pyroscope.ProfileBlockDuration,
        },
        HTTPHeaders: map[string]string{"X-Extra-Header": "extra-header-value"},
    })


    pyroscope.TagWrapper(context.Background(), pyroscope.Labels("foo", "bar"), func(c context.Context) {
        for {
            wg := sync.WaitGroup{}
            wg.Add(2)
            go fastFunction(c, &wg)
            go slowFunction(c, &wg)
            wg.Wait()
        }
    })
}

左滑查看更多

使用以下 Dockerfile 将代码构建成镜像,保存在 ECR 里:

FROM golang:alpine AS build-env
RUN apk update && apk add ca-certificates
WORKDIR /usr/src/app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags '-extldflags "-static"'
FROM scratch
COPY --from=build-env /usr/src/app/pyroscope-demo /pyroscope-demo
COPY --from=build-env /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
CMD ["/pyroscope-demo"]

左滑查看更多

使用以下的配置将应用 pyroscope-demo 应用部署到 EKS 集群,使用环境变量设置 Pyroscope server 的 endpoint:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pyroscope-demo
  labels:
    app: pyroscope-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pyroscope-demo
  template:
    metadata:
      labels:
        app: pyroscope-demo
    spec:
      containers:
      - name: pyroscope-demo
        image: "<AWS_ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/pyroscope-demo:latest"
        env:
        - name: PYROSCOPE_ENDPOINT
          value: "http://pyroscope.pyroscope.svc.cluster.local:4040"
        - name: SERVICE_NAME
          value: "Pyroscope-demo"

左滑查看更多

运行成功后,在 Grafana explorer 里查询 pyroscope-demo 应用的 profiling 信息,可以看到在近 5 分钟内,该应用的运行情况。火焰图是个很直观展示 profiling 的图表,上下层代表调用关系,横向 bar 的宽窄代表占用资源的多少。可以看到在 slowFunction 里 main.work 函数的运行时间为 3.98 分钟,而 fastFunction 为 59.9s,与两个函数执行的循环次数几乎匹配。

923fb7a777445998e34e870b141ffa94.png

通过该例子,可以很直观的对应用运行消耗的资源进行分析,寻找性能问题产生的原因,从而对问题进行排查,优化应用性能。

总结

简而言之,Continuous Profiling 是现代化应用内部性能分析的未来,结合可观测性的另外三个支柱,基于 eBPF 无代码侵入的 Profiling 帮助客户更简单、更大规模、更持续地从基础设施、应用以及涉及的中间件等,进行应用性能的分析调试,帮助客户在关键业务场景结合日志,指标,追踪进行快速的问题定位,并对应用持续优化改进。

参考资料

  • https://www.cncf.io/blog/2022/05/31/what-is-continuous-profiling/

  • https://www.brendangregg.com/flamegraphs.html

  • https://github.com/brendangregg/FlameGraph

  • https://www.infoq.cn/article/a8kmnxdhbwmzxzsytlga

  • https://github.com/grafana/pyroscope

  • https://grafana.com/docs/pyroscope/latest/configure-client/language-sdks/

  • https://opentelemetry.io/community/roadmap/

本篇作者

954bc852aa69f326a78ada3cc0b037e7.jpeg

林旭芳

亚马逊云科技解决方案架构师,主要负责 亚马逊云科技云技术和解决方案的推广工作,在 Container、主机、存储、容灾等方向有丰富实践经验。

0bd6ac2391c09e767dff9b4263816f22.jpeg

李俊杰

亚马逊云解决方案架构师,负责云计算方案的咨询与架构设计,同时致力于容器方面研究和推广。在加入亚马逊云科技之前曾在金融行业IT部门负责传统金融系统的现代化改造,对传统应用的改造,容器化具有丰富经验。

6733d2c41da13b001151049d3e52992b.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

e720a1e16af6688e029d1f875128e69a.gif

听说,点完下面4个按钮

就不会碰到bug了!

8bed653d9fc13a51879b93c978684ba0.gif

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

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

相关文章

Annotorious入门教程:图片注释工具

本文简介 最近有工友问我前端怎么给图片做标注。使用 Fabric.js 或者 Konva.js 等库确实可以实现&#xff0c;但我又好奇有没有专门做图片标注的工具呢&#xff1f; 在网上搜了一下发现 Annotorious 可以实现这个功能。Annotorious 提供了图片注释和标注功能&#xff0c;而且…

UVa10976 Fractions Again?!(分数拆分)

1、题目 2、题意 输入正整数 k k k&#xff0c;找到所有正整数 x ≥ y x \ge y x≥y&#xff0c;使得 1 k 1 x 1 y \frac{1}{k} \frac{1}{x} \frac{1}{y} k1​x1​y1​。 3、分析 既然要求找出所有的 x , y x,y x,y&#xff0c;枚举对象自然是 x , y x,y x,y了。可…

​Vue2【双向数据绑定/响应式原理】

目录 初始化 initProps()&#xff1a;父组件传的 props 列表&#xff0c;proxy() 把属性代理到当前实例上 vm._props.xx 变成 vm.xx initData()&#xff1a;判断data和props、methods是否重名&#xff0c;proxy() 把属性代理到当前实例上 this.xx observe()&#xff1a;给…

c++实现dijskstra算法

图 我一开始写成了最小生成树的代码&#xff0c;最小生成树一直在选最小的那条边&#xff0c;对每个节点来说&#xff0c;它到原点的距离不一定是最近的。 代码 #include<iostream> using namespace std; #include<list> #include<vector>class Node { pub…

RocketMQ事务消息 超时重发还是原来的消息吗?

以下面的一个demo例子来分析一下&#xff0c;探索RocketMQ事务消息原理。 public static final String PRODUCER_GROUP "tran-test";public static final String DEFAULT_NAMESRVADDR "127.0.0.1:9876";public static final String TOPIC "Test&qu…

如何理解Quadratic Weighted Kappa?

Motivation 假定我们现在有 N N N个作文样例&#xff0c;以及它们对应的人类评分和GPT评分。评分一共有 C C C个互斥类别&#xff0c;分别是{0,1,2,3}。现在我们要衡量人类评分和GPT评分的一致性。 一个很直观的想法是&#xff0c;画出混淆矩阵&#xff0c;然后将对角线上的值…

Linux Centos7安装后,无法查询到IP地址,无ens0,只有lo和ens33的解决方案

文章目录 前言1 查看network-scripts目录2 创建并配置 ifcfg-ens33 文件3 禁用NetworkManager4 重新启动网络服务总结 前言 在VMware中&#xff0c;安装Linux centos7操作系统后&#xff0c;想查询本机的IP地址&#xff0c;执行ifconfig命令 ifconfig结果如下&#xff1a; 结…

吴恩达《机器学习》1-5:模型描述

一、单变量线性回归 单变量线性回归是监督学习中的一种算法&#xff0c;通常用于解决回归问题。在单变量线性回归中&#xff0c;我们有一个训练数据集&#xff0c;其中包括一组输入特征&#xff08;通常表示为&#x1d465;&#xff09;和相应的输出目标&#xff08;通常表示为…

UVa140 Bandwidth(带宽)

1、题目 2、题意 给出一个 n &#xff08; n ≤ 8 &#xff09; n&#xff08;n≤8&#xff09; n&#xff08;n≤8&#xff09;个结点的图G和一个结点的排列&#xff0c;定义结点 i i i 的带宽 b ( i ) b(i) b(i) 为 i i i 和相邻结点在排列中的最远距离&#xff0c;而所…

Ansible上通过roles简化playbook演示介绍

目录 一.roles介绍 1.作用 2.role的目录结构 3.role和tasks的执行优先级顺序 二.自定义一个httpd的角色 1.完整目录结构展示 2.主要的各个目录配置 &#xff08;1&#xff09;vars目录和templates目录 &#xff08;2&#xff09;tasks目录和handlers目录 &#xff08…

操作系统中套接字和设备独立性软件的关系

网络编程就是编写程序让两台联网的计算机相互交换数据。在我们不需要考虑物理连接的情况下&#xff0c;我们只需要考虑如何编写传输软件。操作系统提供了名为“套接字”&#xff0c;套接字是网络传输传输用的软件设备。 这是对软件设备的解释&#xff1a; 在操作系统中&#…

Unity ScrollView最底展示

Unity ScrollView最底展示 问题方案逻辑 问题 比如在做聊天界面的时候我们肯定会使用到ScrollView来进行展示我们的聊天内容&#xff0c;那么这个时候来新消息的时候就需要最底展示&#xff0c;我认为这里有两种方案&#xff1b; 一种是通过算法每一条预制体的高度*一共多少…

轮转数组(Java)

大家好我是苏麟 , 这篇文章是凑数的 ... 轮转数组 描述 : 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 题目 : 牛客 NC110 旋转数组: 这里牛客给出了数组长度我们直接用就可以了 . LeetCode 189.轮转数组 : 189. 轮…

Python---break关键字对for...else结构的影响

for循环中添加else结构 循环可以和else配合使用&#xff0c; else下方缩进的代码指的是当循环正常结束之后要执行的代码。 强调&#xff1a; 循环 正常结束&#xff0c;else之后要执行的代码。 非正常结束&#xff0c;其else中的代码是不会执行的。&#xff08;如遇到br…

类和对象(1):类,对象,this指针

面向过程和面向对象初步认识&#xff1a; C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出问题求解的步骤&#xff0c;用函数调用逐步解决。C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完成。…

【.NET Core】创建一个在后台运行的控制台程序(ConsoleApp)

文章目录 1. 添加Nuget包2. 修改Program.cs3. 添加TestService 借助.NET的通用主机&#xff08;IHostBuilder&#xff09;可以轻易创建一个可以执行后台任务的程序 1. 添加Nuget包 Microsoft.Extensions.Hosting 2. 修改Program.cs 通过Host获取IHostService&#xff0c;然…

SSD: Single Shot MultiBox Detector(2016.11)

文章目录 AbstractIntroduction此前本文贡献总结如下: The Single Shot Detector (SSD)SSD ModelMulti-scale feature maps for detectionConvolutional predictors for detectionDefault boxes and aspect ratiosTrainingMatching strategyTraining objectiveChoosing scales …

python---for循环结构中的else结构(是同级关系)

为什么需要在for循环中添加else结构 循环可以和else配合使用&#xff0c; else下方缩进的代码指的是当循环正常结束之后要执行的代码。 强调&#xff1a; 循环 正常结束&#xff0c;else之后要执行的代码。 非正常结束&#xff0c;其else中的代码是不会执行的。&#xf…

GienTech动态|入选软件和信息技术服务名牌企业;荣获城市数字化转型优秀案例;参加第四届深圳国际人工智能展

中电金信入选“2023第二届软件和信息技术服务名牌企业” 近日&#xff0c;中国电子信息行业联合会发布了“2023第二届软件和信息技术服务名牌企业”名单&#xff0c;中电金信入选。此名单发布原则&#xff0c;重点突出技术创新力。突出市场影响力&#xff0c;品牌建设良好&…

Leetcode刷题笔记--Hot81--90

1--打家劫舍III 主要思路&#xff1a; 基于从下到上的 dp 回溯法&#xff0c;每一个节点只有两种状态&#xff0c;dp[0]表示被打劫&#xff0c;dp[1]表示不被打劫&#xff1b; 当前节点被打劫时&#xff0c;其孩子只能都不被打劫&#xff1b;dp[0] left[1] right[1] cur->…