This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

调试与故障排除

帮助用户调试和诊断 Dapr 问题的工具、技术和常见问题

1 - 运行 Dapr 时的常见问题

运行 Dapr 应用程序时遇到的常见问题和故障

本指南涵盖了在安装和运行 Dapr 时可能遇到的常见问题。

安装 Dapr CLI 时 Dapr 无法连接到 Docker

在安装和初始化 Dapr CLI 时,如果运行 dapr init 后看到以下错误消息:

⌛  Making the jump to hyperspace...
❌  could not connect to docker. docker may not be installed or running

通过确保以下内容来排查错误:

  1. 正确的容器正在运行。

  2. 在 Docker Desktop 中,验证已选择 Allow the default Docker socket to be used (requires password) 选项。

我没有看到 Dapr 边车注入到我的 pod 中

边车可能无法注入到 pod 中有多种原因。 首先,检查您的 deployment 或 pod YAML 文件,并检查您是否在正确的位置具有以下注解:

annotations:
  dapr.io/enabled: "true"
  dapr.io/app-id: "nodeapp"
  dapr.io/app-port: "3000"

示例 deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodeapp
  namespace: default
  labels:
    app: node
spec:
  replicas: 1
  selector:
    matchLabels:
      app: node
  template:
    metadata:
      labels:
        app: node
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "nodeapp"
        dapr.io/app-port: "3000"
    spec:
      containers:
      - name: node
        image: dapriosamples/hello-k8s-node
        ports:
        - containerPort: 3000
        imagePullPolicy: Always

在某些已知情况下,这可能无法正常工作:

  • 如果您的 pod 规范模板已正确注解,但您仍然没有看到边车注入,请确保 Dapr 在您的 deployment 或 pod 部署之前已部署到集群。

    如果是这种情况,重启 pod 将解决此问题。

  • 如果您在私有 GKE 集群上部署 Dapr,边车注入在无需额外步骤的情况下无法工作。请参阅设置 Google Kubernetes Engine 集群

    为了进一步诊断任何问题,请检查 Dapr 边车注入器的日志:

     kubectl logs -l app=dapr-sidecar-injector -n dapr-system
    

    注意:如果您将 Dapr 安装到不同的命名空间,请将上面的 dapr-system 替换为所需的命名空间

  • 如果您在 Amazon EKS 上部署 Dapr 并使用 Calico 等覆盖网络,您需要将 hostNetwork 参数设置为 true,这是使用此类 CNI 的 EKS 的限制。

    您可以使用 Helm values.yaml 文件设置此参数:

    helm upgrade --install dapr dapr/dapr \
    --namespace dapr-system \
    --create-namespace \
    --values values.yaml
    

    values.yaml

    dapr_sidecar_injector:
      hostNetwork: true
    

    或使用命令行:

    helm upgrade --install dapr dapr/dapr \
    --namespace dapr-system \
    --create-namespace \
    --set dapr_sidecar_injector.hostNetwork=true
    
  • 确保 kube api 服务器可以到达以下 webhook 服务:

    请与您的集群管理员联系,以设置允许从 kube api 服务器到集群中上述端口 400019443 的入站规则。

我的 pod 处于 CrashLoopBackoff 或其他由于 daprd 边车导致的失败状态

如果 Dapr 边车 (daprd) 初始化时间过长,这可能被 Kubernetes 显示为运行状况检查失败。

如果您的 pod 处于失败状态,您应该检查以下内容:

kubectl describe pod <name-of-pod>

您可能会在命令输出的末尾看到如下表格:

  Normal   Created    7m41s (x2 over 8m2s)   kubelet, aks-agentpool-12499885-vmss000000  Created container daprd
  Normal   Started    7m41s (x2 over 8m2s)   kubelet, aks-agentpool-12499885-vmss000000  Started container daprd
  Warning  Unhealthy  7m28s (x5 over 7m58s)  kubelet, aks-agentpool-12499885-vmss000000  Readiness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
  Warning  Unhealthy  7m25s (x6 over 7m55s)  kubelet, aks-agentpool-12499885-vmss000000  Liveness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
  Normal   Killing    7m25s (x2 over 7m43s)  kubelet, aks-agentpool-12499885-vmss000000  Container daprd failed liveness probe, will be restarted
  Warning  BackOff    3m2s (x18 over 6m48s)  kubelet, aks-agentpool-12499885-vmss000000  Back-off restarting failed container

