赞
踩
官方文档:What is Locust? — Locust 2.14.2 documentation
目录
webUI模式跑起来没有数据。。。运行显示。???;
- E:\T_Work\other\WB_Locust\my_locustfiles>locust
- [2023-02-14 09:57:44,530] PC-20190108TSZQ/INFO/locust.main: Starting web interface at http://127.0.0.1:8089
- [2023-02-14 09:57:44,575] PC-20190108TSZQ/INFO/locust.main: Starting Locust 2.14.2
- [2023-02-14 09:57:44,708] PC-20190108TSZQ/WARNING/root: Exception in keyboard input poller: (8, 'PeekConsoleInput', '存储空间不足,无法处理
- 此命令。')
- [2023-02-14 10:00:13,088] PC-20190108TSZQ/INFO/locust.runners: Ramping to 5 users at a rate of 1.00 per second
- [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
- [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,
- er": 0, "ZJ_User": 1} (5 total users)
- End-My_App
- [2023-02-14 10:01:52,372] PC-20190108TSZQ/INFO/locust.runners: Ramping to 1 users at a rate of 1.00 per second
- [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,
- er": 0, "ZJ_User": 0} (1 total users)
- WARNING: gevent: Unhandled error with no watcher
- Traceback (most recent call last):
- File "E:\Python\Lib\site-packages\gevent\libuv\loop.py", line 44, in python_queue_callback
- def python_queue_callback(self, watcher_ptr, revents):
- KeyboardInterrupt
- Traceback (most recent call last):
- File "E:\Python\Lib\site-packages\gevent\_ffi\loop.py", line 270, in python_check_callback
- def python_check_callback(self, watcher_ptr): # pylint:disable=unused-argument
- 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 :表示用户要进行的操作【用户行为】
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
运行的,常用参数有:
- import os,sys
- pathS = os.getcwd()
- Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
- root_Path = os.path.dirname(pathS)
- sys.path.append(Project_Path)
- sys.path.append(root_Path)
-
- from locust import HttpUser, task , between , User,constant,constant_pacing, constant_throughput,events
- import os
- from other.WB_Locust.my_locustfiles.locustfile01 import B_Set_UP,M_Get
- from other.WB_Locust.my_locustfiles.locustfile_php import My_talent_swagger
- from other.WB_Locust.my_locustfiles.locustfile_php import My_talent_rig
- from other.WB_Locust.my_locustfiles.locustfile01 import My_App
-
- class My_User(User): # 请求一个任务
- host = "http://m-test.xxxxtest.cn"
- wait_time = between(0.5, 5)
- weight = 1
- @task
- def My_User(self):
- pass
-
- class VI_User(User): # 请求一个任务
- host = "http://m-test.xxxxtest.cn"
- wait_time = constant(3)
- weight = 1
- @task
- def VI_User(self):
- pass
-
- class JUM_User(User): # 请求一个任务
- host = "http://m-test.xxxxtest.cn"
- wait_time = constant_pacing(3)
- weight = 2
- @task
- def JUM_User(self):
- pass
-
- class Boon_User(User): # 请求一个任务
- host = "http://m-test.xxxxtest.cn"
- wait_time = constant_throughput(5)
- weight = 2
- @task
- def Boon_User(self):
- pass
-
- class ZJ_User(HttpUser): # 请求一个任务组【TaskSet】
- host = "http://m-test.xxxxtest.cn"
- wait_time = between(2,3)
- weight = 2
- tasks = {B_Set_UP:1}
- @task
- def ZJ_User(self):
- pass
-
- class Myc_User(HttpUser): # 请求一个任务组【TaskSet】
- host = "http://member-service.xxxxtest.cn"
- tasks = {M_Get:2}
- @task
- def Myc_User(self):
- pass
- class My_App(HttpUser): # 请求一个任务组【TaskSet】
- host = "http://api-service.xxxxtest.cn"
- tasks = {My_App:1}
- @task
- def My_App(self):
- pass
-
- class My_talent_swagger(HttpUser):
- wait_time = between(10,20)
- host = "http://member-service.xxxxtest.cn"
- tasks = {My_talent_swagger: 1}
- @task
- def My_talent_swagger(self):
- pass
- class My_talent_rig(HttpUser):
- wait_time = between(5,6)
- host = "http://rig-portal.xxxxtest.cn"
- tasks = {My_talent_rig: 1}
- @task
- def My_talent_rig(self):
- pass
-
- if __name__ == '__main__':
- os.system("locust --headless --users 5 --spawn-rate 1 --run-time 30m --csv=wb_example")
-
- # 命令行执行locust
- # locust --headless --users 10 --spawn-rate 1 --tun-time 1m -l -H https://m-test.xxxxtest.cn
- # --tags WB 只执行标记为WB的任务[debug调试]
- # locust --headless --users 10 --spawn-rate 1 --tun-time 1m -l -H https://m-test.xxxxtest.cn --tags WB
- # exclude-tags WB 执行标识不为WB的任务

前端--逻辑代码文件
请求值参:catch_response = True 为检查点,结合with使用
- @ 多重嵌套任务
- class xxx(TaskSet):
- class AAA(TaskSet):
- @task
- def BBB(self):
- print('000')
- class CCC(TaskSet):
- @task
- def EEE(self):
- print('123')
- with self.client.get("/shop/introduce/59/",catch_response=True) as Res:
- if "万表网" in Res.text:
- Res.success()
- else:
- Res.failure("No member message!")
-

- # locustfile01.py
-
-
-
- import os,sys
- pathS = os.getcwd()
- Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
- root_Path = os.path.dirname(pathS)
- sys.path.append(Project_Path)
- sys.path.append(root_Path)
-
- from locust import HttpUser, task , between , tag,User,constant,constant_pacing,TaskSet,constant_throughput,events
- from other.WB_Locust.common.api_token import *
- from other.WB_Locust.Config import Config
- import json,time,random,requests
-
- class SSet_UP():
- def START_009(self):
- K_token = WB_ApiMD.MD5_token(self,1,1)
- Api_HeaderToKen = HeaderToken.Header_token(self,3, K_token)
- Member_HeaderToKen = HeaderToken.Header_token(self, 5, K_token)
- # PHP专用
- # PHP_mParams = Config.php_mParams
- # P_token = WB_ApiMD.MD5_token(self, 7, 5)
- # Php_HeaderToKen = HeaderToken.Header_token(self, 2, P_token)
- PHP_mParams = ""
- P_token = ""
- Php_HeaderToKen = ""
- return K_token,Api_HeaderToKen,Member_HeaderToKen,Php_HeaderToKen,P_token,PHP_mParams
-
- class B_Set_UP(TaskSet):
- @task
- class Test_HttpUser(TaskSet):
- @tag('42470')
- @task(3)
- def view_goods(self):
- self.client.get("/goods/42470")
-
- @tag('shoubiao')
- @task(2)
- def view_shoubiao(self):
- self.client.get("/shoubiao.html")
-
- @tag('fenlei')
- @task(1)
- def view_fenlei(self):
- self.client.get("/fenlei.html")
- self.interrupt()
-
- @task
- class Woman_UserA(TaskSet):
- @task
- def Woman_UserA(self):
- self.client.get("/shop/59/")
- self.interrupt()
-
- @task
- class Woman_UserB(TaskSet):
- @task
- def Woman_UserB(self):
- self.client.get("/goods/42471")
-
- @task
- def Woman_UserC(self):
- self.client.get("/goods/67")
- self.interrupt()
-
- @task
- class Woman_UserS(TaskSet):
- @task
- def Woman_UserB1(self):
- self.client.get("/goods/16641")
-
- @task
- def Woman_UserC2(self):
- self.client.get("/goods/42823")
- self.interrupt()
-
- @task
- class SWoman_UserS(TaskSet):
- '商城静态页面接口请求'
- @tag('WB')
- @task(2)
- def SWoman_UserB1(self):
- with self.client.get("/shop/introduce/59/",catch_response=True) as Res:
- if "万表网" in Res.text:
- Res.success()
- else:
- Res.failure("No member message!")
- @tag('WB')
- @task(2)
- def SWoman_UserC2(self):
- with self.client.get("/shop/dynamic/59/",catch_response=True) as Res:
- if "万表网" in Res.text:
- Res.success()
- else:
- Res.failure("No member message!")
- self.interrupt()
-
- class M_Get(TaskSet):
- '会员资料接口请求'
- def on_start(self):
- Data_key = SSet_UP().START_009()
- self.My_y = Data_key[2]
-
- def on_stop(self):
- self.client.get('/member/loginOut',headers=self.My_y)
-
- @tag('WB')
- @task(5)
- def login(self): # 会员登录接口请求
- Url_headers = {'Content-Type': 'application/json', 'Connection': 'keep-alive',
- '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'}
- Pcontent = {"identity": '188000000' + str(random.randint(00,99)), "identityType": "1", "password": 111111, "platformSource": "Mall",
- "remember": "true", "terminalType": "PC"}
- Url_loring = 'http://member-service.xxxxtest.cn/member/login'
- with self.client.post(url=Url_loring,data=json.dumps(Pcontent),catch_response=True,headers=Url_headers) as Res:
- if "memberCode" in Res.text:
- Res.success()
- else:
- Res.failure("Wrong")
-
- @tag('SH')
- @task
- def member_get(self): # 获取个人资料
- with self.client.get('/member/center/get',catch_response=True, headers=self.My_y) as Res:
- if "5102252" in Res.text:
- Res.success()
- else:
- Res.failure("No member message!")
-
- @tag('SH')
- @task
- def member_message(self): # 获取会员基本信息
- with self.client.get('/member/center/getMember',
- catch_response=True,
- headers=self.My_y) as Res:
- if "5102252" in Res.text:
- Res.success()
- else:
- Res.failure("No member message!")
-
- class My_App(TaskSet): #api-APP请求
- def on_start(self):
- Data_key = SSet_UP().START_009()
- self.K_token = Data_key[0]
- self.HeaderToKen = Data_key[1]
- def on_stop(self):
- print("End-My_App")
-
- @tag('debug')
- @task
- def My_Cart(self):
- app_mParams = ""
- api_key = WB_ApiMD.api_get(app_mParams,'1','1')
- K_word = api_key + '&wb-token=' + self.K_token + Config.T_keyword
- with self.client.get('/api/cart/getList?' + api_key + WB_ApiMD.sign_R(K_word),
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if "cartGoodsList" in Res.text:
- Res.success()
- else:
- Res.failure("Faile")
- '''
- class My_talent_swagger(TaskSet): # Member swagger
- def on_start(self):
- Data_key = SSet_UP().START_009()
- self.K_token = Data_key[0]
- self.HeaderToKen = Data_key[3]
- def on_stop(self):
- self.interrupt()
- @task
- def talent_get(self): # 达人-获取图文信息
- with self.client.get('/member/talentImageText/get?talentImageTextId=122',
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if "talentImageTextId" in Res.text:
- Res.success()
- else:
- Res.failure("Wrong")
- @task
- def talent_list(self): # 达人-查询列表
- list_data = {
- "pager": {
- "now": 0,
- "size": 5,
- "total": 5
- },
- "search": [
- {
- "name": "string",
- "value": "string"
- }
- ],
- "sort": [
- {
- "asc": 'true',
- "name": "string"
- }
- ]
- }
- with self.client.post('/member/talentImageText/getList',
- data=json.dumps(list_data),
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if "talentImageTextId" in Res.text:
- Res.success()
- else:
- Res.failure("Wrong")
- class My_talent_rig(TaskSet): # Rig Console
- def on_start(self):
- Data_key = SSet_UP().START_009()
- self.K_token = Data_key[4]
- self.HeaderToKen = Data_key[3]
- self.php_mParams = Data_key[5]
- def on_stop(self):
- self.interrupt()
- @task
- def rig_t_get(self): # 达人类目详情
- with self.client.get('/back/member/talent/class/get?id=1'+ self.php_mParams +'&sign='+self.K_token,
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
- @task
- def rig_t_list(self): # 达人类目列表
- with self.client.get('/back/member/talent/class/list?' + self.php_mParams + '&sign=' + self.K_token,
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
- @task
- def rig_t_highCommissionGoods(self): # 高佣金比例的商品列表
- Pcontent = {"brandCodes":[70,176],"goodsCode":"","models":""}
- with self.client.post('/back/member/talent/highCommissionGoods/list?' + self.php_mParams + '&sign=' + self.K_token,
- data= json.dumps(Pcontent),
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
- '''
-
- # class My_cart(HttpUser):
- # host = "http://api-service.xxxxtest.cn"
- # tasks = {My_cart:1}
- # if __name__ == '__main__':
- # os.system("locust -f locustfile01.py --headless --users 1 --spawn-rate 1 --run-time 10")

后台-逻辑代码文件
- # locustfile_php.py
-
-
-
- import os,sys
- pathS = os.getcwd()
- Project_Path = os.path.dirname(os.path.dirname(os.path.dirname(pathS)))
- root_Path = os.path.dirname(pathS)
- sys.path.append(Project_Path)
- sys.path.append(root_Path)
-
- from locust import HttpUser, task , between , tag,User,constant,constant_pacing,TaskSet,constant_throughput,events
- from other.WB_Locust.common.api_token import *
- from other.WB_Locust.Config import Config
- import json,time,random,requests
-
- class SSet_UP():
- def START_009(self):
- # K_token = WB_ApiMD.MD5_token(self,1,1)
- # Api_HeaderToKen = HeaderToken.Header_token(self,3, K_token)
- # Member_HeaderToKen = HeaderToken.Header_token(self, 5, K_token)
- # PHP专用
- PHP_mParams = Config.php_mParams
- P_token = WB_ApiMD.MD5_token(self, 7, 5)
- Php_HeaderToKen = HeaderToken.Header_token(self, 2, P_token)
- # Rig_HeaderToKen = HeaderToken.Header_token(self, 2, K_token)
- # app_mParams = ""
- # api_key = WB_ApiMD.api_get(app_mParams, str(1), str(1))
- # K_word = api_key + '&wb-token=' + K_token + Config.T_keyword
- # Res = requests.get(url='http://api-service.xxxxtest.cn/api/cart/getList?' + api_key + WB_ApiMD.sign_R(K_word),
- # headers=HeaderToKen)
- # print(Res.text)
- # print(Res.url)
- # print(api_key)
- # print(K_word)
- # return K_token,Api_HeaderToKen,Member_HeaderToKen,Php_HeaderToKen,P_token,PHP_mParams
- return Php_HeaderToKen, P_token, PHP_mParams
-
- class My_talent_swagger(TaskSet): # Member swagger
- def on_start(self):
- print("My_talent_swagger")
- Data_key = SSet_UP().START_009()
- self.HeaderToKen = Data_key[0]
- def on_stop(self):
- self.interrupt()
- @task
- def talent_get(self): # 达人-获取图文信息
- with self.client.get('/member/talentImageText/get?talentImageTextId=122',
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if "talentImageTextId" in Res.text:
- Res.success()
- else:
- Res.failure("Wrong")
- @task
- def talent_list(self): # 达人-查询列表
- list_data = {
- "pager": {
- "now": 0,
- "size": 5,
- "total": 5
- },
- "search": [
- {
- "name": "string",
- "value": "string"
- }
- ],
- "sort": [
- {
- "asc": 'true',
- "name": "string"
- }
- ]
- }
- with self.client.post('/member/talentImageText/getList',
- data=json.dumps(list_data),
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if "talentImageTextId" in Res.text:
- Res.success()
- else:
- Res.failure("Wrong")
-
- class My_talent_rig(TaskSet): # Rig Console
- def on_start(self):
- print("My_talent_rig")
- Data_key = SSet_UP().START_009()
- self.K_token = Data_key[1]
- self.HeaderToKen = Data_key[0]
- self.php_mParams = Data_key[2]
- def on_stop(self):
- self.interrupt()
- @task
- def rig_t_get(self): # 达人类目详情
- with self.client.get('/back/member/talent/class/get?id=1'+ self.php_mParams +'&sign='+self.K_token,
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
-
- @task
- def rig_t_list(self): # 达人类目列表
- with self.client.get('/back/member/talent/class/list?' + self.php_mParams + '&sign=' + self.K_token,
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
-
- @task
- def rig_t_highCommissionGoods(self): # 高佣金比例的商品列表
- Pcontent = {"brandCodes":[70,176],"goodsCode":"","models":""}
- with self.client.post('/back/member/talent/highCommissionGoods/list?' + self.php_mParams + '&sign=' + self.K_token,
- data= json.dumps(Pcontent),
- headers=self.HeaderToKen,
- catch_response=True) as Res:
- if 'name' in Res.text:
- Res.success()
- else:
- Res.failure('Wrong')
-
-
-
- # class My_cart(HttpUser):
- # host = "http://api-service.xxxxtest.cn"
- # tasks = {My_cart:1}
- # if __name__ == '__main__':
- # 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】,对应打开链接即可
坑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
- 查看一下Centos下安装python3路径【/usr/local/python3】
- 查看一下安装python3源码包路径【/usr/local/python/Python-3.7.8rc1】
-
- [root@localhost python]# cd Python-3.7.8rc1
- [root@localhost Python-3.7.8rc1]# ./configure --prefix=/usr/local/python3
- [root@localhost Python-3.7.8rc1]# make && make install
-
- 重新编译后,添加环境匹配
- [root@localhost Python-3.7.8rc1]# vi /etc/profile
- export PATH=/usr/local/python3/bin:$PATH ---->path添加一下python执行目录,并保存
-
- [root@localhost Python-3.7.8rc1]# source /etc/profile
- [root@localhost Python-3.7.8rc1]# locust --version
- locust 2.14.2 from /usr/local/python3/lib/python3.7/site-packages/locust (python 3.7.8rc1)
-
-
-
- 下面就是启动后应有的样子
- [root@localhost my_locustfiles]# locust
- [2023-03-01 16:27:57,070] localhost.localdomain/WARNING/locust.main: System open file limit '1024' is below minimum setting '10000'.
- It's not high enough for load testing, and the OS didn't allow locust to increase it by itself.
- See https://github.com/locustio/locust/wiki/Installation#increasing-maximum-number-of-open-files-limit for more info.
- [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)
- [2023-03-01 16:27:57,080] localhost.localdomain/INFO/locust.main: Starting Locust 2.14.2
- [2023-03-01 16:30:04,736] localhost.localdomain/INFO/locust.runners: Ramping to 5 users at a rate of 1.00 per second
- [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)
- End-My_App
-
-
- 因为部署在Centos,外部访问还要对放开防火墙端口访问限制【8089】
- [root@localhost my_locustfiles]# firewall-cmd --zone=public --add-port=8087/tcp --permanent
- [root@localhost my_locustfiles]# systemctl reload firewalld

现在外部就可以访问了
User:自定义请求方式,一个User代表一个线程
设定:电脑总共12个内核,可同时处理24个线程,设置12个节点,开始执行并发测试:
所以,电脑12个节点全开的情况下,
(1)12节点全开,电脑CPU不过载,9000并发以下的时候使用httpuser
(2)12节点全开,电脑CPU过载了,9000并发以上了,考虑使用FastHttpUsers
(3)12节点全开,电脑CPU过载了,并发超过6万了,拓展节点机器继续分布式压测,比如电脑的CPU总共12核,可以开启12个节点,最大化利用CPU资源,增加电脑发给服务器的每秒的请求数。
注意:很容易因为理解不深刻,导致电脑每秒发给服务的请求数不够,比如在自己电脑20万并发,实际每秒只发送了9000个请求,服务器每秒接收到的并不是20万并发的请求数,通过分布式执行来确保20万确实是并发上去了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。