工程

添加免费且开放的 Elastic APM 作为 Elastic 可观测性部署的一部分

在最近的一篇博文中,我们向大家介绍了如何开始使用 Elastic 可观测性的免费开放层。今天,我们将介绍扩展部署时所需的操作,以便您可以开始收集来自应用程序性能监测 (APM) 的指标,或者“跟踪”可观测性集群中的数据,所有这些都可以免费实现。

什么是 APM?

利用应用程序性能监测,您可以查看应用程序将时间花在哪些地方、在执行哪些操作、在调用哪些其他应用程序或服务,以及遇到了哪些错误或异常情况。

distributed-trace.png

此外,通过 APM,您还可以了解关键性能指标的历史记录和趋势,比如延迟和吞吐量,以及事务和依赖信息:

ruby-overview.png

无论您是针对 SLA 违规设置告警,还是要衡量最新版的影响,亦或是决定下次改进所涉及的方面,APM 都可以帮助您进行根本原因分析,进而改善用户体验,并让平均解决时间 (MTTR) 不断趋近于零。

逻辑架构

Elastic APM 依赖于 APM 服务器,后者会将应用程序跟踪和指标数据从安装有 APM 代理的应用程序转发到 Elastic 可观测性集群。Elastic APM 支持多种不同的代理类型:

  • 原生 Elastic APM 代理,支持多种语言,包括 Java、.NET、Go、Ruby、Python、Node.js、PHP 和客户端 JavaScript
  • 已装载 OpenTelemetry 测量工具的代码
  • 已装载 OpenTracing 测量工具的代码
  • 已装载 Jaeger 测量工具的代码


apm-diagram.png

在本篇博文中,我们会通过一个简单示例,说明如何使用原生 Elastic APM Ruby 代理来装载代码,但总体步骤其实与其他语言类似。

设置 APM 服务器

APM 服务器将跟踪和应用程序指标数据从 APM 代理转发到 Elasticsearch。要将 APM 数据添加到您的 Elastic 可观测性集群,我们可以按照 Kibana 本身提供的简要说明进行操作。在 Kibana 中,它会检测您是在 Elastic Cloud(我们的托管式 Elasticsearch 服务)中运行,还是在运行一个自管型集群。在我的这个示例中,运行的是自管型集群。在确认 Elasticsearch 和 Kibana 正在运行后,我们连接到 Kibana 实例。如果您不记得 Kibana URL,可以在 Kibana 日志的开头找到它。例如,我的日志是这样的:

log   [07:30:58.643] [info][server][Kibana][http] http server running at https://192.168.1.175:5601

登录到 Kibana(在我的示例中,使用 elastic/ThisIsTooEasy)后,单击“汉堡”图标,然后从主菜单中选择 APM,以前往 APM 应用:

navigate-to-apm.png

Kibana 检测到还没有任何 APM 数据,并提示我单击指向说明的链接:

add-some-apm.png

单击链接后便可以看到一组开始前应完成的简要步骤。apm-server-steps.png

我们大概按照说明进行操作就可以了;我使用的是自签名证书,因此我需要执行一些额外的步骤,但步骤大体上是相同的。 

  1. 下载 APM 服务器
  2. 将 APM 服务器连接到 Elasticsearch
  3. 将代理连接到 APM 服务器

第 1 步:下载 APM 服务器

Elastic APM 和 APM 服务器都是 Elastic 可观测性免费开放层的一部分 — 您可以根据需要查看源代码;如果想进行功能改进,可以提交拉取请求;如果遇到问题或有疑问,可以提交工单

按照 Kibana 中的说明,我们先从与操作系统对应的说明开始。我是在 Mac 上运行的,因此我要按照这些说明进行设置。第一步让我们下载 APM 服务器 tarball(或所选操作系统系列使用的任何安装包类型)并安装它。对于 MacOS,这只是意味着对其进行扩展并更改为新创建的目录:

curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-7.12.0-darwin-x86_64.tar.gz 
tar xzvf apm-server-7.12.0-darwin-x86_64.tar.gz 
cd apm-server-7.12.0-darwin-x86_64/