消息 Container daprd failed liveness probe, will be restarted 表示 Dapr 边车未能通过其运行状况检查并将被重启。消息 Readiness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refusedLiveness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused 显示运行状况检查失败,因为无法建立到边车的连接。

此失败的最常见原因是组件(例如状态存储)配置错误,导致初始化时间过长。当初始化耗时较长时,运行状况检查可能会在边车记录任何有用的信息之前终止边车。

要诊断根本原因:

  • 显著增加存活探针延迟 - 链接
  • 将边车的日志级别设置为 debug - 链接
  • 观察日志以获取有意义的信息 - 链接

请记得在解决问题后将存活检查延迟和日志级别配置回所需的值。

我无法保存状态或获取状态

您是否在集群中安装了 Dapr 状态存储?

要检查,请使用 kubectl 获取组件列表:

kubectl get components

如果没有状态存储组件,这意味着您需要设置一个。 访问这里了解更多详情。

如果一切设置正确,请确保您的凭据正确。 搜索 Dapr 运行时日志并查找任何状态存储错误:

kubectl logs <name-of-pod> daprd

我无法发布和接收事件

您是否在集群中安装了 Dapr 消息总线?

要检查,请使用 kubectl 获取组件列表:

kubectl get components

如果没有发布订阅组件,这意味着您需要设置一个。 访问这里了解更多详情。

如果一切设置正确,请确保您的凭据正确。 搜索 Dapr 运行时日志并查找任何发布订阅错误:

kubectl logs <name-of-pod> daprd

调用 Dapr 时收到 500 错误响应

这意味着 Dapr 运行时内部存在一些问题。 要诊断,请查看边车的日志:

kubectl logs <name-of-pod> daprd

调用 Dapr 时收到 404 Not Found 响应

这意味着您正在尝试调用一个不存在或 URL 格式错误的 Dapr API 端点。 查看这里的 Dapr API 参考,并确保您调用了正确的端点。

我没有看到来自其他服务的传入事件或调用

您是否指定了您的应用程序正在侦听的端口? 在 Kubernetes 中,确保指定了 dapr.io/app-port 注解:

annotations:
  dapr.io/enabled: "true"
  dapr.io/app-id: "nodeapp"
  dapr.io/app-port: "3000"

如果使用 Dapr Standalone 和 Dapr CLI,请确保将 --app-port 标志传递给 dapr run 命令。

我的启用 Dapr 的应用程序行为不正确

首先要做的是检查从 Dapr API 返回的 HTTP 错误代码(如果有)。 如果您仍然找不到问题,请尝试为 Dapr 运行时启用 debug 日志级别。请参阅这里了解如何执行此操作。

您可能还希望查看您自己进程的错误日志。如果在 Kubernetes 上运行,请找到包含您的应用程序的 pod,并执行以下命令:

kubectl logs <pod-name> <name-of-your-container>

如果在 Standalone 模式下运行,您应该在主控制台会话中看到来自您应用程序的 stderr 和 stdout 输出。

在本地运行 Actors 时出现超时/连接错误

每个 Dapr 实例都会将其主机地址报告给 placement 服务。然后,placement 服务将节点表及其地址分发给所有 Dapr 实例。如果该主机地址不可达,您可能会遇到套接字超时错误或其他请求失败的变体。

除非通过将名为 DAPR_HOST_IP 的环境变量设置为可访问、可 ping 的地址来指定主机名,否则 Dapr 将循环遍历网络接口并选择它找到的第一个非环回地址。

如上所述,为了告诉 Dapr 应该使用什么主机名,只需设置一个名为 DAPR_HOST_IP 的环境变量。

