专栏名称: 预流
敲代码的
目录
相关文章推荐
51好读  ›  专栏  ›  预流

基于Gor实现流量复制(加middleware功能增强)

预流  · 掘金  ·  · 2018-01-25 10:52

正文

最近做功能重构,在上线前要求验证重构后的代码与老代码实现逻辑是否一致,基于这个需求,需要在生产环境做一个功能将生产服务器上的流量复制一份发送到测试服务器上。

就这个事情这几天考察了三种技术,1. 基于 nginx+lua 脚本,2. tcpcopy,3. gor。这里大概说一下这三种方案:

  • nginx+lua 脚本

这种方案的思路是在生产服务器前端架一层壳子,将请求拦截,然后基于 lua-nginx-module 模块,写 lua 脚本,使用其内置的 ngx.location.capture_multi ,对后端发起多个异步并发请求,然后统一将结果返回给前端。

该方案需要安装 nginx ,以及依赖 lua-nginx-module ,ngx_devel_kit 等模块,然后需要写lua代码来复制请求。

  • tcpcopy

这种方案是工作在网络等 TCP 和 IP 层做请求复制,因为其间架构调整过两次,现在的实现架构是在生产环境启动 tcpcopy 进程,测试环境启动 intecept 进程,然后配置复制请求的路径。

  • gor

这是今天搜到的用 Go 语言写的工具,在生产服务器上安装一个 tar 包,用 root 权限启动命令即可

1的方案安装步骤较多,需要理解 nginx 处理请求的过程和 lua 脚本语法以及相关请求调用的 API 。2的安装简单一些,只需要在生产和测试服务器分别安装 tcpcopy 和 intecept 即可(当然前提是他们依赖的 libpcap 之类也有了,否则也要安装),然后启动命令加参数即可,但由于该方案工作在较为底层,看起来比较重,实际跑了个例子就没继续研究。3安装最简单,下载一个 tar 包,解压,sudo 执行即搞定。

个人比较倾向于3,所以这里就介绍一下gor的实现方式。

  1. 下载

根据操作系统环境下载安装包 https://github.com/buger/gor/releases,建议选择 master 分支的,我的是 Mac ,所以选择了 tar 包

  1. 解压
tar -xvf gor_v0.14.1_mac.tar.gz
  1. 验证
sudo ./gor --input-raw :8080 --output-http http://192.168.22.33:8080

至此就搞定了,简单吧!!! 这条命令是监控本地的 8080 端口,并实时复制请求到需要 192.168.22.33 的 8080 端口上,需要本地 root 执行权限。

下面是我的扩展用法:

  1. 保存请求到文件
sudo ./gor --input-raw :8080 --output-file requests.gor

这里将 8080 端口的请求保存到本地文件上,可以用于线上请求记录之后的功能回放

  1. 根据文件回放请求
sudo ./gor --input-file requests.gor --output-http http://192.168.22.33:8080

将上面保存的文件请求回放到 192.168.22.33 服务器的 8080 端口上

  1. url 过滤 包含 /order 的 URL 才发送请求
sudo ./gor --input-raw :8080 --output-http http://192.168.22.33:8080 --http-allow-url ^/order.
  1. url 过滤+记录文件+请求回放
sudo ./gor --input-raw :8080 --output-file gor-order-requests.gor --output-http http://192.168.22.33:8080 --http-allow-url ^/order.

sudo ./gor --input-file gor-order-requests.gor --output-http http://192.168.22.33:8080
  1. url 过滤+记录文件+记录响应
sudo ./gor --input-raw-track-response --input-raw :8080 --output-file gor-order-request-response.gor --http-allow-url ^/order.

