如何在 Linux 中使用 curl 测试服务器连通性

LinuxBeginner
立即练习

介绍

在 Linux 系统管理中,检查服务器连通性是一项基本技能。本实验将引导你使用 cURL 工具来测试服务器连通性。cURL (Client URL) 是一个命令行工具,支持通过多种网络协议进行数据传输,是进行网络诊断和故障排查的必备利器。

通过本实验,你将学会如何使用 cURL 验证服务器可用性、检查响应时间、分析 HTTP 状态码以及排查连接问题。无论你是管理 Web 服务器、API 还是 Linux 环境中的其他网络服务,这些技能都将非常实用。

理解 cURL 基础

cURL 是一个功能强大的命令行工具,允许你使用包括 HTTP、HTTPS、FTP 等在内的多种协议传输数据。在深入进行连通性测试之前,让我们先了解 cURL 是什么以及如何进行基本操作。

安装 cURL

大多数 Linux 发行版(包括你的 Ubuntu 22.04 环境)都预装了 cURL 工具。要验证 cURL 是否已安装,请打开终端并运行:

curl --version

你应该会看到类似以下的输出:

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.13
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

这确认了 cURL 已安装,并显示了版本号以及支持的协议和特性。

cURL 基本语法

使用 cURL 的基本语法如下:

curl [options] [URL]

让我们尝试一个简单的 cURL 命令来获取网站内容:

curl https://example.com

该命令会向 example.com 发送一个 GET 请求,并在终端中显示 HTML 响应。你应该会看到类似以下的 HTML 代码:

<!doctype html>
<html>
  <head>
    <title>Example Domain</title>
    <!-- More HTML content -->
  </head>
  <body>
    <div>
      <h1>Example Domain</h1>
      <p>This domain is for use in illustrative examples in documents...</p>
      <!-- More content -->
    </div>
  </body>
</html>

将输出保存到文件

你可以使用 -o--output 选项将输出保存到文件,而不是直接显示在终端中:

curl -o example.html https://example.com

该命令将来自 example.com 的响应保存为名为 example.html 的文件。要验证文件是否已创建:

ls -l example.html

你应该会看到确认文件存在的输出:

-rw-rw-r-- 1 labex labex 1256 Mar 28 12:34 example.html

查看文件内容:

cat example.html

你应该会看到与之前在终端中显示的相同的 HTML 内容。

理解 cURL 中的 HTTP 方法

cURL 默认使用 HTTP GET 方法,但你可以使用 -X 选项指定其他方法。常见的 HTTP 方法包括:

  • GET:从服务器检索数据
  • POST:向服务器提交数据
  • PUT:更新服务器上的现有数据
  • DELETE:删除服务器上的数据
  • HEAD:类似于 GET,但仅检索响应头

在后续步骤中,我们将探索如何使用这些不同的方法来测试服务器的连通性和功能。

测试基础服务器连通性

现在你已经了解了 cURL 的基础知识,让我们用它来测试服务器连通性。对于系统管理员和开发人员来说,检查服务器是否在线并正常响应是一项至关重要的技能。

简单的连接测试

最基本的连通性测试是向服务器发送请求并查看其是否响应。让我们测试一下 Google 服务器的连通性:

curl -I https://www.google.com

-I 选项(或 --head)告诉 cURL 发送一个 HEAD 请求,该请求仅检索响应头而不包含正文内容。这对于快速检查连通性非常有用。你应该会看到类似以下的输出:

HTTP/2 200
content-type: text/html; charset=ISO-8859-1
date: Tue, 28 Mar 2023 12:34:56 GMT
server: gws
content-length: 219
x-xss-protection: 0
x-frame-options: SAMEORIGIN

HTTP/2 200 表示连接成功——服务器在线且正在响应。

检查 HTTP 状态码

HTTP 状态码是服务器发送的标准化响应,用于指示客户端请求的结果。一些常见的状态码包括:

  • 200:OK - 请求成功
  • 301/302:重定向 - 资源已移动
  • 404:未找到 - 资源不存在
  • 500:内部服务器错误 - 服务器遇到错误

让我们测试一个不存在的 URL 以查看 404 响应:

curl -I https://www.google.com/nonexistent-page

输出应包含 404 状态码:

HTTP/2 404
content-type: text/html; charset=UTF-8
date: Tue, 28 Mar 2023 12:35:01 GMT
server: gws
content-length: 1565
...

测量响应时间

要测量服务器响应所需的时间,请使用 -w 选项配合格式字符串:

curl -s -o /dev/null -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" https://www.google.com