以下示例展示了如何将主机 IP 环境变量设置为 127.0.0.1

注意:对于 <= 0.4.0 版本,使用 HOST_IP

export DAPR_HOST_IP=127.0.0.1

当我的应用程序启动时,我的组件都没有被加载。我一直收到"Error component X cannot be found"

这通常是由于以下问题之一

  • 您可能在本地定义了 NAMESPACE 环境变量,或者将组件部署到 Kubernetes 中的不同命名空间。检查您的应用程序和组件部署到哪个命名空间。阅读将组件限定为一个或多个应用程序以获取更多信息。
  • 您可能没有为 Dapr run 命令提供 --resources-path,或者没有将组件放入您操作系统的默认组件文件夹中。阅读定义组件以获取更多信息。
  • 您可能在组件 YAML 文件中有语法问题。使用组件 YAML 示例检查您的组件 YAML。

服务调用失败,我的 Dapr 服务缺少 appId(macOS)

某些组织将实现过滤掉所有 UDP 流量的软件,这是 mDNS 所基于的。最常见的是,在 MacOS 上,Microsoft Content Filter 是罪魁祸首。

为了使 mDNS 正常运行,请确保 Microsoft Content Filter 处于非活动状态。

  • 打开终端 shell。
  • 输入 mdatp system-extension network-filter disable 并按回车键。
  • 输入您的帐户密码。

当输出为"Success"时,Microsoft Content Filter 已被禁用。

某些组织会不时重新启用过滤器。如果您反复遇到 app-id 值缺失的情况,在进行更广泛的故障排除之前,请首先检查过滤器是否已重新启用。

Admission webhook 拒绝了请求

您可能会遇到与以下类似的错误,由于 admission webhook 对服务帐户创建或修改资源有允许列表。

root:[dapr]$ kubectl run -i --tty --rm debug --image=busybox --restart=Never -- sh
Error from server: admission webhook "sidecar-injector.dapr.io" denied the request: service account 'user-xdd5l' not on the list of allowed controller accounts

要解决此错误,您应该为当前用户创建一个 clusterrolebind

kubectl create clusterrolebinding dapr-<name-of-user> --clusterrole=dapr-operator-admin --user <name-of-user>

您可以运行以下命令来获取集群中的所有用户:

kubectl config get-users

您可以在这里了解更多关于 webhook 的信息。

dapr init 期间端口不可用

在 Windows 上尝试执行 dapr init 后,您可能会遇到以下错误:

PS C:\Users\You> dapr init Making the jump to hyperspace… Container images will be pulled from Docker Hub Installing runtime version 1.14.4 Downloading binaries and setting up components… docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:52379 -> 0.0.0.0:0: listen tcp4 0.0.0.0:52379: bind: An attempt was made to access a socket in a way forbidden by its access permissions.

要解决此错误,请在提升的终端中打开命令提示符并运行:

net stop winnat
dapr init
net start winnat

2 - 配置和查看 Dapr 日志

了解 Dapr 中的日志工作原理以及如何配置和查看日志

本节将帮助您了解 Dapr 中的日志工作原理,以及如何配置和查看日志。

概述

日志具有不同的、可配置的详细程度级别。 下面列出的级别对于系统组件和 Dapr 边车进程/容器都是相同的:

  1. error
  2. warn
  3. info
  4. debug

error 产生最少的输出,而 debug 产生最多的输出。默认级别是 info,它在正常条件下运行 Dapr 时提供平衡的信息量。

要设置输出级别,您可以使用 --log-level 命令行选项。例如:

./daprd --log-level error
./placement --log-level debug

这将启动日志级别为 error 的 Dapr 运行时二进制文件和日志级别为 debug 的 Dapr Actor Placement 服务。

独立模式下的日志

在使用 Dapr CLI 运行应用时设置日志级别,传递 log-level 参数:

dapr run --log-level warn node myapp.js

如上所述,每个 Dapr 二进制文件都接受 --log-level 参数。例如,要使用警告日志级别启动 placement 服务:

./placement --log-level warn

在独立模式下查看日志