下面是别人整理的一些详细配置说明,可以参考一下

  -cpuprofile string
        write cpu profile to file
  -debug verbose
        打开debug模式,显示所有接口的流量 
  -http-allow-header value
        用一个正则表达式来匹配http头部,如果请求的头部没有匹配上,则被拒绝 
         gor --input-raw :8080 --output-http staging.com --http-allow-header api-version:^v1 (default [])
  -http-allow-method value
        类似于一个白名单机制来允许通过的http请求方法,除此之外的方法都被拒绝.
        gor --input-raw :8080 --output-http staging.com --http-allow-method GET --http-allow-method OPTIONS (default [])
  -http-allow-url value
        一个正则表达式用来匹配url, 用来过滤完全匹配的的url,在此之外的都被过滤掉 
         gor --input-raw :8080 --output-http staging.com --http-allow-url ^www. (default [])
  -http-disallow-header value
        用一个正则表达式来匹配http头部,匹配到的请求会被拒绝掉
         gor --input-raw :8080 --output-http staging.com --http-disallow-header "User-Agent: Replayed by Gor" (default [])
  -http-disallow-url value
        用一个正则表达式来匹配url,如果请求匹配上了,则会被拒绝
         gor --input-raw :8080 --output-http staging.com --http-disallow-url ^www. (default [])
  -http-header-limiter value
        读取请求,基于FNV32-1A散列来拒绝一定比例的特殊请求 
         gor --input-raw :8080 --output-http staging.com --http-header-imiter user-id:25% (default [])
  -http-original-host
        在--output-http的输出中,通常gor会使用取代请求的http头,所以应该禁用该选项,保留原始的主机头
  -http-param-limiter value
        Takes a fraction of requests, consistently taking or rejecting a request based on the FNV32-1A hash of a specific GET param:
         gor --input-raw :8080 --output-http staging.com --http-param-limiter user_id:25% (default [])
  -http-rewrite-url value
        Rewrite the request url based on a mapping:
        gor --input-raw :8080 --output-http staging.com --http-rewrite-url /v1/user/([^\/]+)/ping:/v2/user/$1/ping (default [])
  -http-set-header value
        Inject additional headers to http reqest:
        gor --input-raw :8080 --output-http staging.com --http-set-header 'User-Agent: Gor' (default [])
  -http-set-param value
        Set request url param, if param already exists it will be overwritten:
        gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1 (default [])
  -input-dummy value
        Used for testing outputs. Emits 'Get /' request every 1s (default [])
  -input-file value
        从一个文件中读取请求
        gor --input-file ./requests.gor --output-http staging.com (default [])
  -input-http value
        从一个http接口读取请求
        # Listen for http on 9000
        gor --input-http :9000 --output-http staging.com (default [])
  -input-raw value
        Capture traffic from given port (use RAW sockets and require *sudo* access):
        # Capture traffic from 8080 port
        gor --input-raw :8080 --output-http staging.com (default [])
  -input-tcp value
       用来在多个gor之间流转流量
        # Receive requests from other Gor instances on 28020 port, and redirect output to staging
        gor --input-tcp :28020 --output-http staging.com (default [])
  -memprofile string
        write memory profile to this file
  -middleware string
        Used for modifying traffic using external command
  -output-dummy value
        用来测试输入,打印出接收的数据. (default [])
  -output-file value
        把进入的请求写入一个文件中
        gor --input-raw :80 --output-file ./requests.gor (default [])
  -output-http value
        转发进入的请求到一个http地址上
        # Redirect all incoming requests to staging.com address 
        gor --input-raw :80 --output-http http://staging.com (default [])
  -output-http-elasticsearch string
        把请求和响应状态发送到ElasticSearch:
        gor --input-raw :8080 --output-http staging.com --output-http-elasticsearch 'es_host:api_port/index_name'
  -output-http-redirects int
        设置多少次重定向被允许
  -output-http-stats
        每5秒钟输出一次输出队列的状态 
  -output-http-timeout duration
       指定http的request/response超时时间,默认是5秒
  -output-http-workers int
        gor默认是动态的扩展工作者数量,你也可以指定固定数量的工作者
  -output-tcp value
        用来在多个gor之间流转流量
        # Listen for requests on 80 port and forward them to other Gor instance on 28020 port
        gor --input-raw :80 --output-tcp replay.local:28020 (default [])
  -output-tcp-stats
        每5秒钟报告一次tcp输出队列的状态
  -split-output true
        By default each output gets same traffic. If set to true it splits traffic equally among all outputs.
  -stats
        打开输出队列的状态
  -verbose
        Turn on more verbose output

当然最好的还是直接关注作者的 git 项目:https://github.com/buger/gor/wiki







请到「今天看啥」查看全文