云拨测太贵了!快速实现简易的接口可用性检测

前言

作为开发老司机,有时候会碰到公司研发整体架构流程还不完善的情况。项目接口经常变更,上线比较随意,甚至接口参数变更了都没有人知道,同时又缺少测试。导致线上问题频发,客户投诉反馈了才后知后觉地发现问题,再急忙修复。这时候检测接口可用性就显得很有必要。

老司机当然会先找下云服务上有没有相关类似的产品,云拨测似乎可以解决类似的问题,不得不说云厂商已经覆盖了90%以上的场景。

云拨测(Cloud Automated Testing,CAT)利用分布于全球的监测网络,以真实终端用户使用场景为视角,提供模拟终端用户体验的拨测服务。CAT 可实现对网络质量、页面性能、端口性能、文件传输、音视频体验等场景进行周期性监控,支持多维度分析性能指标。利用可视化性能数据和告警通知可帮助您及时对业务质量作出反应,保证业务稳定正常运行。------ 腾讯云拨测服务介绍

下面是云拨测的价格:

不是,我就想测下接口可用性也要那么贵的吗? 好吧,这事估计害得自己来。

动手

首先,公司的接口一般都是比较复杂的或者带着鉴权的,写代码写起来可能一套下来花费的功夫太多。尽量要避免下写大量代码去实现,不然就得不偿失了。

其次,一些过程实现最好是流行的开源的,标准统一,方便修改,易于维护。

好了,废话不要太多,正式介绍下实现接口可用性检测的方案。

实现方案

整体实现的核心是通过利用 Postman 的功能来完成的(没想到吧,想到的当我没说)。

利用到的各个组件为:

  1. Postman 编写测试用的接口,Postman能完成的工作相当丰富,检测个接口不在话下。提醒一点,可以在 Tests里面编写需要测试用例,比如你可以验证模拟账号密码登录后,返回的结果是否是成功状态。又或者是在Tests里面注入一些全局使用的Token供后续使用。Postman功能强大,再多的举例就不说了,不再班门弄斧。
  2. Newman 下一步,我们需要用命令行去运行 Postman 编写好的导出的脚本代码。这里需要用到 Node 来安装运行 Newman。最后运行脚本参考:
bash 复制代码
#!/bin/bash

datetime=$(date "+%Y%m%d%H%M")

filename="/home/wwwroot/default/static/apitest_${datetime}.html"

source /etc/profile && cd /usr/local/lib/node/node-v16.20.2-linux-x64/lib/node_modules/newman/bin/ && /usr/local/lib/node/node-v16.20.2-linux-x64/lib/node_modules/newman/bin/newman.js run /home/wwwroot/script/auto_test_v1.json -r htmlextra,cli --reporter-htmlextra-export "$filename"

Node使用的是v16版本,Newman运行结果默认的情况下较为简单,可以通过引入额外的模板让输出结果更容易阅读。这里使用 newman-reporter-htmlextra 模板。当然了,外国人用的就是英文。相信大部分老司机都是中文使用者,如果需要修改模板,找到安装目录下的模板文件 dashboard-template.hbs 狠狠的修改它,参考路径 vi /usr/local/lib/node/node-v16.20.2-linux-x64/lib/node_modules/newman-reporter-htmlextra/lib/dashboard-template.hbs

  1. 利用gitlabjenkins完成发布功能。
  2. 利用服务器定时任务进行任务执行。需要注意的是,这里没有过多考虑程序运行时间,超时时间等情况,抛砖引玉,根据实际情况做调整。
  3. 输出html文件,通过nginx发布浏览。
  4. 最后的最后,提醒一定是最重要的功能,日常工作中,企业微信是最常用的工具,我们可以利用企业微信完成一个很好的提醒效果。当然也可以更换成邮件或者其他方式。

上参考代码:

python 复制代码
# encoding=utf-8
import cptools
import re
import sys
import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from corpwechatbot.app import AppMsgSender


def read_file(file_path):
    try:
        with open(file_path, 'r') as file:
            content = file.read()
        file.close()
        return content.replace("\n", "")
    except FileNotFoundError:
        return ""
    except:
        return ""


def write_file(file_path, content):
    try:
        with open(file_path, 'w') as file:
            file.write(content)
        file.close()
        print("写入文件成功")
    except:
        print("写入文件出错")


