SmartTravel 智游 —— 全栈智能旅游平台

前言

本文完整记录单人独立开发上线智能旅游平台 SmartTravel 的全过程,从微服务架构搭建、大模型行程生成、支付对接,到线上内存调优、多层容灾降级实战,完整覆盖前后端、中间件、部署运维全链路开发经验,适合全栈开发者、毕业设计项目创作者参考借鉴。

一、项目简介

智游是一个 AI 驱动的旅行规划平台。用户用自然语言描述旅行愿望——比如"带父母去北京 5 天,预算 1.5 万,喜欢历史文化,腿脚不好不爬山"——系统自动生成包含景点、餐饮、住宿的完整行程。确认行程后在线预订酒店、门票、餐厅,走支付宝真实扫码付款,支付成功后短信通知用户。

核心体验闭环:输入目的地 → AI 生成行程 → 确认预订清单 → 支付宝付款 → 短信通知。

整个项目独立完成,前后端共 13 个容器微服务,部署在阿里云 ECS 上,公网可直接访问。

层级 技术
前端 Vue 3 + TypeScript + Element Plus + Pinia + Vite
AI 引擎 LangChain + DeepSeek V3
后端 FastAPI + SQLAlchemy 2.0 + Pydantic
数据库 MySQL 8.4 + Redis 7.2
搜索引擎 Elasticsearch 8.15
消息队列 RabbitMQ 3.13
部署 Docker Compose(13 个容器)+ Nginx

二、技术架构

整体拓扑

┌─────────────────────────────────────────────┐
│                    Nginx (80)               │
│                 反向代理 + 静态资源           │
└─────────────────┬───────────────────────────┘
                  │
        ┌─────────┴──────────┐
        │                    │
   Frontend (5173)      Gateway (8000)
   Vue 3 + Vite          FastAPI 统一网关
                              │
   ┌──────────┬──────────┬────┴─────┬──────────┬──────────┬──────────┐
   │          │          │          │          │          │          │
 User      Itinerary  Search    Payment   Notification  Review
 Service   Service    Service   Service   Service       Service
 (8001)    (8002)     (8003)    (8004)    (8005)        (8007)
 认证/短信  行程/AI    ES搜索    支付宝     短信/邮件     评价系统
   │          │          │          │          │          │
   └──────────┴──────────┴──────────┴──────────┴──────────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
          MySQL 8.4      Redis 7.2     RabbitMQ 3.13
                              │
                      Elasticsearch 8.15

Gateway 作为唯一入口,根据 URL 前缀路由到对应服务:

SERVICE_ROUTES = {
    "/user":          "http://user-service:8001",
    "/itinerary":     "http://itinerary-service:8002",
    "/search":        "http://search-service:8003",
    "/payment":       "http://payment-service:8004",
    "/notification":  "http://notification-service:8005",
}

拆成微服务的核心原因是各服务的资源特征不同:行程生成是 CPU/IO 密集型(调 LLM API 30-120 秒),搜索是 ES 密集型,支付是事务密集型。拆分后可以独立扩容。

低成本环境的内存调优

2 核 4G 运行 13 个容器(含 ES + MySQL),通过以下优化将内存占用控制在 3.2G 以内:

  • Elasticsearch 堆内存:-Xms128m -Xmx256m(默认 1G)
  • MySQL 调小 buffer_pool_size
  • Python 微服务不设内存上限,按需分配
  • 整体内存利用率约 85%,稳定运行不 OOM

三、核心功能实现

1. AI 行程生成:LangChain + DeepSeek V3

为什么选 DeepSeek V3

成本:API 价格约为 GPT-4o 的 1/50。一次行程生成消耗约 4000 tokens,成本约 0.01 元人民币。

中文能力:实测"带父母去北京,喜欢历史文化,腿脚不好不爬山"这种复杂约束,能正确提取"北京"+“历史文化”+“不爬山”+"无障碍需求"四个维度的信息。

