第二次线上事故
# 图片分类服务问题排查与修复记录
## 项目背景
基于FastAPI的房间图片分类服务,使用Gemini AI进行图片识别,部署在Linux服务器上。
## 遇到的问题及解决过程
### 问题1:服务无响应
**现象**:用户反馈访问时出现504错误,服务无法正常响应
**排查步骤**:
1. 检查进程状态:`ps aux | grep uvicorn` - 发现进程存在(PID 3829)
2. 测试服务响应:`curl localhost:5000/health` - 超时无响应
3. 检查端口:`netstat -tlnp | grep 5000` - 端口在监听
**解决方法**:
- 强制结束无响应的进程:`kill -9 3829`
- 重新启动服务:`uvicorn main:app --host 0.0.0.0 --port 5000`
- 验证恢复:服务能正常响应健康检查
**问题原因推测**:进程可能在某个Gemini API调用处阻塞
### 问题2:MIME类型处理
**现象**:日志中出现错误
```
ERROR:main:下载图片失败: 不支持的MIME类型: application/octet-stream
```
**分析**:
- 某些图片URL返回`application/octet-stream`而不是`image/jpeg`
- 原代码只接受以`image/`开头的MIME类型
- Gemini API需要正确的MIME类型
**修改方案**:
1. 在`download_image`函数中增加对`application/octet-stream`的处理
2. 根据URL扩展名推断图片类型
3. 在调用Gemini API前转换MIME类型
**代码修改**:
```python
# 添加函数判断URL是否为图片
def is_likely_image_url(url):
image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp']
return any(url.lower().endswith(ext) for ext in image_extensions)
# 修改MIME类型验证逻辑
def is_valid_image_mime_type(mime_type, url=None):
if mime_type.startswith('image/'):
return True
if mime_type == 'application/octet-stream' and url:
return is_likely_image_url(url)
return False
# 为Gemini API转换MIME类型
def ensure_valid_mime_type_for_gemini(mime_type, url=None):
if mime_type == 'application/octet-stream' and url:
if url.lower().endswith(('.jpg', '.jpeg')):
return 'image/jpeg'
# 其他扩展名的处理...
return mime_type
```
**测试结果**:
- 修改前:某些图片处理失败
- 修改后:之前失败的URL能正常处理
## 技术要点
### 学到的内容
1. **进程管理**:如何排查和处理无响应的服务进程
2. **nginx配置**:反向代理的基本配置方法
3. **API集成**:处理第三方API的兼容性问题
4. **错误处理**:根据日志定位和解决具体问题
### 用到的工具和命令
- 进程管理:`ps`, `kill`, `nohup`
- 网络检查:`netstat`, `curl`
- 服务管理:`systemctl`
- 日志分析:`tail`, `grep`
### 解决思路
1. **现象观察**:通过日志和命令行工具观察问题表现
2. **原因分析**:结合代码逻辑分析可能的原因
3. **逐步解决**:先恢复服务,再解决具体功能问题
4. **验证测试**:修改后进行功能验证
## 实际效果
- 服务从无法访问恢复到正常运行
- 解决了特定类型图片无法处理的问题
- 建立了通过80端口访问的标准化方式
这次问题解决主要是针对具体的技术问题进行排查和修复,积累了一些实际的运维和调试经验。