该命令的含义:

  • -s:静默模式(不显示进度或错误信息)
  • -o /dev/null:将输出重定向到 /dev/null(丢弃输出)
  • -w "...":显示带有计时信息的格式化输出

你应该会看到类似以下的输出:

Connect: 0.052s
Total: 0.157s

这显示了建立连接所花费的时间以及请求完成的总时间。

测试域名解析

有时连通性问题源于 DNS 问题。要测试域名是否能解析为 IP 地址:

curl -v https://www.example.com 2>&1 | grep "Trying"

这里使用了 -v(详细模式)选项,并过滤出 "Trying" 行,该行显示了正在连接的 IP 地址。你应该会看到类似以下的输出:

* Trying 93.184.216.34:443...

这确认了域名已成功解析为 IP 地址。

创建简单的连接测试脚本

让我们创建一个简单的 Shell 脚本来测试多个站点的连通性。打开文本编辑器:

nano connection_test.sh

向文件中添加以下内容:

#!/bin/bash

echo "Testing server connectivity..."

for site in google.com example.com github.com nonexistent-site.xyz; do
  echo -n "Testing $site: "

  ## 使用 curl 并设置 5 秒超时
  status_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "https://$site" 2> /dev/null)

  if [ $? -eq 0 ] && [ "$status_code" -lt 400 ]; then
    echo "OK (Status: $status_code)"
  else
    echo "Failed (Status: $status_code)"
  fi
done

echo "Testing complete!"

Ctrl+O 保存文件,按 Enter 确认,然后按 Ctrl+X 退出。

使脚本可执行:

chmod +x connection_test.sh

运行脚本:

./connection_test.sh

你应该会看到显示每个站点连通性状态的输出:

Testing server connectivity...
Testing google.com: OK (Status: 200)
Testing example.com: OK (Status: 200)
Testing github.com: OK (Status: 200)
Testing nonexistent-site.xyz: Failed (Status: 000)
Testing complete!

该脚本提供了一种同时检查多个服务器连通性的快捷方式。

使用 cURL 进行高级连通性测试

现在你已经了解了基础的连通性测试,让我们探索 cURL 的更多高级功能,这些功能有助于进行详细的故障排查和测试。

使用详细模式进行深度调试

详细模式(-v 选项)对于排查连通性问题非常宝贵,因为它展示了完整的请求和响应过程:

curl -v https://example.com

输出将非常全面,显示 DNS 解析、TLS 握手、请求头、响应头等信息:

*   Trying 93.184.216.34:443...
* Connected to example.com (93.184.216.34) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=California; L=Los Angeles; O=Internet Corporation for Assigned Names and Numbers; CN=www.example.org
*  start date: Nov 24 00:00:00 2022 GMT
*  expire date: Nov 24 23:59:59 2023 GMT
*  subjectAltName: host "example.com" matched cert's "example.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:path: /]
* h2 [:scheme: https]
* h2 [:authority: example.com]
* h2 [user-agent: curl/7.81.0]
* h2 [accept: */*]
* Using Stream ID: 1
> GET / HTTP/2
> Host: example.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< age: 587269
< cache-control: max-age=604800
< content-type: text/html; charset=UTF-8
< date: Tue, 28 Mar 2023 12:40:01 GMT
< etag: "3147526947+ident"
< expires: Tue, 04 Apr 2023 12:40:01 GMT
< last-modified: Thu, 17 Oct 2019 07:18:26 GMT
< server: ECS (nyb/1D2B)
< vary: Accept-Encoding
< x-cache: HIT
< content-length: 1256
<
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    <!-- More HTML content -->
</head>
<body>
    <div>
        <h1>Example Domain</h1>
        <p>This domain is for use in illustrative examples in documents...</p>
        <!-- More content -->
    </div>
</body>
</html>
* Connection #0 to host example.com left intact

这些详细输出有助于你精确定位连接失败的具体环节。

测试不同的 HTTP 方法

让我们向测试 API 端点发送一个 POST 请求:

curl -X POST -d "name=test&email=test@example.com" https://httpbin.org/post

该命令的含义:

  • -X POST:指定发送 POST 请求
  • -d "name=test&email=test@example.com":在请求中发送表单数据

你应该会收到一个显示你所提交数据的 JSON 响应:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "email": "test@example.com",
    "name": "test"
  },
  "headers": {
    "Accept": "*/*",
    "Content-Length": "32",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.81.0",
    "X-Amzn-Trace-Id": "Root=1-642295b1-0d2340ef34f2e8ea6270241a"
  },
  "json": null,
  "origin": "198.51.100.42",
  "url": "https://httpbin.org/post"
}

