【发布时间】:2022-11-20 08:38:05
【问题描述】:
import requests
import threading
import time
def req():
s = time.time()
r = requests.get('https://www.google.com/')
e = time.time()
response_times.append(e - s)
response_times = []
thread_amount = 50
print(f"{thread_amount} parallel threads")
threads = []
s1 = time.time()
for i in range(thread_amount):
threads.append(threading.Thread(target = req))
s2 = time.time()
for thread in threads:
thread.start()
s3 = time.time()
for thread in threads:
thread.join()
s4 = time.time()
total_time = s4 - s1
spawn_time = s2 -s1
start_time = s3 -s2
finish_time = s4 -s3
average_time_per_thread = sum(response_times) / len(response_times)
print(f"average response time per request: {average_time_per_thread} s")
print(f"total time: {total_time} s")
print(f"spawn time: {spawn_time} s")
print(f"start time: {start_time} s")
print(f"finish time: {finish_time} s")
对于 50 个并行线程/请求,每个请求的平均响应时间为 5.5 秒。我已经知道问题与 SSL 证书有关,对于 100 多个并行请求,我得到一个错误:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
resp = conn.urlopen(
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 755, in urlopen
retries = retries.increment(
File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 574, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLZeroReturnError(6, 'TLS/SSL connection has been closed (EOF) (_ssl.c:997)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
self.run()
File "/usr/lib/python3.10/threading.py", line 946, in run
self._target(*self._args, **self._kwargs)
File "/root/speedtest.py", line 7, in req
r = requests.get('https://www.google.com/')
File "/usr/lib/python3/dist-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLZeroReturnError(6, 'TLS/SSL connection has been closed (EOF) (_ssl.c:997)')))
在我的 ubuntu 22.04 服务器上执行以下操作后立即出现此问题:
sudo snap install core; sudo snap refresh core-
sudo snap install --classic certbot-
sudo ln -s /snap/bin/certbot /usr/bin/certbot-
sudo apt-get install nginx-
sudo certbot --nginx(在这一步我必须为我的域创建一个证书)-
sudo certbot renew --dry-run
在此之前,每个请求的平均响应时间为 0.45 秒。
看来我崩溃了 python 请求的 SSL 证书,但我不知道导致此问题的文件。
如果我将请求更改为requests.get('https://www.google.com/', verify=False),平均响应时间将再次变为 0.45 秒,但我认为这不是一个好的解决方案。
【问题讨论】:
-
您是否尝试过
verify=False请求确认是这种情况? -
是的,我现在也将此添加到初始帖子中,
verify = False,平均响应时间将再次变为 0.45 秒。 -
尝试直接导出 REQUESTS_CA_BUNDLE 环境变量。示例:
export REQUESTS_CA_BUNDLE='path/to/cert/file' -
如何获取证书文件的路径?
-
尝试使用较低级别的工具:
openssl s_client -connect www.google.com:443,如果它很慢,请检查输出或将其与它工作的其他机器进行比较。我确实建议分别尝试 IPv4 和 IPv6(选项-4和-6)。如果 IPv6 网络配置不正确(en.wikipedia.org/wiki/Happy_Eyeballs 的结果),有时像您这样的延迟有时是由于先尝试 IPv6 并回退到 IPv4 造成的
标签: python ubuntu ssl python-requests ubuntu-22.04