AWS SageMaker端点无响应:HTTP 301 293错误求助
解决SageMaker自定义容器HTTP 301重定向问题
这种301重定向的坑我在SageMaker部署自定义Nginx+Gunicorn+Flask容器时踩过好几次,结合你描述的现象(能ping通但推理请求返回重定向页面、HTTP 301错误),大概率是路由配置或SageMaker端点规范不匹配的问题,咱们一步步来排查解决:
1. 检查Flask路由的斜杠一致性
Flask默认对路由的末尾斜杠很敏感:如果你的API路由定义是@app.route('/predict')(不带斜杠),但请求路径是/predict/(带斜杠),Flask会自动返回301重定向到不带斜杠的版本;反过来也一样。
解决办法二选一:
- 统一你的路由定义和请求路径的格式(要么都带斜杠,要么都不带)
- 在路由上添加
strict_slashes=False参数,忽略斜杠差异:@app.route('/predict', strict_slashes=False) def predict(): # 你的推理逻辑 return jsonify({"result": "output"})
2. 修正Nginx反向代理配置
Nginx的默认配置可能会触发不必要的重定向,尤其是和SageMaker的请求转发逻辑结合时。重点检查这几点:
- 确保监听端口是
8080(SageMaker要求容器服务监听这个端口) - 去掉强制HTTPS或其他无关的重定向规则(比如
return 301 https://$host$request_uri;) - 添加
proxy_redirect off;阻止Nginx修改后端返回的重定向响应 - 正确转发SageMaker要求的
/ping和/invocations端点
示例Nginx配置(/etc/nginx/nginx.conf或对应站点配置文件):
server { listen 8080; server_name localhost; # 处理SageMaker健康检查的/ping端点 location /ping { proxy_pass http://127.0.0.1:8000/ping; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 处理SageMaker推理请求的/invocations端点 location /invocations { proxy_pass http://127.0.0.1:8000/predict; # 如果你的推理路由是/predict,这里转发过去 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; # 关键:禁止Nginx修改重定向 } }
3. 对齐SageMaker自定义容器的端点规范
SageMaker托管自定义容器有硬性要求:必须实现两个核心端点:
/ping:GET请求,返回200 OK用于健康检查(你已经能ping通,说明这个没问题)/invocations:POST请求,处理推理请求(输入输出为application/json)
如果你的Flask应用把推理路由设成了/predict而不是/invocations,SageMaker的推理请求会默认打到/invocations,此时如果该路由不存在,服务可能返回404或触发重定向。
解决办法二选一:
- 直接把Flask的推理路由改成
/invocations:@app.route('/invocations', methods=['POST']) def invocations(): data = request.get_json() # 推理逻辑 return jsonify({"output": "result"}) - 或者在Nginx里把
/invocations请求转发到你的自定义路由(比如上面Nginx配置示例中的做法)
4. 本地验证容器服务
在部署到SageMaker前,本地启动容器测试请求,确认问题是否来自容器内部:
# 启动容器 docker run -p 8080:8080 your-custom-image:latest # 测试健康检查 curl -v http://localhost:8080/ping # 测试推理请求 curl -v -H "Content-Type: application/json" -d '{"input": "test"}' http://localhost:8080/invocations
如果本地测试也出现301,那问题肯定在容器内部的配置;如果本地正常,再检查SageMaker端点的调用参数是否正确(比如请求头、路径是否符合要求)
内容的提问来源于stack exchange,提问作者Nandan Pc
相关产品推荐
相关产品推荐

