Apache部署的Flask应用调用WSDL服务出现Network is unreachable错误
问题原因
存在两个核心问题导致部署后网络不可达:
- 现有校验函数的代理设置时机错误:zeep的
Client类初始化阶段就会主动请求WSDL文件,你当前的代码是创建Client完成后才设置代理,请求WSDL的阶段根本没走代理,直接直连失败。 - Apache的WSGI进程默认不会继承系统配置的
http_proxy/https_proxy环境变量,就算你本地用户配置了,Apache运行的应用进程也读取不到。
解决方案
第一步:修正校验函数的代理设置顺序
调整代码逻辑,在Client初始化前就完成代理配置,修改后的代码如下:
def validate_vat(self, vat): transport = Transport(timeout=10) # 初始化Client之前就设置代理,确保WSDL请求和后续接口请求都走代理 transport.session.proxies = { 'http': 'http://<proxy.server.com>:9090', # 如果有HTTPS的请求也要加对应HTTPS代理配置 'https': 'http://<proxy.server.com>:9090' } try: client = Client('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', transport=transport) response = client.service.checkVat(vat.data[0:2].upper(), vat.data[2:]) except: raise wtforms.validators.ValidationError('VAT validation service unavailable. Please try again later') if not response.valid: raise wtforms.validators.ValidationError('Not a valid VAT')
第二步:Apache配置传递代理环境变量(可选,适合不想硬编码代理的场景)
如果不想把代理地址硬编码在代码里,可以在你的Flaskapp.conf的VirtualHost块中添加SetEnv指令,将代理地址传递给WSGI应用:
<VirtualHost *:80> ServerName $stationIP ServerAdmin name@domain.com # 新增代理环境变量配置 SetEnv http_proxy http://<proxy.server.com>:9090 SetEnv https_proxy http://<proxy.server.com>:9090 WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi <Directory /var/www/FlaskApp/FlaskApp/> Order allow,deny Allow from all </Directory> Alias /static /var/www/FlaskApp/FlaskApp/static <Directory /var/www/FlaskApp/FlaskApp/static/> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
修改配置后需要重启Apache生效:systemctl restart apache2
这时候你也可以选择在代码中读取环境变量自动设置代理,避免硬编码:
import os transport.session.proxies = { 'http': os.environ.get('http_proxy'), 'https': os.environ.get('https_proxy') }
内容的提问来源于stack exchange,提问作者Pjotruk Prekeder
相关产品推荐
相关产品推荐

