Elastic:使用Heartbeat进行Uptime监控

Elastic在6.5的版本中退出Heartbeat。Heartbeat 也就是我们通常所说的心跳。我们知道在医院,医生是用听心跳来判断一个人是否有生命迹象。在Elastic的Heartbeat里,它也是一样的道理。Heartbeat是一个轻量级的数据收集器。它用来帮我们进行uptime的健康监控。它可以帮我们查看一个服务器及服务器中一些服务是否运行正常。

心跳可以在网络内部或外部运行。 它所需要的就是通过网络访问所需的HTTP,TCP或ICMP端点。 配置就像向Heartbeat提供您要监视的URL列表一样简单。 心跳将执行定期检查以验证端点是否处于运行状态,然后将此信息以及其他有用的指标报告给Elasticsearch。 该信息会自动显示在预建的Kibana仪表板中,以监控服务器或服务的正常运行。

Elastic使用heartbeat来进行Uptime的监控的架构可以表述如下:

让我们仔细看看如何在Elastic Stack中设置和使用心跳。
 

安装Uptime

如果我们打开我们的Kibana并点击Uptime应用,那么第一次打开的时候,我们可以看到,如下的界面。

点击Configure Heartbeat

我们可以选择我们所关心的平台来进行安装。针对我的情况,我来安装到我的Mac电脑上:

curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-7.5.0-darwin-x86_64.tar.gz
tar xzvf heartbeat-7.5.0-darwin-x86_64.tar.gz
cd heartbeat-7.5.0-darwin-x86_64/

在实际的使用中,你可以根据自己的Elasticsearch的版本选择一样版本的Heartbeat。我们进入到Heartbeat的安装目录:

$ pwd
/Users/liuxg/elastic5/heartbeat-7.5.0-darwin-x86_64
liuxg-2:heartbeat-7.5.0-darwin-x86_64 liuxg$ ls 
LICENSE.txt             fields.yml              heartbeat.yml
NOTICE.txt              heartbeat               kibana
README.md               heartbeat.reference.yml monitors.d

从上面我们可以看出来在heartbeat的安装目录中,有一个叫做heartbeat.yml的配置文件。同时在monitor.d目录中,有几个样本的http, icmptcp协议的配置文件。

 

配置Uptime监控

为了使Heartbeat知道要检查的服务,它需要一个URL列表。 在/heartbeat文件夹下的heartbeat.yml文件中指定了此配置。 这是使用Heartbeat进行多个HTTP检查的示例,该检查每10秒运行一次:

# Configure monitors
heartbeat.monitors:
- type: http
  # List or urls to query
  urls:
        - "https://www.elastic.co"
        - "https://discuss.elastic.co"
  # Configure task schedule
  schedule: '@every 10s'

除了HTTP/S监视器,Heartbeat还可以执行TCP和ICMP检查,因此您可以更好地了解服务的不同层。 在心跳中,我们还可以定义其他检查层,例如,使用HTTP/S监视器,我们可以检查响应代码(code),正文(body)和标头(header)。 使用TCP监视器,我们可以定义端口检查和字符串检查。

heartbeat.monitors:
- type: http
# List or urls to query
  urls: ["http://localhost:9200"]
  # request details:
  check.request:
       method: GET
  check.response:
       body: "You Know, for Search"
# Configure task schedule
  schedule: '@every 10s'

这是HTTP正文检查的示例,其中Heartbeat在http//localhost:9200(配置中指定的唯一URL)中寻找字符串“ You Know,for Search”。如果没有找到这个字符串,说明这个服务器是死掉了。

在所有心跳监视器上,我们可以定义其他参数,例如name, timeout和schedule。 您可以在配置心跳文档中找到完整的配置说明。

配置的最后一步是设置心跳输出(将数据发送到的位置)。 受支持的输出包括自我管理的Elasticsearch集群,Elastic Cloud,Logstash等。 在此示例中,我将心跳数据发送到我的本地Elasticsearch实例(“localhost:9200”)中:

output.elasticsearch:
# Array of hosts to connect to.
  hosts: ["localhost:9200"]
 # Optional protocol and basic auth credentials.
 #protocol: "https"
  username: "elastic"
  password: "changeme"

您可以在heartbeat.reference.yml文件中找到具有完整配置的示例文件。

 

第一次启动Heartbeat

心跳带有预建的仪表板,这些仪表板可提供大量的可用的可视化面板。 使用以下命令设置仪表板并运行Heartbeat:

要在Kibana中设置Heartbeat仪表板:(可选,只需运行一次)

./heartbeat setup

接着运行Heartbeat:

./heartbeat -e

Heartbeat一旦开始运行,它将检查您配置的URL列表,将信息发送回Elastic Stack,并预填充Kibana仪表板。