if __name__ == "__main__":
    now_timestamp = round(time.time())
    the_now_time = time.strftime("%Y%m%d%H%M", time.localtime(now_timestamp-60))

    request_path = ("http://127.0.0.1/static/apitest_%s.html" % the_now_time)

    remind_time_path = "/root/python/apitj/remind_time.log"

    is_send = False

    if len(sys.argv) > 1 and str(sys.argv[1]) == "1":
        is_send = True

    last_remind_time = read_file(remind_time_path)
    try:
        if now_timestamp - int(last_remind_time) < 1800:
            print("最后一次提醒时间为%s, 不需要重新提醒" % str(last_remind_time))
            exit()
    except Exception as e:
        print("有异常,需要正常执行")

    response = requests.get(request_path)
    if response.status_code == 200:
        print("Status code is 200")
        if "Failed Tests" in response.text:
            if (f'Failed Tests <span class="badge badge-light">0</span>' not in response.text) or (is_send is True):
                print('screenshot start')
                chrome_options = Options()
                chrome_options.binary_location = '/usr/bin/google-chrome'
                chrome_options.add_argument('--disable-gpu')
                chrome_options.add_argument('--headless')
                chrome_options.add_argument('--no-sandbox')
                driver = webdriver.Chrome(options=chrome_options, executable_path='/usr/local/bin/chromedriver')
                driver.set_window_size(1100, 1200)
                monitor_img_path = '/root/python/apitj/alert.png'
                driver.get(request_path)
                time.sleep(3)
                # Trigger the desired event
                # driver.execute_script('document.getElementById("pills-failed-tab").click();')

                # Wait for the event to take effect
                # time.sleep(1)
                driver.save_screenshot(monitor_img_path)
                driver.close()
                driver.quit()
                print("screenshot end")
                the_now_time_format = time.strftime("%m月%d日%H时%M分", time.localtime(now_timestamp))
                pattern = r'Failed Tests <span class="badge badge-light">(\d+)</span>'
                matches = re.findall(pattern, response.text)
                if matches:
                    failtests = matches[0]
                    msg = "检查到有%s个失败的测试用例" % failtests
                else:
                    msg = "未检查到有失败的测试用例"
                write_file(remind_time_path, str(now_timestamp))
                user_list = ["xxx"]
                app = AppMsgSender(corpid='xxxxx',
                                   corpsecret='xxxxx',
                                   agentid='xxxxx',
                                   log_level=cptools.INFO)
                # app.send_image(image_path=monitor_img_path, touser=user_list)
                # app.send_card(title="接口可用性检查", desp="定时对关键接口进行可用性检查", url=request_path, btntxt="报告详情")
                app.send_card(title="接口可用性告警",
                              desp=("<div class=\"gray\">当前时间:%s</div> <div class=\"highlight\">%s</div> "
                                    "<div class=\"normal\">定时对关键接口进行可用性检查</div>" % (the_now_time_format, msg)),
                              url=request_path, btntxt="报告详情", touser=user_list)
                app.send_image(image_path=monitor_img_path, touser=user_list)
    else:
        print("Status code is not 200")

好了,到此就完成了整个接口可用性检测的整个方案。大家学废了吗?

PS:注意生成的HTML文件别把服务器写满了,记得定期清理。

相关推荐
..过云雨24 分钟前
17-2.【Linux系统编程】线程同步详解 - 条件变量的理解及应用
linux·c++·人工智能·后端
南山乐只1 小时前
【Spring AI 开发指南】ChatClient 基础、原理与实战案例
人工智能·后端·spring ai
努力的小雨2 小时前
从“Agent 元年”到 AI IDE 元年——2025 我与 Vibe Coding 的那些事儿
后端·程序员
源码获取_wx:Fegn08953 小时前
基于springboot + vue小区人脸识别门禁系统
java·开发语言·vue.js·spring boot·后端·spring
wuxuanok3 小时前
Go——Swagger API文档访问500
开发语言·后端·golang
用户21411832636023 小时前
白嫖Google Antigravity!Claude Opus 4.5免费用,告别token焦虑
后端
爬山算法4 小时前
Hibernate(15)Hibernate中如何定义一个实体的主键?
java·后端·hibernate
用户26851612107565 小时前
常见的 Git 分支命名策略和实践
后端
程序员小假5 小时前
我们来说一下 MySQL 的慢查询日志
java·后端