如何在Apache+Gunicorn+Flask环境部署Spyne SOAP服务?
问题分析与解决方案
核心错误点
- 多余的内置WSGI服务器启动代码:
make_server会启动独立WSGI服务器占用8000端口,而Gunicorn本身就是WSGI服务器,两者冲突导致端口占用错误,必须删除这两行代码。 - SOAP服务未与Flask应用整合:删除内置服务器后,Spyne的SOAP服务没有挂载到Flask路由上,所有请求都被Flask的REST服务处理,因此访问根路径会跳转到项目首页,无法获取WSDL。
具体修复步骤
1. 修改soap_api.py,移除内置服务器并暴露SOAP应用
删除server = make_server(...)和server.serve_forever()两行代码,保留Spyne应用定义并暴露wsgi_app:
import logging import main_archive # 你的业务模块 from spyne import Application, rpc, ServiceBase, Integer, Unicode from spyne import Iterable from spyne.protocol.soap import Soap11 from spyne.server.wsgi import WsgiApplication logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s %(levelname)s - %(message)s') file_handler = logging.FileHandler("/var/www/app_on_mod_wsgi/logs/info_logs.log") file_handler.setFormatter(formatter) logger.addHandler(file_handler) logger.info("SOAP service successfully started") class HelloWorldService(ServiceBase): @rpc(Unicode, Integer, _returns=Iterable(Unicode)) def say_hello(ctx, name, times): for i in range(times): yield 'Hello, %s' % name # 配置纯SOAP协议,若需同时支持JSON可保留原in_protocol配置 application = Application([HelloWorldService], tns='spyne.examples.hello', in_protocol=Soap11(), out_protocol=Soap11() ) wsgi_app = WsgiApplication(application)
2. 在主Flask模块中挂载SOAP服务
修改主Python模块(如app.py),将Spyne的SOAP应用挂载到Flask的子路径(如/soap):
from flask import Flask, request from flask_restful import Api import soap_api app = Flask(__name__) api = Api(app) # 挂载SOAP服务到/soap路径 @app.route('/soap', methods=['GET', 'POST']) def soap_service(): return soap_api.wsgi_app(request.environ, start_response) def start_response(status, headers): app.response_class(status=status).headers.extend(headers) return lambda data: app.response_class(data, status=status, headers=headers) # 你的REST服务路由定义...
3. 重启服务验证
- 重启Gunicorn服务:
systemctl restart gunicorn(根据你的实际服务名调整) - 重启Apache服务:
systemctl restart apache2
现在访问http://localhost/soap?wsdl即可查看WSDL文件,发送SOAP请求到http://localhost/soap即可调用服务。
额外说明
- 若需同时支持JSON输入和SOAP输出,可保留原
in_protocol=JsonDocument(validator='soft')配置,但需注意SOAP客户端的协议匹配。 - 确保
/var/www/app_on_mod_wsgi/logs/目录存在且Gunicorn进程有写入权限,避免日志写入失败。
内容的提问来源于stack exchange,提问作者Whatever22
相关产品推荐
相关产品推荐

