Django应用Aruba服务器调用外部API超时,本地正常求排查
Django应用在Aruba服务器调用外部API超时问题排查与解决建议
我有一个基于Django 4.2.2、Python 3.11运行的应用,其中获取验证码的视图代码如下:
import requests from django.http import HttpResponse def get_captcha(request): response = requests.get( "https://geoportale.cartografia.agenziaentrate.gov.it/age-inspire/srv/ita/Captcha?type=image&lang=it" ) session_id = response.cookies.get("JSESSIONID") request.session["CAPTCHA"] = session_id content_type = response.headers["content-type"] return HttpResponse(response.content, content_type=content_type)
本地运行时该API调用可成功执行,但部署在Aruba服务器上时出现超时。我已尝试以下排查步骤但未解决问题:
- 将OpenSSL降级至与本地相同的版本(1.1.1n)
- 禁用防火墙
- 更换DNS服务器用于域名解析
- 降级Python版本
服务器网络诊断信息
traceroute结果
traceroute to geoportale.cartografia.agenziaentrate.gov.it (217.175.52.194), 30 hops max, 60 byte packets 1 host2-224-110-95.serverdedicati.aruba.it (95.110.224.2) 0.702 ms 0.744 ms 0.824 ms 2 cr2-te0-0-0-2.it2.aruba.it (62.149.185.196) 0.865 ms 0.919 ms * 3 * * * 4 * * * 5 * * * 6 * 93-57-68-2.ip163.fastwebnet.it (93.57.68.2) 10.095 ms 10.516 ms 7 81-208-111-134.ip.fastwebnet.it (81.208.111.134) 10.482 ms 10.370 ms 10.536 ms 8 * * * 9 * * * 10 * * * 11 * * * 12 * * * 13 * * * 14 * * * 15 * * * 16 * * * 17 * * * 18 * * * 19 * * * 20 * * * 21 * * * 22 * * * 23 * * * 24 * * * 25 * * * 26 * * * 27 * * * 28 * * * 29 * * * 30 * * *
nslookup输出
Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: Name: geoportale.cartografia.agenziaentrate.gov.it Address: 217.175.52.194
请求详情对比
服务器端调用失败的请求详情
Request URL: https://beta.service.com/captcha/ Request Method: GET Status Code: 500 Internal Server Error Remote Address: 95.110.228.4:443 Referrer Policy: same-origin Connection: keep-alive Content-Length: 152853 Content-Type: text/html; charset=utf-8 Cross-Origin-Opener-Policy: same-origin Date: Tue, 02 Jul 2024 08:39:55 GMT Referrer-Policy: same-origin Server: nginx Strict-Transport-Security: max-age=31536000; includeSubDomains Vary: Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY Accept: */* Accept-Encoding: gzip, deflate, br, zstd Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7 Cache-Control: no-cache Connection: keep-alive Cookie: _fbp=fb.1.1712064669028.980891575; _ga=GA1.3.585575725.1712064668; _gid=GA1.2.894542501.1719830766; csrftoken=us75UYbPCtVM8DTA0ZhQPzC9ON5Jc3qZ; sessionid=z287mdm63vq9j1p0uxwvf69ieykput00; _gid=GA1.3.894542501.1719830766; _ga=GA1.1.585575725.1712064668; _ga_314551799=GS1.1.1719909450.504.1.1719909452.0.0.0; _ga_52G663NH12=GS1.1.1719909450.176.1.1719909452.58.0.0; _gat_UA-67329675-1=1; _gcl_au=1.1.471068170.1719846195.1018237849.1719909461.1719909460 Host: beta.service.com Pragma: no-cache Referer: https://beta.service.com/ Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Linux" Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
本地环境调用成功的请求详情
Request URL: http://localhost:8000/captcha/ Request Method: GET Status Code: 200 OK Remote Address: 127.0.0.1:8000 Referrer Policy: same-origin Content-Length: 19823 Content-Type: image/jpeg Cross-Origin-Opener-Policy: same-origin Date: Tue, 02 Jul 2024 10:15:21 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.11.9 Set-Cookie: sessionid=q57cn8cmh1961ghhhu6ywerflojq1f4l; expires=Tue, 16 Jul 2024 10:15:21 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax Vary: Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY Accept: */* Accept-Encoding: gzip, deflate, br, zstd Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7 Cache-Control: no-cache Connection: keep-alive Cookie: _ga=GA1.1.1117820162.1715856098; _gcl_au=1.1.2110919363.1715856098; _fbp=fb.0.1715856098133.219741871; USENAV=1717774507848.1409993568842083; csrftoken=lLd1jqD3VhFqW2NdQI5RAAQEntxfs476; sessionid=q57cn8cmh1961ghhhu6ywerflojq1f4l; _gid=GA1.1.1504428548.1719909313; _ga_52G663NH12=GS1.1.1719909292.46.1.1719909562.60.0.0; _ga_314551799=GS1.1.1719909292.220.1.1719909562.0.0.0 Host: localhost:8000 Pragma: no-cache Referer: http://localhost:8000/ Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Linux" Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
补充信息:另外两台Aruba服务器上该调用可成功执行,Aruba支持团队称其网络未阻塞该调用。
补充错误及变量信息
错误信息
Request Method: GET Request URL: https://beta.service.com/captcha/ Django Version: 4.2.2 Exception Type: ConnectTimeout Exception Value: HTTPSConnectionPool(host='geoportale.cartografia.agenziaentrate.gov.it', port=443): Max retries exceeded with url: /age-inspire/srv/ita/Captcha?type=image&lang=it (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7f55bb0a6150>, 'Connection to geoportale.cartografia.agenziaentrate.gov.it timed out. (connect timeout=None)'))
本地变量
cert: None chunked: False conn: <urllib3.connectionpool.HTTPSConnectionPool object at 0x7f5579092fd0> proxies: OrderedDict() request: <PreparedRequest [GET]> self: <requests.adapters.HTTPAdapter object at 0x7f55821c33d0> stream: False timeout: Timeout(connect=None, read=None, total=None) url: '/age-inspire/srv/ita/Captcha?type=image&lang=it' verify: True
原因分析及解决建议
可能原因
- 目标服务器IP白名单限制:目标API服务器可能仅允许特定IP段访问,出现问题的Aruba服务器IP不在白名单内,而另外两台成功的服务器IP符合要求。
- 网络路由差异:同一服务商不同服务器的路由路径可能存在差异,traceroute结果显示第7跳后无法继续追踪,说明数据包在后续路由中丢失或被拦截。
- 请求超时配置缺失:当前requests调用未设置超时时间,默认无限制等待,容易触发服务器端超时机制,也无法及时捕获连接问题。
- SSL/TLS握手不兼容:即使OpenSSL版本一致,服务器端的SSL配置(如加密套件支持)可能与目标服务器不匹配,导致握手过程超时。
解决建议
- 添加请求超时配置:修改requests.get调用,明确设置连接和读取超时,避免无限制等待:
response = requests.get( "https://geoportale.cartografia.agenziaentrate.gov.it/age-inspire/srv/ita/Captcha?type=image&lang=it", timeout=(5, 10) # 连接超时5秒,读取超时10秒,可根据实际调整 )
- 测试端口连通性:在问题服务器上执行
telnet 217.175.52.194 443或nc -zv 217.175.52.194 443,确认是否能建立TCP连接。 - 联系目标API服务商:询问是否存在IP白名单限制,将当前服务器IP提交申请加入白名单。
- 检查SSL握手细节:执行
openssl s_client -connect geoportale.cartografia.agenziaentrate.gov.it:443命令,查看SSL握手过程是否有错误,对比成功服务器的输出差异。 - 尝试使用代理:若路由问题无法解决,可尝试使用Aruba服务器内部代理服务进行API调用,绕过当前路由瓶颈。
- 捕获并处理异常:在视图中添加异常捕获,避免直接返回500错误:
import requests from django.http import HttpResponse, HttpResponseServerError def get_captcha(request): try: response = requests.get( "https://geoportale.cartografia.agenziaentrate.gov.it/age-inspire/srv/ita/Captcha?type=image&lang=it", timeout=(5, 10) ) response.raise_for_status() # 捕获HTTP错误状态码 session_id = response.cookies.get("JSESSIONID") request.session["CAPTCHA"] = session_id content_type = response.headers["content-type"] return HttpResponse(response.content, content_type=content_type) except requests.exceptions.RequestException as e: return HttpResponseServerError("验证码获取失败,请稍后重试")
内容的提问来源于stack exchange,提问作者m.piras
相关产品推荐
相关产品推荐

