仿12306校招项目-项目业务和架构

目录

业务图

用户管理

业务难点

1. 如何确定用户注册信息的真实性

2. 面对亿级用户量

3. 支持多种登录方式会造成读请求扩散,需要解决用户定位问题

4. 高并发场景下缓存穿透问题需要有效解决,避免数据库压力过大

5. 明文存储用户敏感信息会造成安全隐患,需要对关键数据加密

项目效果

​编辑

​编辑

​编辑

​编辑

数据库设计

会员相关核心数据库表

乘车人数据表

列车数据表

订单数据表

项目结构


业务图

大体上分为会员服务、订单服务、购票服务、支付服务、网关服务​​​​​​​

用户管理

12306 铁路购票系统中,存在两类用户,分别是:会员(即当前账户登录用户)以及乘车

人。

会员支持在系统中自行注册,需要注册者提供用户名、密码、证件类型、证件号、真实姓

名、手机号、邮箱以及旅客类型。

其中,用户名和证件号码全局唯一,不允许注册者重复使用。

会员登录系统时,支持用户名/邮箱/手机号码三种登录方式,搭配密码完成系统用户登录

行为。

一个注册会员可以添加多个乘车人。添加乘车人时需要填写真实姓名、身份证、手机号

等,新增乘车人需要通过实名认证审核,审核通过方可成功。

会员选择交通工具(火车、高铁等)进行买票时,可以选择多个乘车人进行购票。

会员可以通过已支付订单查看所有订单信息,乘车人也可通过订单标签页中本人车票查看

自己或其他会员购买为自己购买的订单信息。

业务难点

1. 如何确定用户注册信息的真实性

当用户在 12306 网站注册新账号或者为自己的账号添加新的乘车人时,系统需要确保用

户提交的各项信息是真实准确的,而不是虚假的。

这其中就涉及到一个很重要的概念——用户信息的认证。对用户提交的信息进行认证,就是

要验证信息的真实性,确认这确实是本人自愿提交的真实信息,不是其他人冒充的。

12306 中的信息准确性校验主要包括:

1.注册会员时,校验用户名、证件号、手机号是否匹配,确保账号信息真实有效。

2.添加乘车人时,校验乘车人姓名、身份证号是否真实匹配,并校验手机号可用性。

2. 面对亿级用户量

鉴于会员和乘车人数据规模都已超过 10 亿级别,远超出单机 MySQL 数据库的处理能

力,所以需使用分库分表或分布式数据库来支撑海量数据。

分库分表后续又会涉及:

选择分库还是分表,还是选择分库分表?基于什么考虑?

选择哪个字段作为分片键?选择单个分片键还是复合分片键?

如何在老业务上平滑上线分库分表?出现问题如何快速回滚?

拆分后出现单表数据量过大,如何继续扩容?扩单表还是整体扩?

3. 支持多种登录方式会造成读请求扩散,需要解决用户定位问题

在具体的登录环节,由于系统支持会员使用用户名、手机号以及邮箱等多种方式进行

登录,这就存在一个比较棘手的问题:

由于登录时无法确定用户的分片键,使得系统无法直接锁定用户的数据位于哪个数据库或

者哪张表中。为了找到用户的数据,只能对全部的数据库和表进行扫描查询,这就造成了

所谓的“读请求扩散”问题。

也就是说,原本读请求可以直接定位到某个数据库某张表,现在却要多处查询,无疑大大

增加了系统的查询负载。

一旦出现了读请求扩散问题,势必会导致用户的登录请求响应时间变长,严重的话还可能

造成登录超时。

4. 高并发场景下缓存穿透问题需要有效解决,避免数据库压力过大

在高并发的会员注册场景下,可能会出现缓存穿透问题。主要原因可能是:

用户注册时,需要验证用户名是否已存在,这通常需要查询数据库。如果缓存中没有该用户名,就会去数据库查询,如果数据库中也没有,就可以判断该用户名可用。

在高并发的情况下,可能有大量的新用户同时注册,输入的用户名极有可能都不存在

于数据库中。这将导致大量的缓存不存在,都去查询数据库,造成数据库压力剧增。

且这些查询数据库的 Key 都不会被缓存,因为数据库中没有,不会写入缓存。那么这

些 Key 对应的 Null 值也不会被缓存,造成每次请求都查不到缓存,直接查询数据

库。这样就形成了缓存穿透情况。

5. 明文存储用户敏感信息会造成安全隐患,需要对关键数据加密