使用自定义请求头进行测试

许多 API 需要特定的请求头来进行身份验证或指定内容类型。让我们测试一下:

curl -H "User-Agent: MyCustomAgent" -H "Authorization: Bearer test-token" https://httpbin.org/headers

该命令的含义:

  • -H "User-Agent: MyCustomAgent":设置自定义 User-Agent 请求头
  • -H "Authorization: Bearer test-token":设置 Authorization 请求头

响应将显示你在请求中发送的请求头:

{
  "headers": {
    "Accept": "*/*",
    "Authorization": "Bearer test-token",
    "Host": "httpbin.org",
    "User-Agent": "MyCustomAgent",
    "X-Amzn-Trace-Id": "Root=1-642295c3-73cac0a73b34b1c93a8ce520"
  }
}

测试不同端点的响应时间

让我们创建一个脚本来比较不同服务器的响应时间:

nano response_time.sh

添加以下内容:

#!/bin/bash

echo "Testing response times..."

for site in google.com bing.com baidu.com duckduckgo.com yahoo.com; do
  echo -n "$site: "
  curl -s -o /dev/null -w "%{time_total}s" "https://$site"
  echo ""
done

echo "Testing complete!"

保存文件并使其可执行:

chmod +x response_time.sh

运行脚本:

./response_time.sh

输出将显示每个站点的响应时间:

Testing response times...
google.com: 0.187s
bing.com: 0.232s
baidu.com: 0.412s
duckduckgo.com: 0.298s
yahoo.com: 0.342s
Testing complete!

这对于比较不同服务器的性能或长期监控服务器性能非常有用。

测试特定端口的 TCP 连通性

有时你需要测试服务器上的特定端口是否开放。cURL 也可以用于此目的:

curl -v telnet://example.com:80

如果端口开放,你将看到连接成功的消息:

* Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)

Ctrl+C 终止连接。

同样,你可以测试安全连接:

curl -v https://example.com:443

详细输出将显示连接是否成功或是否存在任何问题。

创建综合服务器监控工具

现在你已经学习了各种使用 cURL 进行连通性测试的技术,让我们构建一个结合了这些技术的综合服务器监控工具。

综合服务器监控脚本

创建一个新的脚本文件:

nano server_monitor.sh

添加以下内容:

#!/bin/bash

## 服务器监控脚本
## 该脚本检查指定服务器的可用性和性能

## 定义输出颜色
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' ## 无颜色

## 检查服务器状态的函数
check_server() {
  local url=$1
  local timeout=5

  echo -e "\n${YELLOW}Testing $url:${NC}"

  ## 测试连接并获取状态码
  status_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $timeout "$url" 2> /dev/null)

  if [ "$status_code" -eq 200 ]; then
    echo -e "${GREEN}✓ Status: $status_code (OK)${NC}"
  elif [ "$status_code" -ge 100 ] && [ "$status_code" -lt 400 ]; then
    echo -e "${GREEN}✓ Status: $status_code (Success/Redirect)${NC}"
  elif [ "$status_code" -ge 400 ] && [ "$status_code" -lt 500 ]; then
    echo -e "${RED}✗ Status: $status_code (Client Error)${NC}"
  elif [ "$status_code" -ge 500 ]; then
    echo -e "${RED}✗ Status: $status_code (Server Error)${NC}"
  else
    echo -e "${RED}✗ Status: Connection failed${NC}"
  fi

  ## 如果连接成功,测量响应时间
  if [ "$status_code" -gt 0 ]; then
    response_time=$(curl -s -o /dev/null -w "%{time_total}" --connect-timeout $timeout "$url" 2> /dev/null)
    echo -e "• Response time: ${response_time}s"

    ## 获取服务器响应头
    echo "• Server headers:"
    curl -s -I --connect-timeout $timeout "$url" | grep -E 'Server:|Content-Type:|Date:' | sed 's/^/  /'
  fi
}

## 主函数
main() {
  echo -e "${YELLOW}===== Server Connectivity Monitor =====${NC}"
  echo "Started at: $(date)"

  ## 要监控的服务器列表
  servers=(
    "https://www.google.com"
    "https://www.github.com"
    "https://www.example.com"
    "https://httpbin.org/status/404" ## 这将返回 404 状态
    "https://httpbin.org/status/500" ## 这将返回 500 状态
  )

  ## 检查每个服务器
  for server in "${servers[@]}"; do
    check_server "$server"
  done

  echo -e "\n${YELLOW}===== Monitoring Complete =====${NC}"
  echo "Finished at: $(date)"
}

