在 flask 应用程序子 class 中调用 requests.get() 导致 uwsgi 分段错误和 nginx 上的 502
Invoking requests.get() within flask application sub-class is causing uwsgi segmentation fault and 502 on nginx
我当前的 Flask 应用程序设置存在问题,非常感谢对此提供一些意见。谢谢!
流量
user --> nginx --> uwsgi --> flask app --> https调用外部系统(处理响应并将相关数据返回给客户端)
工作流程
Intent 我的 flask view/route 调用另一个 class,其中一个 https (GET) 调用是对外部系统进行检索数据。然后处理(分析)此数据并将适当的响应发送给用户。
实际 用户在调用基于 Flask 的端点时从网络服务器收到 502 Bad Gateway。这只有在将 nginx 和 uwsgi 服务器放在我的烧瓶应用程序前面时才会发生。直接使用 Flask 的内置服务器在服务器上进行的初步测试似乎有效。
注意:那个分析位确实占用了一些时间所以我增加了所有相关的超时(无济于事)
配置
Nginx(尝试使用和不使用 TLS)
worker_processes 4;
error_log /path/to/error.log;
pid /path/to/nginx.pid;
events {
worker_connections 1024;
}
http {
default_type application/json;
access_log /path/to/access.log;
sendfile on;
keepalive_timeout 0; [multiple values tried]
# HTTPS server
server {
listen 5555 ssl;
server_name my_host.domain.com;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /my_route {
uwsgi_connect_timeout 60s;
uwsgi_read_timeout 300s;
client_body_timeout 300s;
include uwsgi_params;
uwsgi_pass unix:/path/to/my/app.sock;
}
}
}
uWSGI(作为故障排除尝试的一部分,线程减少到 1)
[uwsgi]
module = wsgi:app
harakiri = 300 [also added as part of troubleshooting steps]
logto = /path/to/logs/uwsgi_%n.log
master = true
processes = 1
threads = 1
socket = app.sock
chmod-socket = 766
vacuum = true
socket-timeout = 60
die-on-term = true
代码片段
主烧瓶Class(查看)
@app.route(my_route, methods=['POST'])
def my_view():
request_json = request.json
app.logger.debug(f"Request Received: {request_json}")
schema = MySchema()
try:
schema.load(request_json)
var1 = request_json["var1"]
var2 = request_json["var2"]
var3 = request_json["var3"]
var4 = request_json["var4"]
# begin
execute = AnotherClass(client_home, config, var1, var2, var3, var4, mime_type)
return jsonify(execute.result)
except ValidationError as exception:
error_message = json.dumps(exception.messages)
abort(Response(error_message, 400, mimetype=mime_type))
Class 在外部系统上执行 HTTPS GET
custom_adapter = HTTPAdapter(max_retries=3)
session = requests.Session()
session.proxies = self.proxies
session.mount("https://", custom_adapter)
try:
json_data = json.loads(session.get(process_endpoint, headers=self.headers, timeout=(3, 6)).text)
错误
Nginx
error] 22680#0: *1 upstream prematurely closed connection while
reading response header from upstream, client: client_ip, server:
server_name, request: "POST /my_route HTTP/1.1", upstream:
"uwsgi://unix:/path/to/my/app.sock:", host: "server_name:5555"
用户收到 502(错误网关)
uWSGI
2020-04-24 16:57:23,873 - app.module.module_class - DEBUG - Endpoint:
https://external_system.com/endpoint_details 2020-04-24 16:57:23,876 -
urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1):
external_system.com:443 !!! uWSGI process #### got Segmentation Fault
!!!
* backtrace of #### /path/to/anaconda3/bin/uwsgi(uwsgi_backtrace+0x2e) [0x610e8e]
/path/to/anaconda3/bin/uwsgi(uwsgi_segfault+0x21) [0x611221]
/usr/lib64/libc.so.6(+0x363f0) [0x7f6c22b813f0]
/path/to/anaconda3/lib/python3.7/lib-dynload/../../libssl.so.1.0.0(ssl3_ctx_ctrl+0x170)
[0x7f6c191b77b0]
/path/to/anaconda3/lib/python3.7/site-packages/cryptography/hazmat/bindings/_openssl.abi3.so(+0x5a496)
[0x7f6c16de2496]
....
end of backtrace * DAMN ! worker 1 (pid: ####) died :( trying respawn ... Respawned uWSGI worker 1 (new pid: ####)
已解决
步数
更新密码
更新请求
更新 urllib3
将缺少的 TLS 密码添加到 Py HTTP 适配器(遵循此 guide)
我当前的 Flask 应用程序设置存在问题,非常感谢对此提供一些意见。谢谢!
流量
user --> nginx --> uwsgi --> flask app --> https调用外部系统(处理响应并将相关数据返回给客户端)
工作流程
Intent 我的 flask view/route 调用另一个 class,其中一个 https (GET) 调用是对外部系统进行检索数据。然后处理(分析)此数据并将适当的响应发送给用户。
实际 用户在调用基于 Flask 的端点时从网络服务器收到 502 Bad Gateway。这只有在将 nginx 和 uwsgi 服务器放在我的烧瓶应用程序前面时才会发生。直接使用 Flask 的内置服务器在服务器上进行的初步测试似乎有效。
注意:那个分析位确实占用了一些时间所以我增加了所有相关的超时(无济于事)
配置
Nginx(尝试使用和不使用 TLS)
worker_processes 4;
error_log /path/to/error.log;
pid /path/to/nginx.pid;
events {
worker_connections 1024;
}
http {
default_type application/json;
access_log /path/to/access.log;
sendfile on;
keepalive_timeout 0; [multiple values tried]
# HTTPS server
server {
listen 5555 ssl;
server_name my_host.domain.com;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /my_route {
uwsgi_connect_timeout 60s;
uwsgi_read_timeout 300s;
client_body_timeout 300s;
include uwsgi_params;
uwsgi_pass unix:/path/to/my/app.sock;
}
}
}
uWSGI(作为故障排除尝试的一部分,线程减少到 1)
[uwsgi]
module = wsgi:app
harakiri = 300 [also added as part of troubleshooting steps]
logto = /path/to/logs/uwsgi_%n.log
master = true
processes = 1
threads = 1
socket = app.sock
chmod-socket = 766
vacuum = true
socket-timeout = 60
die-on-term = true
代码片段
主烧瓶Class(查看)
@app.route(my_route, methods=['POST'])
def my_view():
request_json = request.json
app.logger.debug(f"Request Received: {request_json}")
schema = MySchema()
try:
schema.load(request_json)
var1 = request_json["var1"]
var2 = request_json["var2"]
var3 = request_json["var3"]
var4 = request_json["var4"]
# begin
execute = AnotherClass(client_home, config, var1, var2, var3, var4, mime_type)
return jsonify(execute.result)
except ValidationError as exception:
error_message = json.dumps(exception.messages)
abort(Response(error_message, 400, mimetype=mime_type))
Class 在外部系统上执行 HTTPS GET
custom_adapter = HTTPAdapter(max_retries=3)
session = requests.Session()
session.proxies = self.proxies
session.mount("https://", custom_adapter)
try:
json_data = json.loads(session.get(process_endpoint, headers=self.headers, timeout=(3, 6)).text)
错误
Nginx
error] 22680#0: *1 upstream prematurely closed connection while reading response header from upstream, client: client_ip, server: server_name, request: "POST /my_route HTTP/1.1", upstream: "uwsgi://unix:/path/to/my/app.sock:", host: "server_name:5555"
用户收到 502(错误网关)
uWSGI
2020-04-24 16:57:23,873 - app.module.module_class - DEBUG - Endpoint: https://external_system.com/endpoint_details 2020-04-24 16:57:23,876 - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): external_system.com:443 !!! uWSGI process #### got Segmentation Fault !!! * backtrace of #### /path/to/anaconda3/bin/uwsgi(uwsgi_backtrace+0x2e) [0x610e8e] /path/to/anaconda3/bin/uwsgi(uwsgi_segfault+0x21) [0x611221] /usr/lib64/libc.so.6(+0x363f0) [0x7f6c22b813f0] /path/to/anaconda3/lib/python3.7/lib-dynload/../../libssl.so.1.0.0(ssl3_ctx_ctrl+0x170) [0x7f6c191b77b0] /path/to/anaconda3/lib/python3.7/site-packages/cryptography/hazmat/bindings/_openssl.abi3.so(+0x5a496) [0x7f6c16de2496] .... end of backtrace * DAMN ! worker 1 (pid: ####) died :( trying respawn ... Respawned uWSGI worker 1 (new pid: ####)
已解决
步数
更新密码
更新请求
更新 urllib3
将缺少的 TLS 密码添加到 Py HTTP 适配器(遵循此 guide)