Python server multi-process stress testing tool

Source: Internet
Author: User

Python server multi-process stress testing tool

This article describes a multi-process stress testing tool implemented by Python. The features of this tool are as follows:

  • Multi-Process

In most cases, stress testing is generally applicable to IO-intensive scenarios (such as access interfaces and waiting for responses). In this scenario, multi-threaded and multi-process separation is not obvious (see GIL for details ). However, if word table parameter encryption or returned content verification occurs, the multi-process transmission efficiency is improved significantly.

  • QPS can be specified

You can specify the QPS for sending pressure. Based on the concurrency and request time, You can estimate the peak QPS for sending. For example, if the concurrency is 10 and the response time is 100 ms, the QPS peak value should be (1 s/100 ms * 10) = 100, this tool can maintain the QPS stably at a volume smaller than the peak value.

  • Easy to expand

Why do we need a DIY stress testing tool? Common server pressure testing tools, such as http_load and jmeter, are either http or code-based. For example, during the stress test of the thrift interface, it is difficult to extend the java program through jmeter. However, when it comes to scenario-based stress testing or strange sdks, for example, the interface for stress testing in this article is the python message SDK automatically generated through java code and involves Scenario-Based stress testing, it is difficult to solve this problem through a general server pressure test tool.

1. Press the code

Decoupling

The following is the implementation of the stress testing code. As you can see, I use the abc Package here to make an abstract class.

The business test code, such as automated case, inherits the abstract class and obtains the stress test capability, decoupling the stress test from the automated test.

There are two abstract methods.

Vocab ()-constructor vocabulary

Press ()-publishing Logic

It is decorated by the @ abc. abstractmethod modifier and must be implemented in the subclass.

The run () method is used for stress testing. After the sub-class vocabulary method and the stress logic are implemented, you can directly call the run () method for stress testing.

Fixed QPS

Fixed QPS is implemented through the management process. There are two processes:

One is the worker_process process, which calls the press () Sending pressure logic function, and this process can specify the concurrency concurrent, which is the actual sending pressure process, it is worth noting that time is used in worker_process. sleep () is used to control the sending speed.

The other is the manager_process process, which calculates the actual qps at intervals, compares it with the set qps, and then adjusts the sleep time in worker_process. For example, the actual qps is less than the set qps, then you need to sleep for a while.

I have to mention how multi-process variables are shared?

Here we use the Manager package in multiprocessing. This package provides the ability of multi-process shared variables. Here I use the Namespace data structure to store multi-process counts. During use, I suspect that the Manager Namespace shares variables between processes by reading and writing files. I have not studied this in depth.

#-*-Coding: UTF-8 -*-
Import abc
Import time
From multiprocessing import Lock, Process, Manager


Class Press (object ):

_ Metaclass _ = abc. ABCMeta

Def _ init _ (self, qps = 100, concurrent = 10 ):
Self. qps = qps
Self. concurrent = concurrent
Self. mutex = Lock ()
Self. local = Manager (). Namespace ()
Self. local. count = 0
Self. local. sleep = 0.1
Self. manager_gap = 0.5
Self. precision = 0.1
Self. vocab_list = list ()
Self. vocab ()

Def manager_process (self ):
While True:
With self. mutex:
Current_qps = self. local. count/self. manager_gap
Self. local. count = 0
Print self. local. sleep, current_qps

If current_qps <self. qps:
Self. local. sleep = self. local. sleep * (1.0-self. precision)
Else:
Self. local. sleep = self. local. sleep * (1.0 + self. precision)
Time. sleep (self. manager_gap)

Def worker_process (self ):
While True:
With self. mutex:
Self. local. count + = 1
Time. sleep (self. local. sleep)
Self. press ()

@ Abc. abstractmethod
Def vocab (self ):
Return

@ Abc. abstractmethod
Def press (self ):
Return

Def run (self ):
Processes = [Process (target = self. worker_process) for index in range (self. concurrent)]
Processes. append (Process (target = self. manager_process ))
For process in processes:
Process. start ()
For process in processes:
Process. join ()

2. Actual Stress Testing

An example of sending pressure is provided. In three steps ~

QueryVmPress inherits the Press class and obtains the stress sending capability.

Then the vocab method is implemented to construct the word table.

The press method is implemented. here we can see that QueryVmScenario. press_vm (vocab) and QueryVmScenario are deployed in an automated case. Only one of the interfaces is called. The compilation of this interface is complicated, and it is also the reason why you need to make a stress testing tool yourself.

#-*-Coding: UTF-8 -*-
Import random
From query. query_vm_scenario import QueryVmScenario
From db. vm_dao import Dao as vm_dao
From db. account_dao import Dao as account_dao
From press import Press
From lib import common
From vocab import Vocab

