# HTTP 代理配置指南 ## 问题背景 在中国境内部署 Cosmo 时,后端服务需要访问 NASA JPL Horizons API 来获取天体数据,但由于网络限制,直接访问可能会超时或失败。 ## 解决方案 配置 HTTP 代理来访问 NASA API。 ## 配置步骤 ### 1. 在 `.env.production` 中配置代理 编辑 `/Users/jiliu/WorkSpace/cosmo/.env.production` 文件,添加代理配置: ```bash # HTTP 代理配置(用于访问 NASA JPL Horizons API) # 格式:http://host:port HTTP_PROXY=http://192.168.124.203:20171 HTTPS_PROXY=http://192.168.124.203:20171 ``` **注意**: - 代理地址格式必须包含协议前缀(`http://` 或 `https://`) - 如果您的代理服务器只监听 HTTP,两个配置都使用 `http://` - 确保代理服务器在部署的服务器上可以访问(192.168.124.203:20171) ### 2. 重启后端服务 配置修改后需要重启后端服务才能生效: ```bash # 在部署服务器上执行 cd /path/to/cosmo ./deploy.sh --restart ``` 或者使用 Docker Compose: ```bash docker-compose restart backend ``` ## 工作原理 ### 1. httpx 代理配置 后端使用 `httpx` 库直接访问 NASA API(`get_object_data_raw` 方法)。代理通过 `httpx.AsyncClient` 的 `proxies` 参数传递: ```python client_kwargs = {"timeout": 5.0} if settings.proxy_dict: client_kwargs["proxies"] = settings.proxy_dict # proxies = {"http://": "http://192.168.124.203:20171", # "https://": "http://192.168.124.203:20171"} async with httpx.AsyncClient(**client_kwargs) as client: response = await client.get(url, params=params) ``` ### 2. astroquery 代理配置 `astroquery` 库(用于 `get_body_positions` 方法)通过标准环境变量使用代理: ```python if settings.http_proxy: os.environ['HTTP_PROXY'] = settings.http_proxy if settings.https_proxy: os.environ['HTTPS_PROXY'] = settings.https_proxy ``` ## 验证配置 ### 1. 检查日志 配置代理后,启动服务时会在日志中看到: ``` INFO - Set HTTP_PROXY for astroquery: http://192.168.124.203:20171 INFO - Set HTTPS_PROXY for astroquery: http://192.168.124.203:20171 ``` 访问 NASA API 时会看到: ``` INFO - Using proxy for NASA API: {'http://': 'http://192.168.124.203:20171', 'https://': 'http://192.168.124.203:20171'} INFO - Fetching raw data for body 10 ``` ### 2. 测试 API 访问 在前端点击天体的 "JPL Horizons" 按钮,查看是否能成功获取数据。 或者直接访问后端 API: ```bash curl http://your-server-ip/api/nasa/object/10 ``` ## 常见问题 ### 1. 代理地址格式错误 ❌ **错误**: ```bash HTTP_PROXY=192.168.124.203:20171 # 缺少协议前缀 ``` ✅ **正确**: ```bash HTTP_PROXY=http://192.168.124.203:20171 ``` ### 2. 代理服务器无法访问 确保代理服务器在部署服务器上可以访问: ```bash # 在部署服务器上测试 curl -x http://192.168.124.203:20171 https://ssd.jpl.nasa.gov/api/horizons.api ``` ### 3. 仍然超时 如果配置代理后仍然超时,检查: 1. 代理服务器是否运行正常 2. 代理服务器是否允许访问 `ssd.jpl.nasa.gov` 3. 防火墙是否阻止了连接 ### 4. 日志中没有代理信息 如果日志中没有 "Using proxy" 信息,检查: 1. `.env.production` 文件是否正确配置 2. 是否重启了服务 3. Docker 容器是否正确加载了环境变量: ```bash docker-compose exec backend env | grep PROXY ``` ## 不需要代理的情况 如果您的服务器可以直接访问 NASA API(例如:海外服务器),只需将代理配置留空即可: ```bash HTTP_PROXY= HTTPS_PROXY= ``` ## 相关文件 - **配置**: `backend/app/config.py` - Settings 类中的 `http_proxy`, `https_proxy`, `proxy_dict` - **使用**: `backend/app/services/horizons.py` - HorizonsService 类 - **环境变量**: `.env.production` - HTTP_PROXY, HTTPS_PROXY ## 参考链接 - [httpx Proxies Documentation](https://www.python-httpx.org/advanced/#http-proxying) - [NASA JPL Horizons API](https://ssd-api.jpl.nasa.gov/doc/horizons.html) - [astroquery Documentation](https://astroquery.readthedocs.io/)