使用 Dapr CLI 运行 Dapr 时,您的应用的日志输出和运行时的输出都将被重定向到同一会话中,以便于调试。 例如,这是运行 Dapr 时的输出:

dapr run node myapp.js
ℹ️  Starting Dapr with id Trackgreat-Lancer on port 56730
✅  You are up and running! Both Dapr and your app logs will appear here.

== APP == App listening on port 3000!
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="starting Dapr Runtime -- version 0.3.0-alpha -- commit b6f2810-dirty"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="log level set to: info"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="standalone mode configured"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="app id: Trackgreat-Lancer"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component statestore (state.redis)"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component messagebus (pubsub.redis)"
== DAPR == 2019/09/05 12:26:43 redis: connecting to localhost:6379
== DAPR == 2019/09/05 12:26:43 redis: connected to localhost:6379 (localAddr: [::1]:56734, remAddr: [::1]:6379)
== DAPR == time="2019-09-05T12:26:43-07:00" level=warn msg="failed to init input bindings: app channel not initialized"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: starting connection attempt to placement service at localhost:50005"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="http server is running on port 56730"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="gRPC server is running on port 56731"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="dapr initialized. Status: Running. Init Elapsed 8.772922000000001ms"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: established connection to placement service at localhost:50005"

Kubernetes 模式下的日志

了解如何在 Kubernetes 上调试 daprd

您可以通过在 pod 规范模板中提供以下注释来为每个边车单独设置日志级别:

annotations:
  dapr.io/log-level: "debug"

设置系统 Pod 的日志级别

使用 Helm 3.x 将 Dapr 部署到集群时,您可以为每个 Dapr 系统组件单独设置日志级别:

helm install dapr dapr/dapr --namespace dapr-system --set <COMPONENT>.logLevel=<LEVEL>

组件:

  • dapr_operator
  • dapr_placement
  • dapr_sidecar_injector

示例:

helm install dapr dapr/dapr --namespace dapr-system --set dapr_operator.logLevel=error

在 Kubernetes 上查看日志

Dapr 日志被写入 stdout 和 stderr。 本节将指导您如何查看 Dapr 系统组件以及 Dapr 边车的日志。

边车日志

在 Kubernetes 中部署时,Dapr 边车注入器会将名为 daprd 的 Dapr 容器注入到带注释的 pod 中。 要查看边车的日志,只需运行 kubectl get pods 找到相关 pod:

NAME                                        READY     STATUS    RESTARTS   AGE
addapp-74b57fb78c-67zm6                     2/2       Running   0          40h

接下来,获取 Dapr 边车容器的日志:

kubectl logs addapp-74b57fb78c-67zm6 -c daprd

time="2019-09-04T02:52:27Z" level=info msg="starting Dapr Runtime -- version 0.3.0-alpha -- commit b6f2810-dirty"
time="2019-09-04T02:52:27Z" level=info msg="log level set to: info"
time="2019-09-04T02:52:27Z" level=info msg="kubernetes mode configured"
time="2019-09-04T02:52:27Z" level=info msg="app id: addapp"
time="2019-09-04T02:52:27Z" level=info msg="application protocol: http. waiting on port 6000"
time="2019-09-04T02:52:27Z" level=info msg="application discovered on port 6000"
time="2019-09-04T02:52:27Z" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
time="2019-09-04T02:52:27Z" level=info msg="actors: starting connection attempt to placement service at dapr-placement.dapr-system.svc.cluster.local:80"
time="2019-09-04T02:52:27Z" level=info msg="http server is running on port 3500"
time="2019-09-04T02:52:27Z" level=info msg="gRPC server is running on port 50001"
time="2019-09-04T02:52:27Z" level=info msg="dapr initialized. Status: Running. Init Elapsed 64.234049ms"
time="2019-09-04T02:52:27Z" level=info msg="actors: established connection to placement service at dapr-placement.dapr-system.svc.cluster.local:80"

系统日志

Dapr 运行以下系统 Pod:

  • Dapr operator
  • Dapr sidecar injector
  • Dapr placement service

