有一个APIlocalhost:8000/api/postdatetime/
,负责更改驱动程序的联机状态。每次驱动程序访问API时,如果返回响应,则驱动程序状态将为联机,否则驱动程序状态为脱机。
Drivers need to give the response within every 10 seconds.
如果驾驶员没有响应,则他/她将自动标记为离线。
目前我正在做的是获取所有已登录的驱动程序,并一次一个驱动程序地调用上述API。
为了进行模拟,我填充了数千个驱动程序。使用我的方法保持数千名司机的在线离线将使几乎许多司机离线。
我的方法代码如下所述:
online-offline.py
import requests
import random
import math
from rest_framework.authtoken.models import Token
from ** import get_logged_in_driver_ids
from ** import Driver
def post_date_time():
url = 'localhost:8000/api/postdatetime/'
while True:
# getting all logged in driver ids
logged_in_driver_ids = get_logged_in_driver_ids()
# filtering the driver who are logged in and storing their user id in the driver_query variable
driver_query = Driver.objects.only('id', 'user_id').filter(id__in=logged_in_driver_ids).values('user_id')
# storing the user id of driver in list
driver_user_ids = [driver['user_id'] for driver in driver_query]
# getting number of drivers who are supposed to hit the API
drivers_subset_count = math.ceil(len(driver_user_ids)*(random.randint(75, 85)/100))
# shuffle the driver ids list to randomize the driver id order
random.shuffle(driver_user_ids)
# getting the driver list of length drivers_subset_count
required_drivers = driver_user_ids[:drivers_subset_count]
for driver in required_drivers:
token = Token.objects.only('key', 'user_id').get(user_id=driver)
req_headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token' + ' ' + str(token)
}
response = requests.post(url=url, headers=req_headers)
print(response.text)
if __name == '__main__':
post_date_time()
有没有什么想法可以异步发布请求localhost:8000/api/postdatetime/
API,并且可以在10秒内处理大约2-3000个驱动程序?
我对实现异步代码真的很陌生。我读过一些关于aiohttp
库的文章,但在实现它时感到困惑
该online-offline.py
将在整个模拟过程中运行。
如有任何帮助,我们将不胜感激。谢谢:(
在非本地API的情况下,asyncio
可以帮助您。要异步发出请求,您必须:
- 使用特殊语法(
async def
、await
-请阅读此处了解详细信息( - 以非阻塞方式发出请求(这样您就可以等待它们(
- 使用类似方式的asyncio.gather((使多个请求并行">
- 启动事件循环
虽然可以使用线程使requests
库与asyncio
协同工作,但使用像aiohttp
这样已经异步兼容的库会更容易、更好。
看看这里的代码片段*
:它们包含了发出多个并发请求的示例。用同样的方式重写代码,它看起来像:
import asyncio
async def driver_request(driver):
# ...
# use aiohttp to make request with custom headers:
# https://docs.aiohttp.org/en/stable/client_advanced.html#custom-request-headers
async def post_date_time():
# ...
await asyncio.gather(*[
driver_request(driver)
for driver
in required_drivers
])
asyncio.run(post_date_time())
在本地,默认情况下你不会看到任何效果,所以要在本地测试它,你必须让localhost
发送延迟响应,以模拟真实的网络延迟。
*
在最新的Python版本中,事件循环只需使用asyncio.run((即可运行