下面我们用几个例子来展示如何使用Uptime来监控我们的服务的。

 

例子

 

1)监控Elasticsearch服务器

首先,我们可以按照我之前的文章“Elasticsearch:从零开始安装Elasticsearch并使用Python装载一个CSV并读写它”来配置我们的环境。

在这个配置中,我们使用3个docker:

  1. 第一个docker运行一个Elasticsearch并置于口地址9200
  2. 第二个docker运行一个Elasticsearch并置于口地址9202
  3. 第三个docker运行一个Kibana并置于口地址5601,同时它的Elasticsearch配置指向第一个Elasticsearch口地址9200。这样在第二个Elasticsearch docker不运行时,我们的Kibana还可以继续运行

安装的步骤是这样的(具体步骤可以参阅上面说的那篇文章):

1)在一个Terminal中运行

docker network create elastic-network

2)在一个Terminal中启动第一个Docker,口地址9200

docker run --rm --name esn01 -p 9200:9200 -v esdata01:/usr/share/elasticsearch/data --network elastic-network -e "node.name=esn01" -e "cluster.name=liuxg-docker-cluster" -e "cluster.initial_master_nodes=esn01" -e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" docker.elastic.co/elasticsearch/elasticsearch:7.5.0

3)在另外一个Terminal中启动第二个Docker,口地址9202

docker run --rm --name esn02 -p 9202:9200 -v esdata02:/usr/share/elasticsearch/data --network elastic-network -e "node.name=esn02" -e "cluster.name=liuxg-docker-cluster" -e "discovery.seed_hosts=esn01" -e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" docker.elastic.co/elasticsearch/elasticsearch:7.5.0

4)在另外一个Terminal中启动Kibana,口地址5601

docker run --rm --link esn01:elasticsearch --name kibana --network elastic-network -p 5601:5601 docker.elastic.co/kibana/kibana:7.5.0

这样我们的配置就运行好了。我们可以打开Kibana,并查看我们的node运行情况:

我们可以看出来node运行正常。

5)在另外一个Terminal中运行heartbeat应用

因为我们想对我们的口地址为9202的Elasticsearch进行监控,那么,我们需要修改我们的heartbeat.yml口地址如下:

./heartbeat setup
./heartbeat -e

6)打开Uptime应用:

我们可以让我们的9202口地址的docker退出,过一会再重新开启。我们可以看出来如下的变化:

由于我们的Kibana是连接到9200口地址的Elasticsearch,所以即使我们的9202口地址的Elasticsearch是退出了,那么我们的Kibana也可以照常工作。从上面我们可以看出来,我们的端口为9202的Elasticsearch服务器有上线和掉线的情况(红色为掉线,灰色为上线)。点击下方的超链接,我们可以看到更多的细节:

 

2)使用ICMP来监控网站

在接下来的实验里,我们来通过 monitors.d里提供的yaml文件来进行我们的监视。我们可以在heartbeat.yml里看到:

我们可以看到上面有一个路径指向当前heartbeat安装目录下的monitors.d的目录。里面的每一个yml文件会自动成功一个uptime的配置文件,并收集数据。如果我们看一下在默认情况下的monitors.d目录下的文件:

$ pwd
/Users/liuxg/elastic5/heartbeat-7.5.0-darwin-x86_64
liuxg-2:heartbeat-7.5.0-darwin-x86_64 liuxg$ ls monitors.d/
sample.http.yml.disabled sample.icmp.yml.disabled sample.tcp.yml.disabled

因为所有的扩展名为.disabled,它们在默认的情况下没有被自动启动。

我们现在来下载我们所需要的配置及所需要用来做测试的服务源码:

git clone https://github.com/liu-xiao-guo/uptime_example

下载后的文件显示为:

我们首先用我们下载的heartbeat.yml文件来覆盖我们之前的缺省heartbeat.yml文件:

heartbeat.yml:

heartbeat.config.monitors:
  path: ${path.config}/monitors.d/*.yml
  reload.enabled: true
  reload.period: 5s

setup.template.settings:
  index.number_of_shards: 1
  index.codec: best_compression

tags: ["dev-web-services"]

fields:
  env: dev

processors:
- add_observer_metadata:
    netinfo.enabled: false
    cache.ttl: 5m
    geo:
      name: dev-dc-1
      location: 40.7128, -74.0060
      continent_name: North America
      country_iso_code: US
      region_name: Atlanta
      region_iso_code: GA
      city_name: Rosewell

setup.kibana:
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["localhost:9200"]

然后,我们我们下载文件里的icmp.yml文件拷入到monitors.d目录中。我们来首先看看icmp.yml里的内容:

icmp.yml

- type: icmp
  name: ping-tests-google-dns
  schedule: '*/5 * * * * * *'
  hosts: ["8.8.8.8","8.8.4.4."]
  ipv4: true
  ipv6: false
  mode: any
  timeout: 16s
  wait: 1s
  fields:
    env: dev