在 12306 系统中,存在较多的敏感信息,比如会员或者乘车人的姓名、手机号、邮箱、

证件号码以及住址。

在数据库中将手机号或身份证号等敏感个人信息存明文会带来以下安全问题:

1.明文存储可能会直接泄露用户隐私,一旦数据库被攻击或数据泄露,个人敏感信息就

会被完全暴露。

2.明文存储提高了内部人员滥用数据的风险,恶意查询和使用个人敏感信息的成本很

低。

项目效果

个人信息页面

首页查询车票

乘车人页面

订单页面

车票页面

数据库设计

会员相关核心数据库表

t_user 会员数据表:存储会员账号、密码、证件号、邮箱、手机号等信息

t_user_mail 会员邮箱数据表:存储会员邮箱和用户名的关系

t_user_phone 会员手机号数据表:存储会员手机号和用户名的关系

虽然手机号和邮箱在用户表中已经有了,但因为我们对用户表进行了分库分表行为,分片键使用的 username 用户名进行拆分。分库分表中间件ShardingSphere 会通过分片键 username 用户名来确定数据在哪个库中的哪个表。所以,分库分表后,每次增删改查都需要带上分片键用户名。不然的话,查询会请求所有库的所有用户表,新增、修改和删除会直接报错。

用户相关扩展功能表如下:

t_user_reuse 用户名可复用表:存储已被注销的可用用户名

t_user_deletion:用户证件号注销表:存储被注销过得证件号记录数据

t_user_deletion 用户证件号注销表,用来解决用户恶意注销 12306 账号的问题。假设,一个用户用一个证件号反复注册并注销,是不是应该把他拉入黑名单。因为用户名每次注册都可以使用新的,所以说我们只能针对证件号当做依据。目前系统的规则是,如果同一个证件号注销超过5 次,就拉入黑名单不再支持注册。

乘车人数据表

t_passenger:乘车人数据表

一个用户可以多名乘车人,可以用来买票时选择多人购票。用户表和乘车人表之间通过用户名进行关联,一对多的关联关系。

列车数据表

t_train:列车表,存储每天生成的行驶列车数据。

t_carriage:列车车厢表,存储每趟列车对应的车厢数据,包括车厢类型。

t_train_station:列车站点表,存储列车行驶站点顺序表。

t_train_station_relation:列车站点关联表,存储列车行驶站点关联关系表。这是一个会把所有车站都会关联起来的数据集合,存储的数据模型如下所示:北京南->天津西,北京南->沧州西,北京南->xxx,北京南->句容西。

t_train_station_price:列车站点价格表,存储列车站点关联关系不同座位价格表。价格表在 t_train_station_relation 关系表的基础上,加入了两个字段,一个是价格,一个是座位类型。因为列车行驶路线中,不同的站点间隔费用不一样,而且不同的座位费用也不一样。通过价格表整体区分出来。

订单数据表

t_order:订单主表,用户购买的单次车票,就对应一个订单。但是有可能一个订单中会有多个

乘车人,所以还会有订单明细表。

t_order_item:订单明细表,一个订单可能有多个乘车人,多个乘车人就对应多个订单明细。

t_order_item_passenger:订单明细乘车人表,因为订单表和订单明细表分库分表规则所致,

乘车人无法查看本人车票订单,所以创建了这个关联表。通过证件号关联订单。

项目结构

12306项目的后端+前端项目,其中包含了不同的组件、服务和测试集合等。

  • checkstyle: 代码格式检查组件,包括规则配置和忽略配置。
  • console-vue: 12306前端控制台项目,包括相关文件和目录。
  • dependencies: 后端项目全局依赖版本控制的pom.xml文件。
  • format: 后端项目格式化组件,包括格式化规则配置和开源协议头格式化。
  • frameworks: 基础架构组件库,包括顶层抽象基础组件、业务相关组件、缓存组件、公共工具包、项目规约、数据库持久层、设计模式、分布式ID、幂等组件、日志打印、Web相关组件。
  • resources: 项目数据库初始化及其他资源,包括数据初始化和数据库初始化。
  • services: 后端项目集合,包括聚合模式服务、网关服务、订单服务、支付服务、购票服务、用户服务。
  • tests: 单元测试集合,包括通用单元测试。
  • pom.xml: Maven项目的配置文件。
  • LICENSE: 开源许可证文件。
  • mvnw: Maven Wrapper文件。