API 兼容性:DeepSeek API 完全兼容 OpenAI 格式,一行配置即可接入:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="deepseek-chat",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    base_url="https://api.deepseek.com/v1",
    temperature=0.3,
    max_tokens=4096,
    timeout=120,
    max_retries=2,
)
两阶段生成流水线

AI 行程生成拆成两个独立模块,各自有明确的输入输出契约:

用户输入 "我想一个人去新疆发呆5天,预算3000"
    │
    ▼
┌──────────────────────────────────────┐
│  阶段一:意图解析                     │
│  输入: 自然语言                      │
│  输出: { destination: "新疆", days: 5, │
│          budget: 3000, style: "自然风光",│
│          companion: "独自" }           │
└──────────────┬───────────────────────┘
               │
               ▼
┌──────────────────────────────────────┐
│  阶段二:行程生成                     │
│  输入: 意图参数                      │
│  输出: 完整行程 JSON (每天活动/酒店)   │
└──────────────────────────────────────┘

阶段一:用 LangChain 的 ChatPromptTemplate 约束 LLM 输出严格 JSON。LLM 偶尔输出非标准 JSON 时,代码先尝试 json.loads(),失败则用正则从原始文本中提取天数、预算、城市等关键信息,保证系统不崩溃。

阶段二:用 LangChain 的 @tool 装饰器定义 POI 搜索工具,LLM 在生成行程时自动调用高德地图 API 获取真实景点、酒店数据,基于真实数据填充行程。当高德 API 不可用时,降级为 LLM 根据常识自行补全。

2. 支付闭环

支付对接支付宝网页支付,实现从下单到回调的完整闭环。

用户确认预订清单 → 后端创建支付订单 → 跳转支付宝扫码付款
                                              ↓
                                       支付宝同步回调(?paid=1)
                                              ↓
                                       从 sessionStorage 恢复订单详情
                                              ↓
                                       弹窗展示:订单号 + 费用明细(酒店/门票/餐饮逐项列出)

关键设计

  • 跳转支付宝前将订单快照存入 sessionStorage
  • 同步回调(return_url)负责页面跳转,异步回调(notify_url)负责支付确认
  • 沙箱模式支持模拟支付,方便开发调试

踩坑:回调后页面曾出现空白,根因是 router.replace 导致 Vue 组件销毁重建。移除 replace 并改用 sessionStorage 做跨页面状态保持后解决。

3. Vue 3 前端架构

前端共 60+ 个组件,按功能分为六层:

views/           # 页面级组件
components/
  ├── chat/      # AI 对话:ChatPanel、StreamingIndicator、QuickPrompts
  ├── itinerary/ # 行程展示:TimelineDay、ActivityCard、BudgetBar
  ├── search/    # 搜索:SearchBar、SearchFilters、PoiCard
  ├── payment/   # 支付:BookingItem、PaymentPanel、ResourceLock
  ├── home/      # 首页:HeroSection、DestinationGrid、FeatureShowcase
  └── common/    # 通用:AppHeader、AppFooter、LoadingSkeleton

TypeScript 类型系统:所有数据结构都有严格类型定义。一次重构把后端返回字段从 price 改成 estimated_cost,TypeScript 编译直接报了 12 个类型错误,精确指出每个需修改的文件。

Pinia 状态管理:拆了 4 个独立的 store(user、itinerary、search、payment),每个 store 只管理自己的状态和 API 调用,互不耦合。

JWT 双 Token 无感刷新:Axios 响应拦截器捕获 401 状态码,自动用 refresh_token 换新 access_token 后重试原请求。多个请求同时 401 时,用 isRefreshing 锁保证只刷新一次 Token。

SSE 流式输出:AI 生成行程耗时 30-120 秒,用 Server-Sent Events 实现流式推送。前端 fetch + ReadableStream 逐块读取,后端 FastAPI StreamingResponse + AsyncGenerator 逐个 yield SSE 事件,用户实时看到行程逐条生成。