Operator 日志

kubectl logs -l app=dapr-operator -n dapr-system

I1207 06:01:02.891031 1 leaderelection.go:243] attempting to acquire leader lease dapr-system/operator.dapr.io...
I1207 06:01:02.913696 1 leaderelection.go:253] successfully acquired lease dapr-system/operator.dapr.io
time="2021-12-07T06:01:03.092529085Z" level=info msg="getting tls certificates" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.092703283Z" level=info msg="tls certificates loaded successfully" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.093062379Z" level=info msg="starting gRPC server" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator.api type=log ver=unknown
time="2021-12-07T06:01:03.093123778Z" level=info msg="Healthz server is listening on :8080" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.497889776Z" level=info msg="starting webhooks" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
I1207 06:01:03.497944 1 leaderelection.go:243] attempting to acquire leader lease dapr-system/webhooks.dapr.io...
I1207 06:01:03.516641 1 leaderelection.go:253] successfully acquired lease dapr-system/webhooks.dapr.io
time="2021-12-07T06:01:03.526202227Z" level=info msg="Successfully patched webhook in CRD "subscriptions.dapr.io"" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown

注意:如果 Dapr 被安装到 dapr-system 以外的命名空间,只需在上述命令中将命名空间替换为所需的命名空间

边车注入器日志

kubectl logs -l app=dapr-sidecar-injector -n dapr-system

time="2021-12-07T06:01:01.554859058Z" level=info msg="log level set to: info" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.555114755Z" level=info msg="metrics server started on :9090/" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.metrics type=log ver=unknown
time="2021-12-07T06:01:01.555233253Z" level=info msg="starting Dapr Sidecar Injector -- version 1.5.1 -- commit c6daae8e9b11b3e241a9cb84c33e5aa740d74368" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.557646524Z" level=info msg="Healthz server is listening on :8080" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.621291968Z" level=info msg="Sidecar injector is listening on :4000, patching Dapr-enabled pods" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown

注意:如果 Dapr 被安装到 dapr-system 以外的命名空间,只需在上述命令中将命名空间替换为所需的命名空间

查看 Placement 服务日志

kubectl logs -l app=dapr-placement-server -n dapr-system

time="2021-12-04T05:08:05.733416791Z" level=info msg="starting Dapr Placement Service -- version 1.5.0 -- commit 83fe579f5dc93bef1ce3b464d3167a225a3aff3a" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=unknown
time="2021-12-04T05:08:05.733469491Z" level=info msg="log level set to: info" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.733512692Z" level=info msg="metrics server started on :9090/" instance=dapr-placement-server-0 scope=dapr.metrics type=log ver=1.5.0
time="2021-12-04T05:08:05.735207095Z" level=info msg="Raft server is starting on 127.0.0.1:8201..." instance=dapr-placement-server-0 scope=dapr.placement.raft type=log ver=1.5.0
time="2021-12-04T05:08:05.735221195Z" level=info msg="mTLS enabled, getting tls certificates" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735265696Z" level=info msg="tls certificates loaded successfully" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735276396Z" level=info msg="placement service started on port 50005" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735553696Z" level=info msg="Healthz server is listening on :8080" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:07.036850257Z" level=info msg="cluster leadership acquired" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:07.036909357Z" level=info msg="leader is established." instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0

注意:如果 Dapr 被安装到 dapr-system 以外的命名空间,只需在上述命令中将命名空间替换为所需的命名空间

非 Kubernetes 环境

上面的示例专门针对 Kubernetes,但原理对于任何基于容器的环境都是相同的:只需获取 Dapr 边车和/或系统组件(如适用)的容器 ID 并查看其日志。

参考

3 - Dapr API 日志

了解 Dapr 中的 API 日志记录是如何工作的以及如何查看日志

API 日志记录使您能够查看您的应用程序向 Dapr 边车发出的 API 调用。这对于监控应用程序的行为或其他调试目的非常有用。您还可以将 Dapr API 日志记录与 Dapr 日志事件(参见 配置和查看 Dapr 日志)结合到输出中,以便一起使用日志记录功能。