进入 apm-server-7.12.0-darwin-x86_64 目录后,我们会看到一些文件:

~/ELK/apm-server-7.12.0-darwin-x86_64 $ >ls -lF  
total 132724 
-rw-r--r--  1 jamie  staff    13K Mar 18 01:07 LICENSE.txt 
-rw-r--r--  1 jamie  staff   1.1M Mar 18 01:07 NOTICE.txt 
-rw-r--r--  1 jamie  staff   661B Mar 18 01:29 README.md 
-rwxr-xr-x  1 jamie  staff   123M Mar 18 03:11 apm-server* 
-rw-------  1 jamie  staff    52K Mar 18 01:08 apm-server.yml 
-rw-r--r--  1 jamie  staff   323K Mar 18 01:08 fields.yml 
drwxr-xr-x  3 jamie  staff    96B Mar 18 01:08 ingest/

包括一些文档、字段规范、配置文件和 APM 服务器可执行文件。

第 2 步:编辑 APM 服务器配置

在这里,我们将稍微脱离一下说明。我们仍将设置 Elasticsearch 输出部分:

output.elasticsearch:
  hosts: [""] 
  username:  
  password: 

但是,由于 Elasticsearch 使用的是自签名证书,因此我们也需要对它进行配置。

在我的示例中,Elasticsearch 正在侦听 https://192.168.1.175:9200,因此我们将使用它来设置 hostsprotocol 键的值:

output.elasticsearch:
  hosts: ["192.168.1.175:9200"] 
  protocol: "https"

我们可以使用 elastic 用户将 APM 服务器连接到 Elasticsearch,但 APM 服务器不需要超级用户权限。我将创建一个能够正常工作但权限最少的角色,并将它命名为 apm_server。我们会在 Kibana 中的“Security Management”(安全管理)部分执行此操作。要前往这个部分,请单击 Kibana 左上角的汉堡图标,然后前往 Stack Management(堆栈管理),我们可以在这里找到安全部分。依次单击 Roles(角色)、Create role(创建角色),并添加 apm_server 角色:

apm_server-role.png

然后保存。接下来,选择 Users(用户)→ Create user(创建用户),并添加 apm_server_user

apm-server-user.png

当然,您可以为角色和用户使用自己的名称,也可以如上所述,只用 elastic 用户进行试验。 

接下来,我们将需要使用的 usernamepassword 的凭据添加到配置中,如下所示:

output.elasticsearch:
  hosts: ["192.168.1.175:9200"] 
  protocol: "https" 
  username: "apm_server_user" 
  password:"ThisIsTooEasy"

我们快要能够启动 APM 服务器了,但如果我们现在启动的话,会遇到一个错误,提示有关证书是由未知机构签名的:

./apm-server -e 
{"log.level":"error","@timestamp":"2021-04-27T13:21:51.497-0400","log.logger":"publisher_pipeline_output","log.origin":{"file.name":"pipeline/output.go","file.line":154},"message":"Failed to connect to backoff(elasticsearch(https://192.168.1.175:9200)):Get \"https://192.168.1.175:9200\": x509: certificate signed by unknown authority","ecs.version":"1.6.0"}

为了缓解这种情况,我们需要告知 APM 服务器关于证书颁发机构的信息。在我的示例中,这些信息位于 ~/ELK/elasticsearch 文件夹下。首先,我们将 ca.crt 复制到 APM 服务器的目录层次结构(我们可以从它所在位置直接引用,但在真实环境中,您可能会在不同的主机上运行每个服务):

cp ~/ELK/elasticsearch/ca/ca.crt .

然后,通过向 apm_server.ymlelasticsearch.output 部分添加另一个键,将新的 ca.crt 指定为颁发机构:

output.elasticsearch:
  hosts: ["192.168.1.175:9200"] 
  protocol: "https" 
  username: "elastic" 
  password:"ThisIsTooEasy" 
  ssl:
    certificate_authorities: ['certs/ca.crt']