4. 搜索引擎:Elasticsearch 8.15

支持三种查询模式:

全文搜索:multi_match 跨字段匹配,name 权重最高,带 fuzziness 自动容错:

{"multi_match": {
    "query": "故宫",
    "fields": ["name^3", "description^2", "tags^1.5"],
    "fuzziness": "AUTO"
}}

地理位置搜索:geo_distance 查询附近 POI,按距离升序排列。

自动补全:completion suggest 类型,输入"故"自动提示"故宫博物院"。

MySQL 的 LIKE '%故宫%' 无法处理中文分词、拼音搜索、地理位置排序和相关性打分,这些 ES 全部内置支持。ES 不可用时自动降级到 Python 内存种子数据,保证前端不白屏。

5. RabbitMQ 事件驱动

支付超时处理用 x-delayed-message 插件实现 15 分钟延迟消息:

payment-service 创建订单
  → 发布 "order.created" 到 RabbitMQ
  → notification-service 消费 → 短信/WebSocket 推送通知
  → 延迟队列 → 15 分钟后检查支付状态 → 超时自动取消

6. 短信验证码三层降级

  1. 阿里云 SDK 调用失败 → 自动切换 dev_mode,生成本地验证码
  2. Redis 缓存失败 → MySQL 兜底(验证码同时写 Redis 和 MySQL)
  3. 全部失败 → 验证码直接通过 API 返回给前端

阿里云 SDK 是同步阻塞的,通过 loop.run_in_executor() 在线程池中调用,不阻塞 FastAPI 事件循环。

7. 资源锁防超卖

支付页面 15 分钟内锁定资源,超时自动释放。前端 setInterval 实时倒计时 900 秒,后端 Redis SET order_lock:xxx EX 900 到期自动过期,双重保障。


四、容灾设计:七层降级策略

系统中每一个外部依赖都有对应的降级方案:

故障场景 降级行为
DeepSeek API 不可用 正则提取意图 + 模板生成行程
高德 POI API 不可用 LLM 根据常识自行补全景点/酒店数据
高德天气 API 不可用 返回模拟晴天数据,不阻塞检查
阿里云 SMS 不可用 自动切换 dev_mode,验证码返回前端
MySQL 不可用 服务不崩溃,切换内存字典模式
Redis 不可用 验证码回退 MySQL,缓存穿透直接查 DB
Elasticsearch 不可用 返回空结果,自动补全用本地词典

这些异常处理逻辑约占整体代码量 30%,但它们是系统在生产环境真正可用的基础。核心原则:外部依赖挂了,自己的服务不能跟着挂


五、故障排查实录

支付回调页面空白

  • 现象:支付宝付款后跳回页面,主体区域空白
  • 根因onMountedrouter.replace('/itinerary/payment') 导致组件销毁重建,弹窗一闪而空
  • 解决:移除 router.replace,改用 sessionStorage 跨页面传递订单数据

重建前端后 Nginx 502

  • 现象docker compose up -d --build frontend 后页面报 502
  • 根因:Nginx 缓存了旧容器的 IP,新容器 IP 变化后 Connection Refused
  • 解决docker compose restart nginx 刷新 DNS 缓存

支付宝密钥目录混淆

  • 现象:payment-service 启动崩溃,日志提示找不到密钥文件
  • 根因alipay_private_key.pemalipay_public_key.pem 在 Git 中为空目录(Git 不追踪空目录)
  • 解决:通过 heredoc 在 ECS 上直接写入真实密钥内容

六、项目数据

指标 数值
独立开发 100%(1 人全栈)
容器数量 13 个(7 微服务 + 6 中间件)
前端组件 60+ 个 Vue 组件
功能闭环 注册→登录→AI 行程→预订→支付宝付款→短信通知 完整打通
内存优化 从 OOM 到稳定运行 3.2G / 3.7G
降级层数 7 层(DeepSeek / 高德 POI / 天气 / SMS / MySQL / Redis / ES)
上线状态 公网可访问,支付宝真实扫码支付