概述

默认情况下,API 日志记录是禁用的。

要启用 API 日志记录,可以在启动 daprd 进程时使用 --enable-api-logging 命令行选项。例如:

./daprd --enable-api-logging

在自托管模式下配置 API 日志记录

要在使用 Dapr CLI 运行应用程序时启用 API 日志记录,请传递 --enable-api-logging 标志:

dapr run \
  --enable-api-logging \
  -- node myapp.js

在自托管模式下查看 API 日志

当使用 Dapr CLI 运行 Dapr 时,您的应用程序日志输出和 Dapr 运行时日志输出都会被重定向到同一个会话中,以便于调试。

下面的示例显示了一些 API 日志:

$ dapr run --enable-api-logging -- node myapp.js

ℹ️  Starting Dapr with id order-processor on port 56730
✅  You are up and running! Both Dapr and your app logs will appear here.
.....
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="POST /v1.0/state/mystate" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Saving Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="GET /v1.0/state/mystate/key123" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Getting Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="DELETE /v1.0/state/mystate" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Deleted Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="PUT /v1.0/metadata/cliPID" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge

在 Kubernetes 中配置 API 日志记录

您可以通过在 Pod 规范模板中添加以下注解来为边车启用 API 日志:

annotations:
  dapr.io/enable-api-logging: "true"

在 Kubernetes 上查看 API 日志

Dapr API 日志会被写入 stdout 和 stderr,您可以在 Kubernetes 上查看 API 日志。

执行以下命令以查看 Kubernetes API 日志。

kubectl logs <pod_name> daprd -n <name_space>

下面的示例显示了 Kubernetes 中 info 级别的 API 日志记录(启用了 URL 混淆)。

time="2022-03-16T18:32:02.487041454Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:02.698387866Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:02.917629403Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:03.137830112Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:03.359097916Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge

API 日志记录配置

使用 Dapr 配置规范,您可以配置 Dapr 运行时中 API 日志记录的默认行为。

默认启用 API 日志记录

使用 Dapr 配置规范,您可以通过 logging.apiLogging.enabled 选项设置 --enable-api-logging 标志(以及在 Kubernetes 上运行时对应的注解)的默认值。此值适用于引用定义该选项的配置文档或资源的所有 Dapr 运行时。

  • 如果 logging.apiLogging.enabled 设置为 false(默认值),则除非将 --enable-api-logging 设置为 true(或添加 dapr.io/enable-api-logging: true 注解),否则 Dapr 运行时的 API 日志记录将被禁用。
  • logging.apiLogging.enabledtrue 时,Dapr 运行时默认启用 API 日志记录,可以通过设置 --enable-api-logging=false 或使用 dapr.io/enable-api-logging: false 注解来禁用。

例如:

logging:
  apiLogging:
    enabled: true

在 HTTP API 日志记录中混淆 URL

默认情况下,HTTP 端点中 API 调用的日志包含被调用的完整 URL(例如,POST /v1.0/invoke/directory/method/user-123),其中可能包含个人身份信息(PII)。

为了降低 PII 意外包含在 API 日志中的风险(启用时),Dapr 可以改为记录被调用的抽象路由(例如,POST /v1.0/invoke/{id}/method/{method:*})。这有助于确保遵守 GDPR 等隐私法规。

要在 Dapr 的 HTTP API 日志中启用 URL 混淆,请将 logging.apiLogging.obfuscateURLs 设置为 true。例如:

logging:
  apiLogging:
    obfuscateURLs: true

Dapr gRPC API 发出的日志不受此配置选项的影响,因为它们仅包含被调用方法的名称,不包含参数。

从 API 日志记录中省略健康检查

当启用 API 日志记录时,对 Dapr API 服务器的所有调用都会被记录,包括对健康检查端点的调用(例如 /v1.0/healthz)。根据您的环境,这每分钟可能会生成多个日志行,并可能产生不必要的噪音。