├── checkstyle || -- # 代码格式检查组件
│ ├── 12306_checkstyle.xml || -- # 代码格式检查组件规则配置
│ └── 12306_checkstyle_suppression.xml || -- # 忽略代码格式检查组件规则配
置
├── console-vue || -- # 12306 前端控制台项目
│ ├── README.md
│ ├── babel.config.js
│ ├── jsconfig.json
│ ├── node_modules
│ ├── package.json
│ ├── public
│ ├── src
│ ├── vue.config.js
│ └── yarn.lock
├── dependencies || -- # 12306 后端项目全局依赖版本控制
│ └── pom.xml
├── format || -- # 12306 后端项目格式化组件
│ ├── 12306_spotless_formatter.xml || -- # 12306 后端项目格式化组件规则
配置
│ └── license-header || -- # 12306 后端项目开源协议头格式化
├── frameworks || -- # 12306 基础架构组件库
│ ├── base || -- # 12306 顶层抽象基础组件
│ ├── bizs || -- # 12306 业务相关基础组件,比如用户上下文等
│ ├── cache || -- # 12306 缓存基础组件
│ ├── common || -- # 12306 公共工具包组件
│ ├── convention || -- # 12306 项目规约组件
│ ├── database || -- # 12306 数据库持久层组件
│ ├── designpattern || -- # 12306 设计模式抽象基础组件
│ ├── distributedid || -- # 12306 分布式 ID 基础组件
│ ├── idempotent || -- # 12306 幂等基础组件,包括 HTTP 及不同消息队列实现
│ ├── log || -- # 12306 日志打印基础组件库
│ └── web || -- # 12306 Web 相关基础组件库
│ ├── pom.xml
├── resources || -- # 12306 项目数据库初始化及其它
│ ├── data || -- # 12306 数据库数据初始化
│ └── db || -- # 12306 数据库初始化
├── services || -- # 12306 后端项目集合
│ ├── aggregation-service || -- # 12306 SpringBoot 聚合模式服务
│ ├── gateway-service || -- # 12306 网关服务
│ ├── order-service || -- # 12306 订单服务
│ ├── pay-service || -- # 12306 支付服务
│ ├── ticket-service || -- # 12306 购票服务
│ └── user-service || -- # 12306 用户服务
│ ├── pom.xml
└── tests || -- # 12306 单元测试集合
│ ├── general || -- # 12306 通用单元测试
└── pom.xml
├── LICENSE
├── mvnw

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/701406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抽象的java

Consider defining a bean of type org.springframework.mail.MailSender in your configuration. 报错原因: 第一个:未安装对应的依赖 第二个:对应配置问题 背景:用springboot-java完成邮箱发送 第一个问题解决方法&#xff1…

实战一个 Jenkins 构建 CI/CD流水线 的简单配置过程哈

引言:上一期我们讲述了gitlabCI/CD工具的介绍,工具之争,本期我们介绍Jenkins CI/CD 目录 一、Jenkins介绍 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 二、安装Jenkins 1、安装JDK 2、安装Jenkins 1、上传压缩包 2、…

基于django的购物商城系统

摘要 本文介绍了基于Django框架开发的购物商城系统。随着电子商务的兴起,购物商城系统成为了许多企业和个人创业者的首选。Django作为一个高效、稳定且易于扩展的Python web框架,为开发者提供了便捷的开发环境和丰富的功能模块,使得开发购物商…

GEE入门篇|遥感专业术语(实践操作3):时间分辨率(Temporal Resolution)

目录 时间分辨率(Temporal Resolution) 1.Landsat 2.Sentinel-2 时间分辨率(Temporal Resolution) 时间分辨率是指特定传感器图像流的重访时间或时间节奏,重访时间是指卫星连续访问地球表面同一位置…

小迪安全30WEB 攻防-通用漏洞SQL 注入CTF二次堆叠DNS 带外

#知识点: 1、数据库堆叠注入 根据数据库类型决定是否支持多条语句执行 2、数据库二次注入 应用功能逻辑涉及上导致的先写入后组合的注入 3、数据库 Dnslog 注入 解决不回显(反向连接),SQL 注入,命令执行,SSRF 等 4、黑盒模式分析以上 二次注入&…

创作纪念日:记录我的成长与收获

机缘 一开始是在我深入学习前端知识的Vue.js框架遇到了一个问题,怎么都解决不了,心烦意乱地来csdn上找解决方法。开心的是真被我找到了,真的很感恩,也意识到在这个平台上分享自己的经验是多么有意义的事情,可能随便的…

