工程

添加免费且开放的 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,并将您的代理更改为指向您的新集群。
ElasticON Global 2021

Join us at ElasticON Global for free!

Our biggest event of the year is back Oct 5-7. Take your organization's search, observability, or security capabilities to a whole new level.