Class QueryVmVocab (Vocab ):

Def _ init _ (self ):
Vocab. _ init _ (self)


Class QueryVmPress (Press ):

Def _ init _ (self, qps = 100, concurrent = 10 ):
Press. _ init _ (self, qps, concurrent)

Def vocab (self ):
For account in account_dao.query_all_account (limit = 10 ):
Account_name = account [1]
Account_password = account [2]
Res = common. login_by_account (account_name, account_password)
For item in vm_dao.query_vm_by_account (account_name, limit = 100 ):
Vm_uuid = item [1]
Vocab = QueryVmVocab ()
Vocab. add ('session _ uuid ', res. inventory. uuid)
Vocab. add ('vm _ uuid ', vm_uuid)
Self. vocab_list.append (vocab)
Return self. vocab_list

Def press (self ):
Vocab = self. vocab_list [random. randint (0, len (self. vocab_list)-1)]
QueryVmScenario. press_vm (vocab)


If _ name _ = '_ main __':
QueryVmPress (qps = 100, concurrent = 10). run ()

QueryVmPress (qps = 100, concurrent = 10). run (), the pressure test is performed according to qps.

0.1 20.0
0.09 40.0
0.081 60.0
0.0729 80.0
0.06561 60.0
0.059049 80.0
0.0531441 60.0
0.04782969 80.0
0.043046721 80.0
0.0387420489 80.0
0.03486784401 80.0
0.031381059609 100.0
0.0345191655699 80.0
0.0310672490129 88.0
0.0279605241116 92.0
0.0251644717005 100.0
0.0276809188705 80.0
0.0249128269835 100.0
0.0274041096818 100.0
0.03014452065 80.0
0.027130068585 100.0
0.0298430754435 80.0
0.0268587678991 100.0
0.029544644689 92.0

The first column is the sleep time, and the second column is the actual QPS. As you can see, the qps will be dynamically stabilized on the set value.

3. Mixed pressure

This can be done when multiple interfaces are mixed.

First, write the python class for single pressure. In the code for single pressure, you can see that I have implemented the QueryVmVocab class and the table name is the word table type. This class is integrated from Vocab, vocab is a dictionary encapsulation.

During mixed pressure, the word table is summarized and shuffled first. When the word table is popped up, isinstance is used to determine the Word Table type and different stress issuing functions are called for stress testing.

Vocab implementation

#-*-Coding: UTF-8 -*-
Import abc

Class Vocab (object ):

_ Metaclass _ = abc. ABCMeta

Def _ init _ (self ):
Self. vocab = dict ()

Def add (self, key, value ):
Self. vocab [key] = value

Def get (self, key ):
Return self. vocab. get (key)

Def remove (self, key ):
Del self. vocab [key]

Mixed pressure implementation

#-*-Coding: UTF-8 -*-
Import random

From press import Press
From query_eip_press import QueryEipPress, QueryEipVocab
From query_image_press import QueryImagePress, QueryImageVocab
From query_snapshot_press import QuerySnapshotPress, QuerySnapshotVocab
From query_vm_press import QueryVmPress, QueryVmVocab

From query. query_eip_scenario import QueryEipScenario
From query. query_image_scenario import QueryImageScenario
From query. query_snapshot_scenario import QuerySnapshotScenario
From query. query_vm_scenario import QueryVmScenario


Class MixedPress (Press ):

Def _ init _ (self, qps = 100, concurrent = 10 ):
Press. _ init _ (self, qps, concurrent)

Def vocab (self ):
Self. vocab_list.extend (QueryEipPress (). vocab ())
Self. vocab_list.extend (QueryImagePress (). vocab ())
Self. vocab_list.extend (QuerySnapshotPress (). vocab ())
Self. vocab_list.extend (QueryVmPress (). vocab ())

Def press (self ):
Vocab = self. vocab_list [random. randint (0, len (self. vocab_list)-1)]
If isinstance (vocab, QueryEipVocab ):
QueryEipScenario. press_eip (vocab)
Elif isinstance (vocab, QueryImageVocab ):
QueryImageScenario. press_image (vocab)
Elif isinstance (vocab, QuerySnapshotVocab ):
QuerySnapshotScenario. press_snapshot (vocab)
Elif isinstance (vocab, QueryVmVocab ):
QueryVmScenario. press_vm (vocab)


If _ name _ = '_ main __':
MixedPress (200, 50). run ()

Postscript

This is just a small Implementation of the function and is for your reference. If something is wrong, I hope you can correct it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.