上面的配置文件非常地简单。它每隔5秒去ping一下谷歌的DNS服务器8.8.8.8及8.8.4.4。重新启动heartbeat应用

./heartbeat -e

注意:目前由于一些原因,针对ICMP的监测,我们必须使用root权限来运行。这在将来的版本中可能会有改变。所以针对上面的命令,在MacOS上,应该是:

chown root heartbeat.yml
chown root monitors.d/icmp.yml
sudo ./heartbeat -e

 

由于刚开始我使用的地址8.8.8.4.是错的。多了一个“.",所以,我们可以看到有一些红色。之后我矫正过后就可以看到连接的状态。

我们可以点击进入超链接,就可以看到每一个连接的具体情况:

 

使用REST接口来查运行状态

我们首先停止我们之前运行的heartbeat。我们首先进入到我们下载的service目录下的restful目录下,并执行如下的命令:

gradle clean
gradle build

等我们顺利编译好我们的restful项目后,我们重新进入到restful下的build/libs目录,并运行我们的JAVA应用:

从上面的显示,我们可以看出来我们已经成功地启动我们的Restful服务。我们在浏览器的地址栏中输入如下写地址:

从上面的显示中,我们可以看到我们的链接地址http://localhost:9001/product/logstash返回一个JSON的结果。针对我们的坚持来说,我们如果通过这个结果能够返回到这样的一个JSON的结果,我们认为我们的微服务是正常工作的,否则,我们认为是处于不正常工作状态。我们需要定制我们的restful.http.yml文件。我们把从上面下载的文件中的restful.http.yml文件拷入到我们的monitors.d文件目录下。

restful.http.yml

- type: http
  name: product-service-restful
  schedule: '@every 5s'
  urls: ["http://localhost:9001/product/logstash"]
  check.request:
    method: GET
  check.response:
    status: 200
    json:
      - description: check status
        condition:
          equals: 
            name: "Logstash"

上面的restful.http.yml文件的意思是restful接口的返回结果是200,并且是JSON格式的输出,返回结果是“Logstash”。如果这样的条件满足的话,那么我们认为这个微服务是正常的。

现在我们重新运行我们的heartbeat:

./heartbeat -e

我们重新在我们的Kibana中查看:

我们可以看到我们的Restful接口显示是在Up的状态。假如我们把我们的微服务接口关掉,那么我们看到的是如下的情况:

 

使用SOAP来查看运行状态

SOAP的方法和刚才我们讲到的Rest接口方法是一样的。我们可以编译在services目录下的soap项目,并运行它:

cd services/soap
gradle clean
gradle build fatjar

cd services/soap/build/libs
java -jar soap-1.0.0.jar

然后,我们在浏览器的地址中输入http://localhost:9002/ws/product.wsdl?,我们可以看到如下的输出:

显然我们的Web Service是成功地部署了。接下来,我们来定义我们的配置文件。我们把下载下来的soap.http.yml拷入到我们的monitors.d文件目录中。

soap.http.yml

- type: http
  name: product-service-soap
  schedule: '@every 5s'
  urls: ["http://localhost:9002/ws/product"]
  check.request:
    method: POST
    body: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.elksoft.com/"> <soapenv:Header/> <soapenv:Body> <ws:getProduct> <arg0>logstash</arg0> </ws:getProduct> </soapenv:Body> </soapenv:Envelope>'
  check.response:
    status: 200
    body: '(?s).*.<name>Logstash</name>.*'

这样我们配置成功后,我们重新运行我们的heartbeat应用:

./heartbeat -e

我们可以看到我们的微服务状态是Up状态:

如果我们把刚才启动的微服务关掉的话,那么我们可以看到如下的图:

 

使用TCP来监控运行状态

除了上面我们介绍的ICMP, SOAP, REST方法外,我们其实也可以通过TCP协议来监测运行的状态。比如我们可以这样定义:

tcp.yml

- type: tcp 
  name: elasticsearch-checker
  schedule: '@every 5s' 
  hosts: ["localhost:9200"]
  ipv4: true
  ipv6: true
  mode: any
  fields:
    env: dev

其实这个和我们刚开始介绍那个运用http协议来监测Elasticsearch运行的情况相似。在这里我就不再详述了。

 

参考:

【1】https://www.elastic.co/webinars/elastic-uptime-monitoring-actively-monitor-the-availability-of-your-systems-and-services

【2】https://www.elastic.co/blog/elastic-uptime-monitoring-solution-released

【3】https://www.elastic.co/blog/uptime-monitoring-with-heartbeat-and-the-elastic-stack