一、前言我用Django写了一个上传大文件的Api接口。现在想在本地检查一下接口并发的稳定性。有什么好的解决办法吗?本文以文件上传为例,谈谈Jmeter并发执行Python脚本的完备性。流程二、Python实现文件上传。大文件上传包括4个步骤,分别是:获取文件信息和分片个数,分段分片,上传-API文件合并-API文件路径参数化2-1获取文件信息和分片个数首先,获取文件的大小和然后使用预设的分片大小得到总的段数最后得到文件名和md5值,'rb')asf:data=f.read()returnhashlib.md5(data).hexdigest()defget_filename(self,filepath):"""获取文件原名"""#filenamewithsuffixfilename_with_suffix=os.path.basename(filepath)#文件名filename=filename_with_suffix.split('.')[0]#后缀名suffix=filename_with_suffix.split('.')[-1]returnfilename_with_suffix,filename,suffixdefget_chunk_info(self,file_path):"""获取段信息"""#获取文件总大小(字节)file_total_size=os.path.getsize(file_path)print(file_total_size)#总段数total_chunks_num=math.ceil(file_total_size/self.chunk_size)#文件名(带后缀)filename=self.get_filename(file_path)[0]#文件的md5值file_md5=self.get_file_md5(file_path)returnfile_total_size,total_chunks_num,filename,file_md52-2分片和multipart上传利用分片总数和分片大小对文件进行分片,调用分片文件上传接口importrequestsdefdo_chunk_and_upload(self,file_path):"""对文件进行分片和分片处理upload"""file_total_size,total_chunks_num,filename,file_md5=self.get_chunk_info(file_path)#traverseforindexinrange(total_chunks_num):print('{}thfileupload'.format(index+1))ifindex+1==total_chunks_num:partSize=file_total_size%chunk_sizeelse:partSize=chunk_size#文件偏移offset=index*chunk_size#生成分片id,从1开始chunk_id=index+1print('开始准备上传文件')print("Shardid:",chunk_id,"文件偏移量:",offset,",currentfragmentsize:",partSize,)#分片上传文件self.__upload(offset,chunk_id,file_path,file_md5,filename,partSize,total_chunks_num)def__upload(self,offset,chunk_id,file_path,file_md5,filename,partSize,total):"""批量上传文件"""url='http://**/file/brust/upload'params={'chunk':chunk_id,'fileMD5':file_md5,'fileName':filename,'partSize':partSize,'total':total}#根据文件路径和偏移量,读取文件二进制数据,files=files).textprint(resp)2-3合并文件最后调用合并文件的接口将小文件合并成大文件defmerge_file(self,filepath):"""Merge"""url='http://**/file/brust/merge'file_total_size,total_chunks_num,filename,file_md5=self.get_chunk_info(filepath)payload=json.dumps({"fileMD5":file_md5,"chunkTotal":total_chunks_num,"fileName":filename})print(payload)headers={"Content-Type":"application/json"}resp=requests.post(url,headers=headers,data=payload).textprint(resp)2-4文件路径参数化对于并发执行,参数化文件上传路径#fileupload.py...if__name__=='__main__':filepath=sys.argv[1]#每个分片的大小(MB)chunk_size=2*1024*1024fileApi=FileApi(chunk_size)#分片上传fileApi.do_chunk_and_upload(filepath)#合并fileApi.merge_file(filepath)3.Jmeter并发执行创建并发Jmeter流程之前,我们需要写一个批处理脚本。执行批处理脚本时,需要和文件路径一起执行#cmd.bat@echooffsetfilepath=%1pythonC:\Users\xingag\Desktop\rpc_demo\fileupload.py%*然后,新建一个CSV文件本地写多个文件路径#准备多个文件路径(csv)C:\\Users\\xingag\\Desktop\\charles-proxy-4.6.1-win64.msiC:\\Users\\xingag\\Desktop\\V2.0.pdfC:\\Users\\xingag\\Desktop\\HBuilder1.zipC:\\Users\\xingag\\Desktop\\HBuilder2.zip接下来就可以使用Jmeter创建并发进程了。完整的步骤如下:创建一个测试计划,在下面添加一个线程组,这里的线程组数量和上面的文件数量保持一致即可。在线程组下,在同步定时器中添加“同步定时器”。同步定时器中的“模拟用户组数”与上述参数个数一致。添加CSV数据文件设置指向上面准备的csv数据文件,并设置文件格式为UTF-8,变量名设置为file_path,最后设置线程共享模式为“当前线程组”添加调试采样器为了方便调试添加一个OS进程采样器选择上面创建的批处理文件,命令行参数设置为“${file_path”}”添加查看结果数4.最后运行上面创建的Jmeter并发进程,你可以在结果数中查看并发上传文件的结果。当然我们可以增加并发文件数来模拟真实的使用场景,只需要修改CSV数据源和Jmeter的参数就可以使用了。最近整理了上百G的Python学习资料,包括初学者电子书、教程、源码等,免费分享给大家!想上“Python编程学习圈”,发“J”免费领取