BRIA.AI开源最强AI一键抠图模型RMBG,超简上手体验

本文首发: AIWalker 欢迎关注AIWalker,近距离接触底层视觉与基础AI技术 近日,BRIA.AI团队于HuggingFace开源了一个基于ISNet背景移除模型RMBG-1.4,它可以有效对前景与背景进行分离。RMBG-1.4在精心构建的数据集上训练而来,该数据包…

django rest framework 学习笔记-实战商城

01项目环境搭建_哔哩哔哩_bilibili 本博客借鉴至大佬的视频学习笔记 # 创建项目 django-admin startproject MyShop# 创建app E:\desktop\my_drf\MyShop>django-admin startapp goodsE:\desktop\my_drf\MyShop>django-admin startapp orderE:\desktop\my_drf\MyShop>…

C++ //练习 8.2 测试函数,调用参数为cin。

C Primer(第5版) 练习 8.2 练习 8.2 测试函数,调用参数为cin。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块见练习8.1 /**************************************************************…

代码随想录|day 23

Day 23 一、回溯 二、代码 216. 组合总和 III - 力扣&#xff08;LeetCode&#xff09; class Solution { private:vector<int>path;vector<vector<int>>result;void backtracing(int sum,int k,int n,int startindex){//中止条件if(path.size()k){if(sum…

three.js第一个3D案例

在正式学习Three.js之前&#xff0c;先做一些必要的准备工作&#xff0c;具体说就是下载threejs官方文件包&#xff0c;threejs官方文件包提供了很多有用的学习资源。 threejs官方文件包所有版本&#xff1a;https://github.com/mrdoob/three.js/releases threejs文件资源目录…

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录 一、引言二、应用场景与技术背景三、模式定义与实现四、实例详解五、优缺点分析总结&#xff1a; 一、引言 ​ 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构&…

Android RecyclerView 如何展示自定义列表 Kotlin

Android RecyclerView 如何展示自定义列表 Kotlin 一、前提 有这么一个对象 class DeviceDemo (val name: String, val type: String, val address: String)要展示一个包含这个对象的列表 bluetoothDevices.add(DeviceDemo("bb 9800", "LE", "32:…

Sublime Text4配置C#运行环境

这里写自定义目录标题 前言部署.NET环境Sublime Text4配置C#编译环境1. 下载插件 运行测试 前言 今天把家里的9年前的远古神机搬了出来&#xff0c;重装了个win7的精简版&#xff0c;本打算装个VScode测试一下是否能写C#代码&#xff0c;结果是可以的&#xff0c;但&#xff0…

Qt 设置隐式加载dll路径

在c++中DLL的加载方式有两种,显式加载和隐式加载。 隐式加载 在程序从开始运行时,就会按照系统中一定的搜索路径,寻找动态库,找到就自动加载它,才能成功运行程序,这些步骤,是系统自动完成的。 显示加载 我们对动态库的调用,是在代码中直接使用LoadLibrary,或其他加载函…

基于springboot+vue的大型商场应急预案管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Flask基础学习3

参考视频&#xff1a;41-【实战】答案列表的渲染_哔哩哔哩_bilibili flask 实现发送短信功能 pip install flask-mail # 安装依赖 我这里用登录的网易邮箱获取的授权码&#xff08;登录QQ邮箱的授权码总是断开收不到邮件&#xff09;&#xff0c; # config # config mail MAI…

【智能车入门:pcb版】(蓝牙遥控、超声波避障、红外循迹)

实现最简单的蓝牙遥控、超声波避障、红外循迹&#xff09; 总览项目获取 本篇是对 上一篇博客的改进&#xff0c;上一篇博客使用面包板&#xff0c;看起来很乱&#xff0c;春节结束之后嘉立创免费打板恢复&#xff0c;板子到了之后进行焊接测试&#xff0c;相较于使用面包板&a…

神经网络系列---激活函数

文章目录 激活函数Sigmoid 激活函数Tanh激活函数ReLU激活函数Leaky ReLU激活函数Parametric ReLU激活函数 &#xff08;自适应Leaky ReLU激活函数&#xff09;ELU激活函数SeLU激活函数Softmax 激活函数Swish 激活函数Maxout激活函数Softplus激活函数 激活函数 一般来说&#xf…

Python入门必学:单引号、双引号与三引号的差异与应用

Python入门必学&#xff1a;单引号、双引号与三引号的差异与应用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望得…