news 2026/6/15 20:07:11

零基础从零到一PHP开发仿12306系统的庖丁解牛

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零基础从零到一PHP开发仿12306系统的庖丁解牛

12306 的本质是高并发、强一致性、分布式事务的票务系统


一、核心认知:12306 的本质是什么?

▶ 1.业务本质
  • 核心实体
    • 车次(Train)
    • 座位(Seat)
    • 订单(Order)
  • 核心流程

    查询余票

    锁定座位

    支付

    生成电子票

▶ 2.技术挑战
挑战初学者简化方案
高并发单机 MySQL + 乐观锁
分布式事务本地事务 + 补偿机制
余票计算预分配座位池

💡核心原则
先实现单机版,再考虑分布式


二、阶段 1:单机 MVP(1 天)

▶ 1.数据库设计
-- 车次表CREATETABLEtrains(idINTPRIMARYKEYAUTO_INCREMENT,train_noVARCHAR(20)NOTNULL,-- G1234departureVARCHAR(50)NOTNULL,-- 北京南arrivalVARCHAR(50)NOTNULL,-- 上海虹桥depart_timeDATETIMENOTNULL);-- 座位表(预分配)CREATETABLEseats(idINTPRIMARYKEYAUTO_INCREMENT,train_idINTNOTNULL,seat_noVARCHAR(10)NOTNULL,-- 05车12AstatusTINYINTDEFAULT0,-- 0=可用, 1=已锁定, 2=已售FOREIGNKEY(train_id)REFERENCEStrains(id));-- 订单表CREATETABLEorders(idVARCHAR(32)PRIMARYKEY,-- UUIDuser_idINTNOTNULL,train_idINTNOTNULL,seat_idINTNOTNULL,statusTINYINTDEFAULT0,-- 0=待支付, 1=已支付created_atDATETIMEDEFAULTCURRENT_TIMESTAMP,FOREIGNKEY(seat_id)REFERENCESseats(id));
▶ 2.PHP 基础代码(无框架)
  • db.php(数据库连接):

    <?php$pdo=newPDO('mysql:host=localhost;dbname=12306','root','',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);
  • query.php(查询余票):

    <?phprequire'db.php';$trainId=$_GET['train_id'];$stmt=$pdo->prepare(" SELECT COUNT(*) as available FROM seats WHERE train_id = ? AND status = 0 ");$stmt->execute([$trainId]);echojson_encode($stmt->fetch());
  • lock.php(锁定座位):

    <?phprequire'db.php';$trainId=$_POST['train_id'];// 乐观锁:仅锁定可用座位$pdo->beginTransaction();try{$stmt=$pdo->prepare(" SELECT id FROM seats WHERE train_id = ? AND status = 0 LIMIT 1 FOR UPDATE ");$stmt->execute([$trainId]);$seat=$stmt->fetch();if(!$seat){thrownewException('No seats available');}// 锁定座位$pdo->prepare("UPDATE seats SET status = 1 WHERE id = ?")->execute([$seat['id']]);// 创建订单$orderId=uniqid();$pdo->prepare(" INSERT INTO orders (id, user_id, train_id, seat_id) VALUES (?, 1, ?, ?) ")->execute([$orderId,$trainId,$seat['id']]);$pdo->commit();echojson_encode(['order_id'=>$orderId]);}catch(Exception$e){$pdo->rollback();http_response_code(400);echojson_encode(['error'=>$e->getMessage()]);}

三、阶段 2:核心功能增强(3 天)

▶ 1.余票缓存(防超卖)
  • 问题
    • 高并发下SELECT ... FOR UPDATE性能差
  • 解决方案
    -- 新增余票计数表CREATETABLEtrain_inventory(train_idINTPRIMARYKEY,available_seatsINTNOTNULL,versionINTDEFAULT0-- 乐观锁版本号);
  • 锁定逻辑
    // 先扣减库存$stmt=$pdo->prepare(" UPDATE train_inventory SET available_seats = available_seats - 1, version = version + 1 WHERE train_id = ? AND available_seats > 0 ");if($stmt->execute([$trainId])&&$stmt->rowCount()>0){// 再分配具体座位// ...}
▶ 2.订单超时释放
  • 方案
    • 定时任务扫描 15 分钟未支付订单
    • 释放座位并回滚库存
  • crontab
    */5 * * * * php /path/to/release_expired_orders.php
▶ 3.基础安全防护
  • SQL 注入
    • 全程使用PDO::prepare()
  • XSS
    • 输出时htmlspecialchars()
  • CSRF
    • 表单添加隐藏 Token 字段