七、技术反思

  1. 微服务边界要务实:7 个服务在 2C4G 下运维成本高于单体。若重来一次,会先单体上线验证核心流程,再按业务域渐进拆分
  2. 日志是第一排查工具docker compose logs --tail=50 是使用频率最高的命令,所有线上故障均靠日志定位
  3. 第三方依赖必须降级:每个外部服务挂了都有应对方案,不把系统可用性寄托在第三方 SLA 上
  4. 测试是最大的技术债:目前依赖手动验收,缺少单元测试和集成测试,是后续优先补充的部分
  5. TypeScript 物超所值:一次字段名重构发现 12 处遗漏修改,编译期拦截比运行时排查高效得多
  6. 支付模块深度不足:目前仅完成支付宝基础扫码支付闭环,支付成功后订单详情的查询与展示、支付消息的实时推送(站内通知 / WebSocket 推送而非仅短信)尚未实现,用户支付体验还有较大提升空间
  7. 搜索能力可进一步增强:当前 ES 搜索依赖字段加权和关键词匹配,缺少语义理解能力。引入 RAG(检索增强生成)可以将搜索结果结合大模型做智能整合,让用户获得更精准、更自然的搜索回答
  8. 单点 Redis 存在风险:当前 Redis 是单实例部署,一旦宕机会导致验证码、资源锁、会话缓存全部失效。后续需要搭建 Redis 集群保障高可用
  9. 数据展示缺乏可视化:个人中心的订单记录、消费统计、历史行程等信息目前以纯文本列表展示,缺少图表和可视化看板,用户难以直观了解自己的旅行消费趋势

八、后续规划

基于当前项目现状与技术反思,后续将分三个优先级推进:

优先级 P0:核心体验增强

功能 说明
AI 行程生成升级 DeepSeek V3 实时推理替代当前模板降级方案,生成质量从"可用"提升到"惊艳"
支付订单详情展示 支付宝支付成功后,用户可在个人中心查看完整订单详情(订单编号、费用明细逐项列出、支付时间)
消息通知推送 基于 WebSocket 实现站内实时通知(支付成功、行程提醒、天气预警),类似微信消息弹窗的推送体验,替代当前单一的短信通知
个人中心数据可视化 引入 ECharts 图表展示消费趋势、目的地偏好、月度旅行频次等,让数据一目了然

优先级 P1:业务闭环扩展

功能 说明
购物车 用户可在行程生成后将多个景点、酒店、餐厅加入购物车,统一结算,支持增删改和批量下单
旅游推荐系统 基于用户历史行程数据和偏好标签,协同过滤推荐相似的景点和行程,提升转化率
订单管理后台(商家端) 酒店、餐厅、景区商家可登录后台管理订单、查看营收数据、设置库存和价格
RAG 增强搜索 引入 Milvus 向量数据库 + Embedding 模型,搜索结果经 LLM 二次整合,支持口语化自然语言搜索(如"适合带爸妈去的安静景点")

优先级 P2:架构升级

功能 说明
Redis 集群架构 Redis Sentinel 主从 + 哨兵模式,实现自动故障转移,保障验证码、资源锁、会话缓存的高可用
MySQL 读写分离 主库写、从库读,应对用户量增长后的数据库压力
ES 独立节点 将 Elasticsearch 从当前容器中拆出为独立节点,避免与其他服务争抢内存和 CPU

结语

一个完整上线的项目不仅是功能堆砌,更考验架构取舍、故障容错与低成本运维能力。本项目暴露出微服务拆分、缓存高可用等优化空间,后续迭代将补齐 RAG 检索、Redis 集群等能力,也希望本篇实战复盘能为做全栈、AI 类开发的开发者提供可复用的落地思路。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