在上一篇 Go网络抓包、引流工具GoReplay 介绍了Gor的一些基础和实际开发中对 HTTP 流量进行复制,以用于测试、性能监测等用途。而Apache APISIX 是 Apache 软件基金会下的云原生 API 网关,它兼具动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、身份认证、可观测性等丰富的流量管理功能。结合使用 Gor 和 Apisix 可以轻松地实现流量复制,并将其应用于各种场景中。

本篇文章将介绍如何使用 Gor 和 Apisix 实现流量复制,具体包括以下几个部分:

  1. 测试环境介绍
  2. 安装和配置 Gor
  3. 安装和配置 Apisix
  4. 配置 Apisix 的 proxy-mirror 插件
  5. 测试流量复制

测试环境介绍

  1. OS: 两台 Ubuntu 虚拟机(Gateway、Node)

    a. Gateway 安装 ApiSix

    b. Node 安装节点服务

  2. Docker & DockerCompose

安装和配置 Gor

首先,需要在Node上安装 Gor 工具。可以从 Gor 的官网下载相应的二进制文件,然后将其解压到服务器上即可。

# tar xvf gor_1.3.3_x64.tar.gz
# cp gor /usr/local/bin/gor
# sudo chmod +x /usr/local/bin/gor

安装完成后,可以使用以下命令启动 Gor:

# gor version

输出

# Version:1.3.0 

安装和配置 Apisix

ApiSix: 这里使用 DockerCompose安装

git clone https://github.com/apache/apisix-docker.git

cd apisix-docker/example

docker-compose up -d

这个命令会启动 Apisix 并监听在本地的 80 端口。

配置 Apisix 的 proxy-mirror 插件

Apisix 的 proxy-mirror 插件可以用于流量复制。 增加一个路由hello-proxy-mirror, Upstream为Node主机的服务A(端口9696),流量复制到Node主机的服务B(端口9797),其中

  1. host 为 指定镜像服务地址
  2. sample_ratio 镜像请求采样率,本例中为1,表示全量复制
{
  "uri": "/hello",
  "name": "hello-proxy-mirror",
  "methods": [
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "PATCH",
    "HEAD",
    "OPTIONS",
    "CONNECT",
    "TRACE"
  ],
  "plugins": {
    "proxy-mirror": {
      "disable": false,
      "host": "http://192.168.1.101:9797",
      "sample_ratio": 1
    }
  },
  "upstream": {
    "nodes": [
      {
        "host": "192.168.1.101",
        "port": 9696,
        "weight": 1
      }
    ],
    "timeout": {
      "connect": 6,
      "send": 6,
      "read": 6
    },
    "type": "roundrobin",
    "scheme": "http",
    "pass_host": "pass",
    "keepalive_pool": {
      "idle_timeout": 60,
      "requests": 1000,
      "size": 320
    }
  },
  "status": 1
}

这个配置会开启 proxy-mirror 插件,并将其配置为将流量发送到本地的 8080 端口,即 Gor 监听的地址。

测试流量复制

接着可开始测试流量复制。

启动 HTTP 服务A监听9696端口:

python3 -m http.server 9696

正常启动输出

Serving HTTP on 0.0.0.0 port 9696 (http://0.0.0.0:9696/) ...

启动 镜像服务B监听9797端口:

python3 -m http.server 9797

正常启动输出

Serving HTTP on 0.0.0.0 port 9797 (http://0.0.0.0:9797/) ...

启动 Gor 监听在本地的 9797 端口

sudo gor --input-raw :9797 --output-stdout  

此命令将监听镜像服务B端口9797, 将 HTTP 流量输出到控制台

接着,curl测试

curl http://192.168.1.100:80/hello -i

输出

HTTP/1.1 404 File not found
Content-Type: text/html;charset=utf-8
Content-Length: 469
Connection: keep-alive
Date: Sun, 19 Mar 2023 06:55:42 GMT
Server: APISIX/3.2.0

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <title>Error response</title>
    </head>
    <body>
        <h1>Error response</h1>
        <p>Error code: 404</p>
        <p>Message: File not found.</p>
        <p>Error code explanation: HTTPStatus.NOT_FOUND - Nothing matches the given URI.</p>
    </body>
</html>

测试会发送一个 HTTP 请求到Apisix开放的Http端口80,可以到达下游服务(Node主机的ServerA 9696端口),输出如下:

192.168.1.100 - - [19/Mar/2023 06:47:44] code 404, message File not found
192.168.1.100 - - [19/Mar/2023 06:47:44] "GET /hello HTTP/1.1" 404 -

而且,ApiSix Proxy Mirror复制Http请求到端口 9797的镜像服务, 输出如下:

192.168.1.100 - - [19/Mar/2023 06:49:07] code 404, message File not found
192.168.1.100 - - [19/Mar/2023 06:49:07] "GET /hello HTTP/1.1" 404 -

可见和目标服务的的完全一致。 接着,观察Gor是否正常记录http请求,正常输出如下:

1 af0c2645c0a801c7399d6efb 1679212462567906772 0
GET /hello HTTP/1.1
Host: 192.168.1.100
Connection: close
User-Agent: curl/7.64.1
Accept: */*

说明Gor已经成功从镜像服务捕获流量。 再结合使用Gor的流量回放功能可以应用于例如测试、性能监测等场景。 以上。

参考