当前位置:   article > 正文

Locust初次体验【解决webUI没数据】_locust peekconsoleinput 存储空间不足

locust peekconsoleinput 存储空间不足

官方文档What is Locust? — Locust 2.14.2 documentation

目录

Widows篇

Centos7 & Locust安装及踩坑

User、Httpuser、Fasthttpuser描述

Taskset、SequentialTaskSet描述


Widows篇

webUI模式跑起来没有数据。。。运行显示。???;

  1. E:\T_Work\other\WB_Locust\my_locustfiles>locust
  2. [2023-02-14 09:57:44,530] PC-20190108TSZQ/INFO/locust.main: Starting web interface at http://127.0.0.1:8089
  3. [2023-02-14 09:57:44,575] PC-20190108TSZQ/INFO/locust.main: Starting Locust 2.14.2
  4. [2023-02-14 09:57:44,708] PC-20190108TSZQ/WARNING/root: Exception in keyboard input poller: (8, 'PeekConsoleInput', '存储空间不足,无法处理
  5. 此命令。')
  6. [2023-02-14 10:00:13,088] PC-20190108TSZQ/INFO/locust.runners: Ramping to 5 users at a rate of 1.00 per second
  7. [2023-02-14 10:00:17,090] PC-20190108TSZQ/INFO/locust.runners: All users spawned: {"Boon_User": 1, "JUM_User": 1, "My_App": 1, "My_User": 1, "My_talent_rig": 0, "My_talent_swagger": 0, "Myc_User": 0, "VI_Us
  8. [2023-02-14 10:00:17,090] PC-20190108TSZQ/INFO/locust.runners: All users spawned: {"Boon_User": 1, "JUM_User": 1, "My_App": 1, "My_User": 1,
  9. er": 0, "ZJ_User": 1} (5 total users)
  10. End-My_App
  11. [2023-02-14 10:01:52,372] PC-20190108TSZQ/INFO/locust.runners: Ramping to 1 users at a rate of 1.00 per second
  12. [2023-02-14 10:01:52,373] PC-20190108TSZQ/INFO/locust.runners: All users spawned: {"Boon_User": 1, "JUM_User": 0, "My_App": 0, "My_User": 0,
  13. er": 0, "ZJ_User": 0} (1 total users)
  14. WARNING: gevent: Unhandled error with no watcher
  15. Traceback (most recent call last):
  16. File "E:\Python\Lib\site-packages\gevent\libuv\loop.py", line 44, in python_queue_callback
  17. def python_queue_callback(self, watcher_ptr, revents):
  18. KeyboardInterrupt
  19. Traceback (most recent call last):
  20. File "E:\Python\Lib\site-packages\gevent\_ffi\loop.py", line 270, in python_check_callback
  21. def python_check_callback(self, watcher_ptr): # pylint:disable=unused-argument
  22. KeyboardInterrupt

解决文案一:原因是gevent(协程,locust 压测要用到的)这个库版本不一致导致的,更新一下:

python.exe -m pip install --upgrade gevent==21.12.0 -i https://mirrors.aliyun.com/pypi/simple/

解决文案二:把‘locust’,'gevent', 'geventhttpclient', 'greenlet',全部删掉,重新安装即可

重新安装出现警告

原因分析:安装package时中途中断

需要在目录【...\Python\Lib\site-packages】删除~ip文件夹后,再次重新安装,就正常运行有数据返回;

再次运行就可以打开Web-ui界面了

  

 

安装Locust

命行模式:python.exe -m pip install locust

代码段主要作用为创建用户或用户组角色【按wait_time、weight自定义选择执行】

User :表示要生成进行负载测试的系统的 HTTP“用户”

---HttpUser:比User类更常用,因为它添加了一个client属性,用来发送HTTP请求

task :表示用户要进行的操作【用户行为】

  • 方法前添加@task才会执行操作
  • 访问首页 → 登录 → 增、删改查 → homPage

tasks:指定为一个列表,那么每次执行任务时,它将从tasks属性中随机选择

tasks = {My_talent_rig: 1} 
--->每次执行
tasks = {My_talent_rig: 1,My_talent_swagger:5} 
--->My_talent_swagger执行次数是My_talent_rig的五倍

wait_time:时间间隔

  • 固定时间, 由constant(wait)函数提供

  • 区间随机时间: `between(min_wait, max_wait)函数

  • 自适应节奏时间: constant_pacing用于确保任务每 X 秒(最多)运行一次

  • 固定吞吐量,由constant_throughput函数提供

weight

        测试中,存在多个User Class,默认情况下locust将为每个User Class的实例的数量是相同的。通过设置weight属性,来控制locust为我们的User Class生成不同数量的实例。

命令行模式启动:locust --headless --users 5 --spawn-rate 1 --run-time 30m --csv=wb_example

框架是通过命令locust运行的,常用参数有:

  • -H:指定测试的主机地址(注:会覆盖Locust类指定的主机地址)
  • -f:指定测试脚本地址(注:脚本中必须包含一个Locust的衍生类)
  • --no-web:不启动web网页,而是直接开始运行测试,需提供属性-c和-r
  • -u or users:并发的用户数,与--no-web一起使用
  • -r or spawn-rate:每秒启动的用户数,与--no-web一起使用
  • -t or run-time:运行时间(单位:秒),与--no-web一起使用
  • csv : 保存CSV报告数据,默认保存文件【wb_example_exceptions.csv、wb_example_failures.csv、wb_example_stats.csv、wb_example_stats_history.csv】

  1. import os,sys
  2. pathS = os.getcwd()
  3. Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
  4. root_Path = os.path.dirname(pathS)
  5. sys.path.append(Project_Path)
  6. sys.path.append(root_Path)
  7. from locust import HttpUser, task , between , User,constant,constant_pacing, constant_throughput,events
  8. import os
  9. from other.WB_Locust.my_locustfiles.locustfile01 import B_Set_UP,M_Get
  10. from other.WB_Locust.my_locustfiles.locustfile_php import My_talent_swagger
  11. from other.WB_Locust.my_locustfiles.locustfile_php import My_talent_rig
  12. from other.WB_Locust.my_locustfiles.locustfile01 import My_App
  13. class My_User(User): # 请求一个任务
  14. host = "http://m-test.xxxxtest.cn"
  15. wait_time = between(0.5, 5)
  16. weight = 1
  17. @task
  18. def My_User(self):
  19. pass
  20. class VI_User(User): # 请求一个任务
  21. host = "http://m-test.xxxxtest.cn"
  22. wait_time = constant(3)
  23. weight = 1
  24. @task
  25. def VI_User(self):
  26. pass
  27. class JUM_User(User): # 请求一个任务
  28. host = "http://m-test.xxxxtest.cn"
  29. wait_time = constant_pacing(3)
  30. weight = 2
  31. @task
  32. def JUM_User(self):
  33. pass
  34. class Boon_User(User): # 请求一个任务
  35. host = "http://m-test.xxxxtest.cn"
  36. wait_time = constant_throughput(5)
  37. weight = 2
  38. @task
  39. def Boon_User(self):
  40. pass
  41. class ZJ_User(HttpUser): # 请求一个任务组【TaskSet】
  42. host = "http://m-test.xxxxtest.cn"
  43. wait_time = between(2,3)
  44. weight = 2
  45. tasks = {B_Set_UP:1}
  46. @task
  47. def ZJ_User(self):
  48. pass
  49. class Myc_User(HttpUser): # 请求一个任务组【TaskSet】
  50. host = "http://member-service.xxxxtest.cn"
  51. tasks = {M_Get:2}
  52. @task
  53. def Myc_User(self):
  54. pass
  55. class My_App(HttpUser): # 请求一个任务组【TaskSet】
  56. host = "http://api-service.xxxxtest.cn"
  57. tasks = {My_App:1}
  58. @task
  59. def My_App(self):
  60. pass
  61. class My_talent_swagger(HttpUser):
  62. wait_time = between(10,20)
  63. host = "http://member-service.xxxxtest.cn"
  64. tasks = {My_talent_swagger: 1}
  65. @task
  66. def My_talent_swagger(self):
  67. pass
  68. class My_talent_rig(HttpUser):
  69. wait_time = between(5,6)
  70. host = "http://rig-portal.xxxxtest.cn"
  71. tasks = {My_talent_rig: 1}
  72. @task
  73. def My_talent_rig(self):
  74. pass
  75. if __name__ == '__main__':
  76. os.system("locust --headless --users 5 --spawn-rate 1 --run-time 30m --csv=wb_example")
  77. # 命令行执行locust
  78. # locust --headless --users 10 --spawn-rate 1 --tun-time 1m -l -H https://m-test.xxxxtest.cn
  79. # --tags WB 只执行标记为WB的任务[debug调试]
  80. # locust --headless --users 10 --spawn-rate 1 --tun-time 1m -l -H https://m-test.xxxxtest.cn --tags WB
  81. # exclude-tags WB 执行标识不为WB的任务
前端--逻辑代码文件

请求值参:catch_response = True 为检查点,结合with使用

  1. @ 多重嵌套任务
  2. class xxx(TaskSet):
  3.         class AAA(TaskSet):
  4.                 @task
  5.                 def BBB(self):
  6. print('000')
  7. class CCC(TaskSet):
  8. @task
  9. def EEE(self):
  10. print('123')
  11. with self.client.get("/shop/introduce/59/",catch_response=True) as Res:
  12. if "万表网" in Res.text:
  13. Res.success()
  14. else:
  15. Res.failure("No member message!")
  1. # locustfile01.py
  2. import os,sys
  3. pathS = os.getcwd()
  4. Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
  5. root_Path = os.path.dirname(pathS)
  6. sys.path.append(Project_Path)
  7. sys.path.append(root_Path)
  8. from locust import HttpUser, task , between , tag,User,constant,constant_pacing,TaskSet,constant_throughput,events
  9. from other.WB_Locust.common.api_token import *
  10. from other.WB_Locust.Config import Config
  11. import json,time,random,requests
  12. class SSet_UP():
  13. def START_009(self):
  14. K_token = WB_ApiMD.MD5_token(self,1,1)
  15. Api_HeaderToKen = HeaderToken.Header_token(self,3, K_token)
  16. Member_HeaderToKen = HeaderToken.Header_token(self, 5, K_token)
  17. # PHP专用
  18. # PHP_mParams = Config.php_mParams
  19. # P_token = WB_ApiMD.MD5_token(self, 7, 5)
  20. # Php_HeaderToKen = HeaderToken.Header_token(self, 2, P_token)
  21. PHP_mParams = ""
  22. P_token = ""
  23. Php_HeaderToKen = ""
  24. return K_token,Api_HeaderToKen,Member_HeaderToKen,Php_HeaderToKen,P_token,PHP_mParams
  25. class B_Set_UP(TaskSet):
  26. @task
  27. class Test_HttpUser(TaskSet):
  28. @tag('42470')
  29. @task(3)
  30. def view_goods(self):
  31. self.client.get("/goods/42470")
  32. @tag('shoubiao')
  33. @task(2)
  34. def view_shoubiao(self):
  35. self.client.get("/shoubiao.html")
  36. @tag('fenlei')
  37. @task(1)
  38. def view_fenlei(self):
  39. self.client.get("/fenlei.html")
  40. self.interrupt()
  41. @task
  42. class Woman_UserA(TaskSet):
  43. @task
  44. def Woman_UserA(self):
  45. self.client.get("/shop/59/")
  46. self.interrupt()
  47. @task
  48. class Woman_UserB(TaskSet):
  49. @task
  50. def Woman_UserB(self):
  51. self.client.get("/goods/42471")
  52. @task
  53. def Woman_UserC(self):
  54. self.client.get("/goods/67")
  55. self.interrupt()
  56. @task
  57. class Woman_UserS(TaskSet):
  58. @task
  59. def Woman_UserB1(self):
  60. self.client.get("/goods/16641")
  61. @task
  62. def Woman_UserC2(self):
  63. self.client.get("/goods/42823")
  64. self.interrupt()
  65. @task
  66. class SWoman_UserS(TaskSet):
  67. '商城静态页面接口请求'
  68. @tag('WB')
  69. @task(2)
  70. def SWoman_UserB1(self):
  71. with self.client.get("/shop/introduce/59/",catch_response=True) as Res:
  72. if "万表网" in Res.text:
  73. Res.success()
  74. else:
  75. Res.failure("No member message!")
  76. @tag('WB')
  77. @task(2)
  78. def SWoman_UserC2(self):
  79. with self.client.get("/shop/dynamic/59/",catch_response=True) as Res:
  80. if "万表网" in Res.text:
  81. Res.success()
  82. else:
  83. Res.failure("No member message!")
  84. self.interrupt()
  85. class M_Get(TaskSet):
  86. '会员资料接口请求'
  87. def on_start(self):
  88. Data_key = SSet_UP().START_009()
  89. self.My_y = Data_key[2]
  90. def on_stop(self):
  91. self.client.get('/member/loginOut',headers=self.My_y)
  92. @tag('WB')
  93. @task(5)
  94. def login(self): # 会员登录接口请求
  95. Url_headers = {'Content-Type': 'application/json', 'Connection': 'keep-alive',
  96. 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 8.1.0; Redmi Note 5 MIUI/V9.6.4.0.OEICNFD) WBIAO_MARKET_20190471_8.1.0 com.wbiao.wbapp 3.4.9#huawei# runningIn_1'}
  97. Pcontent = {"identity": '188000000' + str(random.randint(00,99)), "identityType": "1", "password": 111111, "platformSource": "Mall",
  98. "remember": "true", "terminalType": "PC"}
  99. Url_loring = 'http://member-service.xxxxtest.cn/member/login'
  100. with self.client.post(url=Url_loring,data=json.dumps(Pcontent),catch_response=True,headers=Url_headers) as Res:
  101. if "memberCode" in Res.text:
  102. Res.success()
  103. else:
  104. Res.failure("Wrong")
  105. @tag('SH')
  106. @task
  107. def member_get(self): # 获取个人资料
  108. with self.client.get('/member/center/get',catch_response=True, headers=self.My_y) as Res:
  109. if "5102252" in Res.text:
  110. Res.success()
  111. else:
  112. Res.failure("No member message!")
  113. @tag('SH')
  114. @task
  115. def member_message(self): # 获取会员基本信息
  116. with self.client.get('/member/center/getMember',
  117. catch_response=True,
  118. headers=self.My_y) as Res:
  119. if "5102252" in Res.text:
  120. Res.success()
  121. else:
  122. Res.failure("No member message!")
  123. class My_App(TaskSet): #api-APP请求
  124. def on_start(self):
  125. Data_key = SSet_UP().START_009()
  126. self.K_token = Data_key[0]
  127. self.HeaderToKen = Data_key[1]
  128. def on_stop(self):
  129. print("End-My_App")
  130. @tag('debug')
  131. @task
  132. def My_Cart(self):
  133. app_mParams = ""
  134. api_key = WB_ApiMD.api_get(app_mParams,'1','1')
  135. K_word = api_key + '&wb-token=' + self.K_token + Config.T_keyword
  136. with self.client.get('/api/cart/getList?' + api_key + WB_ApiMD.sign_R(K_word),
  137. headers=self.HeaderToKen,
  138. catch_response=True) as Res:
  139. if "cartGoodsList" in Res.text:
  140. Res.success()
  141. else:
  142. Res.failure("Faile")
  143. '''
  144. class My_talent_swagger(TaskSet): # Member swagger
  145. def on_start(self):
  146. Data_key = SSet_UP().START_009()
  147. self.K_token = Data_key[0]
  148. self.HeaderToKen = Data_key[3]
  149. def on_stop(self):
  150. self.interrupt()
  151. @task
  152. def talent_get(self): # 达人-获取图文信息
  153. with self.client.get('/member/talentImageText/get?talentImageTextId=122',
  154. headers=self.HeaderToKen,
  155. catch_response=True) as Res:
  156. if "talentImageTextId" in Res.text:
  157. Res.success()
  158. else:
  159. Res.failure("Wrong")
  160. @task
  161. def talent_list(self): # 达人-查询列表
  162. list_data = {
  163. "pager": {
  164. "now": 0,
  165. "size": 5,
  166. "total": 5
  167. },
  168. "search": [
  169. {
  170. "name": "string",
  171. "value": "string"
  172. }
  173. ],
  174. "sort": [
  175. {
  176. "asc": 'true',
  177. "name": "string"
  178. }
  179. ]
  180. }
  181. with self.client.post('/member/talentImageText/getList',
  182. data=json.dumps(list_data),
  183. headers=self.HeaderToKen,
  184. catch_response=True) as Res:
  185. if "talentImageTextId" in Res.text:
  186. Res.success()
  187. else:
  188. Res.failure("Wrong")
  189. class My_talent_rig(TaskSet): # Rig Console
  190. def on_start(self):
  191. Data_key = SSet_UP().START_009()
  192. self.K_token = Data_key[4]
  193. self.HeaderToKen = Data_key[3]
  194. self.php_mParams = Data_key[5]
  195. def on_stop(self):
  196. self.interrupt()
  197. @task
  198. def rig_t_get(self): # 达人类目详情
  199. with self.client.get('/back/member/talent/class/get?id=1'+ self.php_mParams +'&sign='+self.K_token,
  200. headers=self.HeaderToKen,
  201. catch_response=True) as Res:
  202. if 'name' in Res.text:
  203. Res.success()
  204. else:
  205. Res.failure('Wrong')
  206. @task
  207. def rig_t_list(self): # 达人类目列表
  208. with self.client.get('/back/member/talent/class/list?' + self.php_mParams + '&sign=' + self.K_token,
  209. headers=self.HeaderToKen,
  210. catch_response=True) as Res:
  211. if 'name' in Res.text:
  212. Res.success()
  213. else:
  214. Res.failure('Wrong')
  215. @task
  216. def rig_t_highCommissionGoods(self): # 高佣金比例的商品列表
  217. Pcontent = {"brandCodes":[70,176],"goodsCode":"","models":""}
  218. with self.client.post('/back/member/talent/highCommissionGoods/list?' + self.php_mParams + '&sign=' + self.K_token,
  219. data= json.dumps(Pcontent),
  220. headers=self.HeaderToKen,
  221. catch_response=True) as Res:
  222. if 'name' in Res.text:
  223. Res.success()
  224. else:
  225. Res.failure('Wrong')
  226. '''
  227. # class My_cart(HttpUser):
  228. # host = "http://api-service.xxxxtest.cn"
  229. # tasks = {My_cart:1}
  230. # if __name__ == '__main__':
  231. # os.system("locust -f locustfile01.py --headless --users 1 --spawn-rate 1 --run-time 10")
后台-逻辑代码文件
  1. # locustfile_php.py
  2. import os,sys
  3. pathS = os.getcwd()
  4. Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
  5. root_Path = os.path.dirname(pathS)
  6. sys.path.append(Project_Path)
  7. sys.path.append(root_Path)
  8. from locust import HttpUser, task , between , tag,User,constant,constant_pacing,TaskSet,constant_throughput,events
  9. from other.WB_Locust.common.api_token import *
  10. from other.WB_Locust.Config import Config
  11. import json,time,random,requests
  12. class SSet_UP():
  13. def START_009(self):
  14. # K_token = WB_ApiMD.MD5_token(self,1,1)
  15. # Api_HeaderToKen = HeaderToken.Header_token(self,3, K_token)
  16. # Member_HeaderToKen = HeaderToken.Header_token(self, 5, K_token)
  17. # PHP专用
  18. PHP_mParams = Config.php_mParams
  19. P_token = WB_ApiMD.MD5_token(self, 7, 5)
  20. Php_HeaderToKen = HeaderToken.Header_token(self, 2, P_token)
  21. # Rig_HeaderToKen = HeaderToken.Header_token(self, 2, K_token)
  22. # app_mParams = ""
  23. # api_key = WB_ApiMD.api_get(app_mParams, str(1), str(1))
  24. # K_word = api_key + '&wb-token=' + K_token + Config.T_keyword
  25. # Res = requests.get(url='http://api-service.xxxxtest.cn/api/cart/getList?' + api_key + WB_ApiMD.sign_R(K_word),
  26. # headers=HeaderToKen)
  27. # print(Res.text)
  28. # print(Res.url)
  29. # print(api_key)
  30. # print(K_word)
  31. # return K_token,Api_HeaderToKen,Member_HeaderToKen,Php_HeaderToKen,P_token,PHP_mParams
  32. return Php_HeaderToKen, P_token, PHP_mParams
  33. class My_talent_swagger(TaskSet): # Member swagger
  34. def on_start(self):
  35. print("My_talent_swagger")
  36. Data_key = SSet_UP().START_009()
  37. self.HeaderToKen = Data_key[0]
  38. def on_stop(self):
  39. self.interrupt()
  40. @task
  41. def talent_get(self): # 达人-获取图文信息
  42. with self.client.get('/member/talentImageText/get?talentImageTextId=122',
  43. headers=self.HeaderToKen,
  44. catch_response=True) as Res:
  45. if "talentImageTextId" in Res.text:
  46. Res.success()
  47. else:
  48. Res.failure("Wrong")
  49. @task
  50. def talent_list(self): # 达人-查询列表
  51. list_data = {
  52. "pager": {
  53. "now": 0,
  54. "size": 5,
  55. "total": 5
  56. },
  57. "search": [
  58. {
  59. "name": "string",
  60. "value": "string"
  61. }
  62. ],
  63. "sort": [
  64. {
  65. "asc": 'true',
  66. "name": "string"
  67. }
  68. ]
  69. }
  70. with self.client.post('/member/talentImageText/getList',
  71. data=json.dumps(list_data),
  72. headers=self.HeaderToKen,
  73. catch_response=True) as Res:
  74. if "talentImageTextId" in Res.text:
  75. Res.success()
  76. else:
  77. Res.failure("Wrong")
  78. class My_talent_rig(TaskSet): # Rig Console
  79. def on_start(self):
  80. print("My_talent_rig")
  81. Data_key = SSet_UP().START_009()
  82. self.K_token = Data_key[1]
  83. self.HeaderToKen = Data_key[0]
  84. self.php_mParams = Data_key[2]
  85. def on_stop(self):
  86. self.interrupt()
  87. @task
  88. def rig_t_get(self): # 达人类目详情
  89. with self.client.get('/back/member/talent/class/get?id=1'+ self.php_mParams +'&sign='+self.K_token,
  90. headers=self.HeaderToKen,
  91. catch_response=True) as Res:
  92. if 'name' in Res.text:
  93. Res.success()
  94. else:
  95. Res.failure('Wrong')
  96. @task
  97. def rig_t_list(self): # 达人类目列表
  98. with self.client.get('/back/member/talent/class/list?' + self.php_mParams + '&sign=' + self.K_token,
  99. headers=self.HeaderToKen,
  100. catch_response=True) as Res:
  101. if 'name' in Res.text:
  102. Res.success()
  103. else:
  104. Res.failure('Wrong')
  105. @task
  106. def rig_t_highCommissionGoods(self): # 高佣金比例的商品列表
  107. Pcontent = {"brandCodes":[70,176],"goodsCode":"","models":""}
  108. with self.client.post('/back/member/talent/highCommissionGoods/list?' + self.php_mParams + '&sign=' + self.K_token,
  109. data= json.dumps(Pcontent),
  110. headers=self.HeaderToKen,
  111. catch_response=True) as Res:
  112. if 'name' in Res.text:
  113. Res.success()
  114. else:
  115. Res.failure('Wrong')
  116. # class My_cart(HttpUser):
  117. # host = "http://api-service.xxxxtest.cn"
  118. # tasks = {My_cart:1}
  119. # if __name__ == '__main__':
  120. # os.system("locust -f locustfile01.py --headless --users 1 --spawn-rate 1 --run-time 10")
执行
locust --headless --users 5 --spawn-rate 1 --run-time 30m --csv=wb_example
  • Type: 请求的类型,例如GET/POST。

  • Name:请求的路径。

  • reqs:当前请求的数量。

  • Fails:当前请求失败的数量。

  • Med:中间值,单位毫秒,一半的服务器响应时间低于该值,而另一半高于该值。

  • Avg:平均值,单位毫秒,所有请求的平均响应时间。

  • Min:请求的最小服务器响应时间,单位毫秒。

  • Max:请求的最大服务器响应时间,单位毫秒。

  • Average size:平均请求的大小,单位字节。

  • Req/s:是每秒钟请求的个数。

  • Failures/s:瞬时每秒失败数。

WebUI启动,均需要在命令行切换到执行文件的目录下,执行【locust】,对应打开链接即可 

Centos7 & Locust安装及踩坑

坑1:pip3 install locust ---> 99%无法安装,不是网络慢,就是各种依赖安装错误

解决:指定版本安装

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple locustio==2.14.2

坑2:Locust安装成功后,提示如下

ModuleNotFoundError: No module named '_ctypes'

解决:重新安装依赖包【libffi-devel】,并重新编译,添加环境匹配

yum install libffi-devel
  1. 查看一下Centos下安装python3路径【/usr/local/python3
  2. 查看一下安装python3源码包路径【/usr/local/python/Python-3.7.8rc1
  3. [root@localhost python]# cd Python-3.7.8rc1
  4. [root@localhost Python-3.7.8rc1]# ./configure --prefix=/usr/local/python3
  5. [root@localhost Python-3.7.8rc1]# make && make install
  6. 重新编译后,添加环境匹配
  7. [root@localhost Python-3.7.8rc1]# vi /etc/profile
  8. export PATH=/usr/local/python3/bin:$PATH ---->path添加一下python执行目录,并保存
  9. [root@localhost Python-3.7.8rc1]# source /etc/profile
  10. [root@localhost Python-3.7.8rc1]# locust --version
  11. locust 2.14.2 from /usr/local/python3/lib/python3.7/site-packages/locust (python 3.7.8rc1)
  12. 下面就是启动后应有的样子
  13. [root@localhost my_locustfiles]# locust
  14. [2023-03-01 16:27:57,070] localhost.localdomain/WARNING/locust.main: System open file limit '1024' is below minimum setting '10000'.
  15. It's not high enough for load testing, and the OS didn't allow locust to increase it by itself.
  16. See https://github.com/locustio/locust/wiki/Installation#increasing-maximum-number-of-open-files-limit for more info.
  17. [2023-03-01 16:27:57,071] localhost.localdomain/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
  18. [2023-03-01 16:27:57,080] localhost.localdomain/INFO/locust.main: Starting Locust 2.14.2
  19. [2023-03-01 16:30:04,736] localhost.localdomain/INFO/locust.runners: Ramping to 5 users at a rate of 1.00 per second
  20. [2023-03-01 16:30:08,739] localhost.localdomain/INFO/locust.runners: All users spawned: {"Boon_User": 1, "JUM_User": 1, "My_App": 1, "My_User": 1, "My_talent_rig": 0, "My_talent_swagger": 0, "Myc_User": 0, "VI_User": 0, "ZJ_User": 1} (5 total users)
  21. End-My_App
  22. 因为部署在Centos,外部访问还要对放开防火墙端口访问限制【8089
  23. [root@localhost my_locustfiles]# firewall-cmd --zone=public --add-port=8087/tcp --permanent
  24. [root@localhost my_locustfiles]# systemctl reload firewalld

现在外部就可以访问了

User、Httpuser、Fasthttpuser描述

User:自定义请求方式,一个User代表一个线程

设定:电脑总共12个内核,可同时处理24个线程,设置12个节点,开始执行并发测试:

  • FastHttpUsers 单核每秒可以处理接近 5000 个请求,每秒可以处理接近 6万个请求,实际按5万算
  • HttpUser 单核每秒可以处理接近 850个请求(18款 MacBook Pro i7 上测试) 2.6GHz),12个内核,使用 httpuser 后,每秒可以处理接近9000 个请求

所以,电脑12个节点全开的情况下,
(1)12节点全开,电脑CPU不过载,9000并发以下的时候使用httpuser
(2)12节点全开,电脑CPU过载了,9000并发以上了,考虑使用FastHttpUsers
(3)12节点全开,电脑CPU过载了,并发超过6万了,拓展节点机器继续分布式压测,比如电脑的CPU总共12核,可以开启12个节点,最大化利用CPU资源,增加电脑发给服务器的每秒的请求数。

注意:很容易因为理解不深刻,导致电脑每秒发给服务的请求数不够,比如在自己电脑20万并发,实际每秒只发送了9000个请求,服务器每秒接收到的并不是20万并发的请求数,通过分布式执行来确保20万确实是并发上去了。
 

Taskset、SequentialTaskSet描述

  • TaskSet是指动作集合,就是将某个功能整合在一起,能够完成一系列动作;
  • 当执行到Class Test03的时候,会进入该类里面,执行里面的任务;
  • 当进入该类执行任务的时候,需要使用self.interrupt()来退出这个任务,否则任务将会一直在这类里面执行内部的任务,无法跳出执行其他任务;
  • SequentialTaskSet同样是指动作集合,比原TaskSet多了个功能,可以让任务,从上往下按顺序执行,同样的,也需要使用self.interrupt()来退出这个任务;
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/863552
推荐阅读
相关标签
  

闽ICP备14008679号