随着世界杯足球的赛况如火如荼进行,本文借势简单向大家介绍下系统方面上的“攻防演练”:基于python-web服务的压力测试方案以及构筑稳定的web系统的技术方案。
环境信息:申请某公有云主机centos(2核 4G 20MB带宽)Docker version 18.03.1-ce, build 9ee9f4。
首先,选择python-web的框架,我们选择python django这个web框架,Django可以运行在Apache,Nginx上,也可以运行在支持WSGI,FastCGI的服务器上。为了简化在初始化python环境的一些环境和版本隔离的步骤,我们通过docker命令直接构建容器化django环境。我通过在某公有云上申请到了centos7主机上进行搭建:
1.先安装docker环境,我通过yum安装的docker版本是最新的18.03.1-ce 。
2.简单介绍下python的django环境搭建。
直接拉取django的镜像:
启动镜像并绑定主机8080端口,并进入容器bash,通过shell进去manage启动django。
docker run -d --name=redis -p 6600 redis 同样拉取redis镜像并运行redis。
将之前启动的django容器和redis容器链接,并进入django容器的bash ping redis验证。
至此,整体的容器拓扑就可以绘制出来了,如下图所示:
然后我们需要编写django的view文件,并匹配到URLconf的url中的/hello/ 中,然后关于django框架的逻辑机制,不是本文的重点,有兴趣的可以自行学习,我以后有机会也会出相关的文章进行详细的描述。服务的主要功能为匹配到hello/的时候,Django转换HttpResponse为HTTP response返回。整体的服务环境就搭建完成了,下一篇将围绕搭建环境进行升级进行“防守”性能提升。
现在我们将对所搭建的环境进行压力测试。先总结下通过python编写相应的压力工具以及进行压力工具的框架模型进行分析:
同步压测模型:通过python 的 threading.Thread实现多线程,通过queue.Queue形成线程队列,压测中的用例或者参数需要通过python函数从redis中提取。如下所示:通过qos绑定redis对象,然后通过get方法返回给压测线程。
至此一个简单的python压测模型形成了。
当然上述的queue.Queue的压测队列结构也可以通过python的另外自带的线程池来实现:
总结如此实现的压测工具其实和上图queue.Queue实现的压测工具没有本质上的性能提升,只不过代码逻辑结构看起来简洁一些而已。我们需要提升下我们的进攻效率,那么如何提升压测性能的效率呢,就要从redis提供参数的效率开始研究。
在上面所述的结构中,我们通过一个函数实现从redis提取参数,另外一个函数实现对django进行压测。那么redis线程和主线程的配合效率就对整体的压测性能至关重要了。上文中的结构整体的压测还是同步结构,如果参数供给不上压测线程就有出现等待阻塞。
我们通过协程机制来提升redis参数提供线程与整体的效率,从而提高整体的压测“进攻质量”。
异步结构压测:通过协程预缴机制,实现压测进程与参数提供的高效异步,大大提升压测效率。
这还是一种简单的压测工具,因为其中通过参数提供的线程是单一的,只不过进攻效率较上文中的模型提高罢了,如果在大规模的参数预缴需求以及进行“并行进行进攻”需求下,我们还需要用python调用Linux操作系统的高速IO接口进行实现。select 及其升级版 epoll(Linux) 和 kqueue(*BSD 和 Mac OS X),通常还包括poll模式。形成下图的进攻模型:
扯的有点远,关于select 、epoll读者有兴趣请自行研究。至此上篇docker web环境搭建和进攻性能演练以及提升方法已经描述好了,受时间、水平限制,画图也有点赶,有描述不当或者建议请随时联系我。本篇介绍完毕,防守篇--性能测试以及提升策略,将在下篇阐述。
附某公有云的一个查询接口性能反馈:
通过给没个线程进行打标数字,可以看出标记序号为0,4,8,2,1,6的线程有了正常返回,也可以看出来某公有云的相关接口并发限制为6,超出的并发将拒绝服务并将返回Api concurrency limit。
END
领取专属 10元无门槛券
私享最新 技术干货