您可以使用 Dapr 配置规范配置 Dapr 在启用 API 日志记录时不记录对健康检查端点的调用,方法是将 logging.apiLogging.omitHealthChecks 设置为 true。默认值为 false,这意味着健康检查调用会记录在 API 日志中。

例如:

logging:
  apiLogging:
    omitHealthChecks: true

4 - 性能分析与调试

通过性能分析会话发现并发、性能、CPU 和内存使用等方面的问题和隐患

在任何真实场景中,应用程序可能会出现资源方面的异常行为。 在大多数情况下,CPU/内存飙升并不罕见。

Dapr 允许用户通过其性能分析服务端点使用 pprof 启动按需性能分析会话,并启动检测会话以发现并发、性能、CPU 和内存使用等方面的问题和隐患。

启用性能分析

Dapr 允许您在 Kubernetes 和独立模式两种模式下启用性能分析。

独立模式

要在独立模式下启用性能分析,请将 --enable-profiling--profile-port 标志传递给 Dapr CLI: 请注意 profile-port 不是必需的,如果未提供,Dapr 将选择一个可用端口。

dapr run --enable-profiling --profile-port 7777 python myapp.py

Kubernetes

要在 Kubernetes 中启用性能分析,只需将 dapr.io/enable-profiling 注解添加到您的 Dapr 注解 pod 中:

   annotations:
    dapr.io/enabled: "true"
    dapr.io/app-id: "rust-app"
    dapr.io/enable-profiling: "true"

调试性能分析会话

启用性能分析后,我们可以启动性能分析会话来调查 Dapr 运行时发生了什么。

独立模式

对于独立模式,找到您想要分析的 Dapr 实例:

dapr list
APP ID           DAPR PORT     APP PORT  COMMAND      AGE  CREATED              PID
node-subscriber  3500          3000      node app.js  12s  2019-09-09 15:11.24  896

获取 DAPR PORT,如果已按照上述说明启用了性能分析,您现在可以开始使用 pprof 来分析 Dapr。 查看上面的 Kubernetes 示例,获取一些用于分析 Dapr 的有用命令。

有关 pprof 的更多信息可以在这里找到。

Kubernetes

首先,找到包含 Dapr 运行时的 pod。如果您还不知道 pod 名称,请输入 kubectl get pods

NAME                                        READY     STATUS    RESTARTS   AGE
divideapp-6dddf7dc74-6sq4l                  2/2       Running   0          2d23h

如果性能分析已成功启用,运行时日志应显示以下内容: time="2019-09-09T20:56:21Z" level=info msg="starting profiling server on port 7777"

在这种情况下,我们要与 pod divideapp-6dddf7dc74-6sq4l 内的 Dapr 运行时启动会话。

我们可以通过端口转发连接到 pod 来实现:

kubectl port-forward divideapp-6dddf7dc74-6sq4 7777:7777
Forwarding from 127.0.0.1:7777 -> 7777
Forwarding from [::1]:7777 -> 7777
Handling connection for 7777

既然连接已经建立,我们可以使用 pprof 来分析 Dapr 运行时。

以下示例将创建一个 cpu.pprof 文件,其中包含持续 120 秒的性能分析会话的采样:

curl "http://localhost:7777/debug/pprof/profile?seconds=120" > cpu.pprof

使用 pprof 分析文件:

pprof cpu.pprof

您还可以将结果以可视化方式保存到 PDF 中:

go tool pprof --pdf your-binary-file http://localhost:7777/debug/pprof/profile?seconds=120 > profile.pdf

对于内存相关问题,您可以分析堆:

go tool pprof --pdf your-binary-file http://localhost:7777/debug/pprof/heap > heap.pdf

heap

分析已分配的对象:

go tool pprof http://localhost:7777/debug/pprof/heap
> exit

Saved profile in /Users/myusername/pprof/pprof.daprd.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz

要进行分析,请获取上面的文件路径(这是一个动态文件路径,所以请注意记录并粘贴这个路径),然后执行:

go tool pprof -alloc_objects --pdf /Users/myusername/pprof/pprof.daprd.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz > alloc-objects.pdf

alloc