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

前言

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

老司机当然会先找下云服务上有没有相关类似的产品,云拨测似乎可以解决类似的问题,不得不说云厂商已经覆盖了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文件别把服务器写满了,记得定期清理。

相关推荐
zopple6 小时前
常见的 Spring 项目目录结构
java·后端·spring
cjy0001118 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本9 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34169 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan9 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer10 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor35610 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor35611 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer11 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP12 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