第 3 步:启动 APM 服务器

我们现在可以启动 APM 服务器了。它将连接到 Elasticsearch,但现在它只侦听 localhost。我想对配置再做一处更改,以便让它能够侦听主机 IP,而不仅仅是 localhost,这样防火墙后面的其他主机就可以访问到它。在 apm-server.yml 文件的开头附近有一个地方可以进行这项更改。我的 APM 服务器将在我运行其他资源的同一机器上运行,所以我会使用相同的 192.168.1.175 地址,现在的配置如下所示:

apm-server:
  # 定义服务器要侦听的主机和端口。使用 "unix:/path/to.sock" 侦听 unix 域套接字。              
  host:"192.168.1.175:8200"

最终,我们可以使用 ./apm-server -e 启动 APM 服务器(-e 会使它只登录到控制台,这在启动时很有用)。

如果我们回到 Kibana,APM 应用中仍然没有显示任何内容,但有一个小按钮 Check APM Server status 可以检查 APM 服务器的状态。单击这个按钮,应该会收到您已正确设置 APM 服务器这条令人满意的消息:

correctly-set-up-apm.png

您可能还注意到,在状态检查下方还有一个关于 APM 代理的部分

apm-agent-instructions.png

我们不妨在这一部分获取一些真实的装载测量工具数据!

使用 Elastic APM 代理装载示例代码

各种语言代理的指令会因编程语言而有所不同,但大致流程相似。首先,在语言的本机规范中添加代理的依赖项,然后配置代理,让它知道如何查找 APM 服务器。

您可以尝试任何您喜欢的类型,但我将使用我找到的全栈 Ruby 示例 来演练 Ruby on Rails 说明。我在运行这个示例时确实遇到了一个问题,原来是类似于这个的 bootsnap 缓存问题。这个问题通过在我的 docker 文件中添加一行就可以解决:

volumes:
      - .:/app 
      # 不要挂载 tmp 目录 
      - /app/tmp

它包含在我的上述存储库的分叉中。

获取示例代码(也可用自己的代码)

首先,我克隆 GitHub 存储库,然后更改到以下目录:

git clone https://github.com/jamiesmith/docker-rails-example.git 
cd docker-rails-example

(如果没有安装 git,只需下载一个 zip 文件并将其解压缩即可)

添加依赖项

按照说明,我编辑了项目的依赖项规范(如果用的是 Ruby,那就是 Gemfile),并添加了 gem 'elastic-apm'

我把它放在了靠近顶部的位置:

source 'https://rubygems.org' 
git_source(:github) { |repo| "https://github.com/#{repo}.git" } 
ruby '2.7.2' 
# 启用 Elastic APM 
gem 'elastic-apm' 
# 捆绑边缘 Rails 代替:gem 'rails', github: 'rails/rails' 
gem 'rails', '~> 6.1.0'

保存文件并继续下一步 — 开始配置代理。

请注意,完整的 Gemfile 作为 Gemfile.elastic-apm 包含在存储库中。

配置代理

代理需要将应用程序跟踪数据发送到 APM 服务器,所以必须能够访问到它。如果您还记得,我们的配置是侦听主机 IP,因此子网中的任何应用程序都可以向它发送数据。我们需要在项目中添加另一个文件,以在项目开始时进行选取。在项目顶部的 config 目录下新建一个文件,并添加以下类似于 docs 的注释:

# 设置服务名称 - 允许使用的字符:a-z、A-Z、0-9、-、_ 和空格 
# 默认为 Rails 应用的名称 
service_name: 'my-service' 
# APM 服务器需要密钥令牌时使用 
# secret_token: '' 
# 设置自定义 APM 服务器 URL(默认:http://localhost:8200) 
server_url: 'http://192.168.1.175:8200' 
# 设置服务环境 
environment: 'production'