四、阶段 3:性能与扩展(7 天+)

▶ 1.引入 Redis 缓存
  • 缓存余票
    // 查询余票$available=$redis->get("train:{$trainId}:seats");if($available===false){// 从 DB 加载并缓存$available=getFromDB();$redis->setex("train:{$trainId}:seats",30,$available);}
▶ 2.队列解耦(Swoole)
  • 架构

    提交订单

    Web 服务器

    Swoole 队列

    订单处理 Worker

    MySQL

  • 优势
    • Web 层快速响应
    • 异步处理高耗时操作
▶ 3.分库分表(未来扩展)
  • 拆分策略
    • 按车次日期分表(orders_20231001
    • 按用户 ID 分库

五、避坑指南

陷阱破局方案
直接实现分布式事务先用本地事务 + 补偿机制
过度设计缓存余票缓存足够,避免复杂多级缓存
忽略数据一致性FOR UPDATE或 Redis Lua 脚本保证原子性

六、终极心法

**“12306 不是系统,
而是领域的显影——

  • 当你建模实体
    你在校准边界;
  • 当你简化并发
    你在聚焦核心;
  • 当你渐进扩展
    你在铸造韧性。

真正的工程能力,
始于对领域的敬畏,
成于对细节的精控。”


结语

从今天起:

  1. 先实现单机版余票查询 + 锁定
  2. FOR UPDATE保证基础一致性
  3. 逐步引入 Redis/Swoole 优化

因为最好的高并发系统,
不是一蹴而就,
而是亲手活出每一行代码的密度。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 11:30:18

Open Interpreter未来趋势预测:本地AI编程部署前景展望

Open Interpreter未来趋势预测&#xff1a;本地AI编程部署前景展望 1. Open Interpreter是什么&#xff1a;让自然语言真正变成可执行代码的本地引擎 Open Interpreter 不是一个新概念的玩具&#xff0c;而是一套已经跑在成千上万台电脑上的“本地AI编程操作系统”。它不依赖…

作者头像 李华
网站建设 2026/6/15 1:17:06

构建卓越通信体验:移动端开发工程师(IM系统方向)的核心能力与实践

上海辰锐信息科技有限公司 移动端开发工程师 职位信息 岗位职责: 1.负责IM系统设计:架构设计、技术选型、演进规划、安全性框架、高可用架构等; 2.负责移动端应用程序的开发、测试、交付等; 3.参与移动端功能设计开发规范的制定、实施及优化; 4.负责团队技术指导与跨团队沟…

作者头像 李华
网站建设 2026/6/15 11:37:45

AD导出Gerber文件教程:新手必看的EDA输出流程

以下是对您提供的博文《AD导出Gerber文件教程:新手必看的EDA输出流程技术分析》进行 深度润色与专业重构后的版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、老练、有工程师现场感 ✅ 摒弃“引言/核心知识点/应用场景/总结”等模板化结构,代之以 …

作者头像 李华
网站建设 2026/6/14 12:30:39

一文说清多层感知机如何实现组合逻辑门

以下是对您提供的博文内容进行 深度润色与结构重构后的专业级技术文章 。全文已彻底去除AI生成痕迹,采用真实工程师口吻、教学博主风格撰写,逻辑层层递进,语言自然流畅,兼具理论严谨性与工程实操感。所有术语、公式、代码、表格均保留并优化表达,同时强化了“为什么这么…

作者头像 李华
网站建设 2026/6/13 10:41:09

开箱即用!DASD-4B-Thinking模型部署与调用全攻略

开箱即用&#xff01;DASD-4B-Thinking模型部署与调用全攻略 你是否试过在本地部署一个能真正“思考”的小模型&#xff1f;不是简单地接个API&#xff0c;而是从零开始&#xff0c;把一个专精数学推理、代码生成和科学分析的40亿参数模型稳稳装进自己的环境里&#xff0c;点开…

作者头像 李华
网站建设 2026/6/15 12:39:16

Qwen3-4B Instruct-2507入门必看:temperature/top_p/nucleus sampling区别

Qwen3-4B Instruct-2507入门必看&#xff1a;temperature/top_p/nucleus sampling区别 1. 这不是“调参玄学”&#xff0c;是掌控生成质量的开关 你有没有遇到过这样的情况&#xff1a; 问模型“请写一首春天的诗”&#xff0c;它回了一首押韵工整但毫无灵气的八股&#xff1…

作者头像 李华