我正在尝试使用Python 3在服务器上进行压力测试。我们的想法是每隔1秒向API服务器发送一次HTTP请求,持续30分钟。我尝试使用requests
和apscheduler
来执行此操作,但我一直在
执行作业" send_request(触发:间隔[0:00:01],下次运行于:美国东部时间23:05:05:46)" 已跳过:达到最大运行实例数(1)
我该如何使这项工作?以下是我目前的代码:
import requests, json, time, ipdb
from apscheduler.schedulers.blocking import BlockingScheduler as scheduler
def send_request():
url = 'http://api/url/'
# Username and password
credentials = { 'username': 'username', 'password': 'password'}
# Header
headers = { 'Content-Type': 'application/json', 'Client-Id': 'some string'}
# Defining payloads
payload = dict()
payload['item1'] = 1234
payload['item2'] = 'some string'
data_array = [{"id": "id1", "data": "some value"}]
payload['json_data_array'] = [{ "time": int(time.time()), "data": data_array]
# Posting data
try:
request = requests.post(url, headers = headers, data = json.dumps(payload))
except (requests.Timeout, requests.ConnectionError, requests.HTTPError) as err:
print("Error while trying to POST pid data")
print(err)
finally:
request.close()
print(request.content)
return request.content
if __name__ == '__main__':
sched = scheduler()
print(time.time())
sched.add_job(send_request, 'interval', seconds=1)
sched.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
# This is here to simulate application activity (which keeps the main thread alive).
while true:
pass
except (KeyboardInterrupt, SystemExit):
# Not strictly necessary if daemonic mode is enabled but should be done if possible
scheduler.shutdown()
我尝试搜索堆栈溢出但是其他问题都没有达到我想要的目标,或者我可能错过了一些东西。如果是这样的话,我希望有人能指出我正确的主题。非常感谢你!
答案 0 :(得分:0)
我以前从未在python中使用过调度程序,但是other stackOverflow question似乎处理了这个问题。
这意味着该任务花费的时间超过一秒,默认情况下,对于给定的工作,只允许一次并发执行......-AlexGrönholm
在您的情况下,我想使用线程可以满足您的需求。 如果你创建了一个在python中继承线程的类,比如:
class Requester(threading.Thread):
def __init__(self, url, credentials, payload):
threading.Thread._init__(self)
self.url = url
self.credentials = credentials
self.payload = payload
def run(self):
# do the post request here
# you may want to write output (errors and content) to a file
# rather then just printing it out sometimes when using threads
# it gets really messing if you just print everything out
然后就像你稍微改变一样处理。
if __name__ == '__main__':
url = 'http://api/url/'
# Username and password
credentials = { 'username': 'username', 'password': 'password'}
# Defining payloads
payload = dict()
payload['item1'] = 1234
payload['item2'] = 'some string'
data_array = [{"id": "id1", "data": "some value"}]
payload['json_data_array'] = [{ "time": int(time.time()), "data": data_array]
counter = 0
while counter < 1800:
req = Requester(url, credentials, payload)
req.start()
counter++
time.sleep(1)
当然,如果您愿意,可以完成其余部分,以便您可以使KeyboardInterrupt实际完成脚本。
这当然是绕过调度程序的一种方法,如果这就是问题所在。
答案 1 :(得分:0)
我认为我的错误是由我标记的副本以及@jeff
的答案所描述的编辑:显然不是..所以我在这里描述如何解决最大实例问题:
当您向调度程序添加作业时,您可以为作业的最大允许并发实例数设置一个参数。你可以 在这里阅读: BaseScheduler.add_job()
因此,解决问题只是将其设置为更高的问题:
sch.add_job(myfn, 'interval', seconds=1, max_instances=10)
但是,您想要多少个并发请求?如果他们需要超过一秒钟的时间来回复,并且您每秒请求一次,那么如果您让它运行得足够长,那么最终会最终错误...
有几个可用的调度程序选项,这里有两个:
您正在导入阻止调度程序 - 阻止调度程序在启动时会阻塞。因此,在调度程序停止之后,其余代码才会执行。如果在启动调度程序后需要执行其他代码,我会使用这样的后台调度程序:
from apscheduler.schedulers.background import BackgroundScheduler as scheduler
def myfn():
# Insert your requests code here
print('Hello')
sch = scheduler()
sch.add_job(myfn, 'interval', seconds=5)
sch.start()
# This code will be executed after the sceduler has started
try:
print('Scheduler started, ctrl-c to exit!')
while 1:
# Notice here that if you use "pass" you create an unthrottled loop
# try uncommenting "pass" vs "input()" and watching your cpu usage.
# Another alternative would be to use a short sleep: time.sleep(.1)
#pass
#input()
except KeyboardInterrupt:
if sch.state:
sch.shutdown()
如果您在启动调度程序后不需要执行其他代码,则可以使用阻止调度程序,它更容易:
apscheduler.schedulers.blocking import BlockingScheduler as scheduler
def myfn():
# Insert your requests code here
print('Hello')
# Execute your code before starting the scheduler
print('Starting scheduler, ctrl-c to exit!')
sch = scheduler()
sch.add_job(myfn, 'interval', seconds=5)
sch.start()