## 运行主函数
main

保存文件并使其可执行:

chmod +x server_monitor.sh

运行脚本:

./server_monitor.sh

输出将提供每个服务器的综合状态概览:

===== Server Connectivity Monitor =====
Started at: Tue Mar 28 13:15:01 UTC 2023

Testing https://www.google.com:
✓ Status: 200 (OK)
• Response time: 0.186s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:02 GMT
  Content-Type: text/html; charset=ISO-8859-1
  Server: gws

Testing https://www.github.com:
✓ Status: 200 (OK)
• Response time: 0.247s
• Server headers:
  Server: GitHub.com
  Date: Tue, 28 Mar 2023 13:15:02 GMT
  Content-Type: text/html; charset=utf-8

Testing https://www.example.com:
✓ Status: 200 (OK)
• Response time: 0.132s
• Server headers:
  Content-Type: text/html; charset=UTF-8
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Server: ECS (nyb/1D2B)

Testing https://httpbin.org/status/404:
✗ Status: 404 (Client Error)
• Response time: 0.189s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Content-Type: text/html; charset=utf-8
  Server: gunicorn/19.9.0

Testing https://httpbin.org/status/500:
✗ Status: 500 (Server Error)
• Response time: 0.192s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Content-Type: text/html; charset=utf-8
  Server: gunicorn/19.9.0

===== Monitoring Complete =====
Finished at: Tue Mar 28 13:15:04 UTC 2023

定时执行连通性检查

为了定期监控服务器,你可以设置一个 cron 任务。在实际生产环境中,你可能会将此脚本添加到 crontab 中以定期运行。为了演示,让我们创建一个简单的包装脚本,在指定时间内每分钟运行一次监控:

nano scheduled_monitor.sh

添加以下内容:

#!/bin/bash

## 定时监控脚本
## 该脚本定期运行 server_monitor.sh

## 检查是否提供了持续时间参数
if [ $## -ne 1 ]; then
  echo "Usage: $0 <duration_in_minutes>"
  exit 1
fi

duration=$1
interval=60 ## 秒
iterations=$((duration * 60 / interval))

echo "Starting scheduled monitoring for $duration minutes..."
echo "Press Ctrl+C to stop monitoring"

for ((i = 1; i <= iterations; i++)); do
  echo -e "\n===== Run $i of $iterations ====="
  ./server_monitor.sh

  ## 最后一次迭代后不休眠
  if [ $i -lt $iterations ]; then
    echo "Next check in $interval seconds..."
    sleep $interval
  fi
done

echo "Scheduled monitoring completed."

保存文件并使其可执行:

chmod +x scheduled_monitor.sh

运行脚本 2 分钟(你可以根据需要增加或减少时间):

./scheduled_monitor.sh 2

这将每分钟运行一次服务器监控脚本,持续 2 分钟:

Starting scheduled monitoring for 2 minutes...
Press Ctrl+C to stop monitoring

===== Run 1 of 2 =====
===== Server Connectivity Monitor =====
...
(monitoring output)
...
Next check in 60 seconds...
(waits for 60 seconds)

===== Run 2 of 2 =====
===== Server Connectivity Monitor =====
...
(monitoring output)
...
Scheduled monitoring completed.

在生产环境中,你通常会设置 cron 任务,但此脚本提供了一种在实验练习期间执行定时监控的简单方法。

总结

在本实验中,你探索了如何在 Linux 环境中使用 cURL 测试服务器连通性。从基础知识开始,你学习了如何发送简单的 HTTP 请求并将响应保存到文件。随后,你深入学习了更复杂的操作,包括检查 HTTP 状态码、测量响应时间以及使用详细模式进行深度调试。

你创建了几个实用的脚本,展示了 cURL 在服务器监控和连通性测试方面的强大功能:

  1. 一个基础的连接测试脚本,用于检查多个服务器的连通性
  2. 一个响应时间比较脚本,用于测量和比较服务器性能
  3. 一个综合服务器监控工具,提供关于服务器状态、响应时间和响应头信息的详细报告
  4. 一个定时监控脚本,用于自动化定期连通性检查

这些工具和技术对于系统管理员、开发人员以及任何从事网络系统工作的人员来说都非常宝贵。通过掌握 cURL,你现在拥有了一个强大的工具,可以用于诊断和解决 Linux 环境中的连通性问题。

在继续使用 Linux 系统时,请记住 cURL 不仅可用于测试连通性,还可用于与 API 交互、下载文件以及自动化各种网络相关任务。你在本实验中获得的技能将为你未来进行更高级的网络操作和故障排查奠定基础。