对上述注释的一些解释:

  • service_name: 如果您忽略此项,它将默认为应用程序的名称,但您可以在此处覆盖这个名称。
  • secret_token: 使用密钥令牌,您可以授权对 APM 服务器的请求,但 APM 服务器必须设置了 SSL/TLS,并且已设置密钥令牌。我们没有在代理和 APM 服务器之间使用 HTTPS,因此我们会将这项注释掉。
  • server_url: 这是代理能够访问 APM 服务器的方式,请将它替换为主机的名称或 IP。
  • environment: 这允许您向服务添加元数据。例如,您可能在 QA 中有一个版本,在生产中有另一个版本。

请注意,示例 config 文件作为 config/elastic_apm.yml.elastic-apm 包含在存储库中。

至此,Elastic APM 端的配置已经完成,接下来只需按照 README 中的步骤启动即可。我们复制两个文件,然后构建并运行:

cp .env.example .env 
cp docker-compose.override.yml.example docker-compose.override.yml 
docker-compose up --build

构建步骤将需要几分钟的时间。完成后,在同一目录的另一个终端窗口中,运行 ./run rails db:setup 来设置初始数据库。

您可以通过访问 http://localhost:8000http://localhost:8000/up 前往正在运行的示例应用程序。虽然样本数量不多,但它确实生成了一些 APM 数据。要生成一点负载,您可以重新加载几次,也可以运行一个快速加载的小脚本:

while [ 1 ] 
do 
    curl localhost:8000/up 
    curl localhost:8000  
    sleep 1  
done

这样每秒都会重新加载页面。

返回 Kibana,重新转到 APM 应用(单击汉堡图标,然后选择 APM),您应该会看到新的 my service 服务(我运行了我的服务,所以它显示了更多的历史记录):

my-service.png

服务概述页面对服务运行状况提供了一个总体性的概述。如果您是开发人员或 SRE,可以从这个页面中查看以下几个方面: 

  • 新部署对性能有何影响?
  • 对哪些事务的影响最大?
  • 性能如何与底层基础架构相关联?

这个视图列出了在指定时间段内(本例中为过去 15 分钟)向 Elastic APM 发送应用程序跟踪数据的所有应用程序。此外,还有以迷你图形式显示延迟、吞吐量和错误率的波形图。单击 my-service,即会转到服务概述页面,其中显示了服务中的各种事务(回想一下,我的脚本正在命中 //up 终端,它们是 PageController 的一部分,如事务部分所示)。我们看到的图表,比如延迟吞吐量错误错误率(目前尚未出现错误)会更大,并且列出了此服务所依赖的服务和应用程序,在本例中,它所依赖的唯一服务是 Postgres:

my-service-details.png

当您在真实负载下装载实际应用程序时,您将看到更多的连接(和错误!)

errors-and-dependencies.png

单击事务视图中的事务(在本例中,显示的是我们示例应用的 PagesController#up 事务),我们可以确切地看到调用了哪些操作:

page-controller-up.png

或者,如果是更为复杂的调用其他微服务和外部服务的事务,我们看到的细节会更多:

java-trace.png

包括有关调用外部服务(如数据库查询)的详细信息:

database-query.png

后续操作

至此,您的 Elastic 可观测性集群已设置好并开始运行,收集了开箱即用的应用程序跟踪数据。接下来会探索您的应用程序所用语言的公共 API,这会让您将 APM 数据提升到下一个级别。使用这些 API,您可以添加定制元数据,定义业务事务,创建定制范围等。您可以在 APM 代理文档页面上找到各种 APM 代理(例如 JavaRuby 等)的公共 API 规范。如果您想了解有关 Elastic APM 的更多信息,请查看关于 Elastic APM 转向云原生的网络研讨会,了解 Elastic APM 可在您的生态系统中助您一臂之力的其他方式。

如果您决定让我们托管您的可观测性集群,则可以进行注册,以在 Elastic Cloud 上免费试用 Elasticsearch Service,并将您的代理更改为指向您的新集群。
  • We're hiring

    Work for a global, distributed team where finding someone like you is just a Zoom meeting away. Flexible work with impact? Development opportunities from the start?