Python 3.x 在Python3中每x秒发出一次API请求
我正在尝试使用Python3在服务器上进行压力测试。其思想是每1秒向API服务器发送一个HTTP请求,持续30分钟。我尝试使用Python 3.x 在Python3中每x秒发出一次API请求,python-3.x,Python 3.x,我正在尝试使用Python3在服务器上进行压力测试。其思想是每1秒向API服务器发送一个HTTP请求,持续30分钟。我尝试使用请求和apscheduler来执行此操作,但我不断收到 执行作业“发送请求(触发器:间隔[0:00:01],下次运行时间:2017-05-23 11:05:46 EDT)” 跳过:已达到最大运行实例数(1) 我怎样才能做到这一点?以下是我目前的代码: import requests, json, time, ipdb from apscheduler.schedulers
请求
和apscheduler
来执行此操作,但我不断收到
执行作业“发送请求(触发器:间隔[0:00:01],下次运行时间:2017-05-23 11:05:46 EDT)”
跳过:已达到最大运行实例数(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()
我试着在堆栈溢出上搜索,但到目前为止,没有一个问题符合我的要求,或者我遗漏了什么。如果是这样的话,我希望有人能给我指出正确的线索。多谢各位 我以前从未在python中使用过调度程序,不过这似乎可以解决这个问题 这意味着任务花费的时间超过1秒,默认情况下,给定作业只允许一次并发执行-亚历克斯·格伦霍姆 在您的情况下,我认为使用线程可以满足您的需要。 如果您创建了一个继承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)
如果uuuu name_uuuu=='\uuuuuuu main\uuuuuu':
url='1〕http://api/url/'
#用户名和密码
凭据={'username':'username','password':'password'}
#定义有效载荷
有效载荷=dict()
有效载荷['item1']=1234
有效负载['item2']='some string'
data_数组=[{“id”:“id1”,“data”:“some value”}]
有效负载['json_data_array']=[{“time”:int(time.time()),“data”:data_array]
计数器=0
当计数器小于1800时:
req=请求者(url、凭证、有效负载)
请求启动()
柜台++
时间。睡眠(1)
当然,不管你怎么想,你都可以完成剩下的部分,如果你想的话,你可以这样做,键盘中断就是真正完成脚本的部分
这当然是绕过调度程序的一种方法,如果这就是问题所在。我认为我标记的副本以及@jeff的答案很好地描述了您的错误 编辑:显然不是..所以这里我将描述如何修复最大实例问题: 最大实例问题 将作业添加到计划程序时,可以为作业允许的最大并发实例数设置一个参数。您可以应该阅读以下内容: 因此,解决您的问题只是将其设置为更高的值:
sch.add_job(myfn, 'interval', seconds=1, max_instances=10)
但是,您需要多少并发请求?如果它们需要一秒钟以上的时间响应,而您每秒请求一个请求,那么如果您让它运行足够长的时间,您最终总会得到一个错误
调度者
有几个可用的计划程序选项,以下是两个:
背景调度器
您正在导入blocking scheduler(阻塞计划程序)-它在启动时会阻塞。因此,在计划程序停止后,才会执行其余代码。如果启动计划程序后需要执行其他代码,我将使用如下后台计划程序:
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()
@calico_uu的可能副本谢谢,我们很快就会查看它。@calico_u是的,问题是请求需要超过1秒。但是由于这是一个压力测试,如果请求已经存在,我不能跳过请求。我希望代码能够做的是,即使之前的请求没有完成/正在进行,也能发出API请求返回了。是的,很抱歉其他答案不完整。我编辑了我的答案以包含一个解决方案。嗯,这样请求者就不会等到下一个请求者启动了吗?这是一个有趣的想法,我将尝试一下,看看它是如何工作的。谢谢!不过,如果我们定义
def run(self)
,而不是req.start()
,我们不应该改为使用req.run()
吗?我还更新了标题部分,错误地将其与一些不相关的代码一起取出。因此,当使用线程时,通常不调用run方法,run从start方法调用。附带说明。我来自java背景,但我确实看到了这一点[使用Jerubs answer,这可能是一种更为python的解决方案。因此,如果您不想创建thread的子类,您可以改为执行以下操作:def makeRequest(url、标头、负载):#请求的实际处理(抱歉,我似乎不知道如何将代码放入代码块中)apscheduler
包以一种干净的面向对象的方式实现了这一目标,但确实需要理解一些中间Python原则。有关详细信息,请参阅下面的答案。我尝试了两种解决方案,但问题仍然存在。我认为其背后的原因是请求本身执行所需的时间超过1秒(我试着每5秒运行一次,这样效果很好)