仿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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js设计模式:委托者模式

作用: 一个对象可以将一些任务交给另外一个对象去执行,两者执行这个方法的结果是一致的 被委托者去替代委托者完成了某个功能,通常各种服务镜像就是这样的 示例: //npmconst npm {downModules(name){console.log(下载${name}依赖包)}}//mirrornpmconst mirrornpm {src:npm…

如何使用ArcGIS Pro生成等高线

无论在制图还是规划中,经常会使用到等高线,大多数情况下,从网上获取的高程数据都是DEM文件,我们可以通过ArcGIS Pro来生成等高线,这里为大家介绍一下生成方法,希望能对你有所帮助。 数据来源 教程所使用的…

IO 作业 24/2/21

1、使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源 #include <myhead.h> //定义分支线程1 void *task1(void *arg) {int fdr-1;//只读打开被复制文件if((fdropen("./111.txt…

【概率论与数理统计】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱概率论1. 基本概念2. 随机变量3. 分布函数4. 期望与方差 数理统计1. 数据收集与整理2. 描述性统计3. 推断性统计4. 回归分析5. 方差分析 简述概要 概率论与数理统计基础知识 知识图谱 概率论 1. 基本概…

六大设计原则 (SOLID)

一、设计原则概述 古人云: 有道无术,术可求.有术无道,止于术. 而设计模式通常需要遵循一些设计原则,在设计原则的基础之上衍生出了各种各样的设计模式。设计原则是设计要求,设计模式是设计方案,使用设计模式的代码则是具体的实现。 设计模式中主要有六大设计原则,简称为SOL…

python 3D散点图

from mpl_toolkits import mplot3d import numpy as np import matplotlib.pyplot as plt#解决中文乱码和负号不显示问题 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False fig plt.figure() ax plt.axes(projection3d)#构造3个散点向量x1[[…

【Flink集群RPC通讯机制(二)】创建AkkaRpcService、启动RPC服务、实现相互通信

文章目录 零. RpcService服务概述1. AkkaRpcService的创建和初始化2.通过AkkaRpcService初始化RpcServer3. ResourceManager中RPC服务的启动4. 实现相互通讯能力 零. RpcService服务概述 RpcService负责创建和启动Flink集群环境中RpcEndpoint组件的RpcServer&#xff0c;且Rpc…

CSS基础属性

【三】基础属性 【1】高度和宽度 &#xff08;1&#xff09;参数 width&#xff08;宽度&#xff09;&#xff1a;用于设置元素的宽度。可以使用具体的数值&#xff08;如像素值&#xff09;或百分比来指定宽度。 height&#xff08;高度&#xff09;&#xff1a;用于设置元…

小程序端学习

P2 创建Uni-app 分离窗口 一样的Ctrl S P3 细节知识点 创建新的小程序页面

设计模式浅析(六) ·命令模式

设计模式浅析(六) 命令模式 日常叨逼叨 java设计模式浅析&#xff0c;如果觉得对你有帮助&#xff0c;记得一键三连&#xff0c;谢谢各位观众老爷&#x1f601;&#x1f601; 命令模式 概念 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c…

C#知识点-13(进程、多线程、使用Socket实现服务器与客户端通信)

进程 定义&#xff1a;每一个正在运行的应用程序&#xff0c;都是一个进程 进程不等于正在运行的应用程序。而是为应用程序的运行构建一个运行环境 Process[] pros Process.GetProcesses();//获取电脑中所有正在运行的进程//通过进程&#xff0c;直接打开文件//告诉进程&…

解决IDEA搜不到插件

File -> Settings -> Plugins https://plugins.jetbrains.com/ 完成以上操作即可搜到插件

小程序--组件通信

一、父传子 与vue利用props类似&#xff0c;小程序是利用自定义属性&#xff1a;properties // components/my-nav/my-nav.js Component({// 小程序组件默认样式是隔离&#xff0c;addGlobalClass设置为true可允许外部修改样式options: {addGlobalClass: true,// 只要使用到具…

面试经典150题——生命游戏

​"Push yourself, because no one else is going to do it for you." - Unknown 1. 题目描述 2. 题目分析与解析 2.1 思路一——暴力求解 之所以先暴力求解&#xff0c;是因为我开始也没什么更好的思路&#xff0c;所以就先写一种解决方案&#xff0c;没准写着写…

OJ链接——打印从1到最大的n位数

目录 1. 题目描述2. 示例3. 分析思路4. 完整代码 1. 题目描述 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 用返回一个整数列表来代替打印n 为正整数&#xff0c;0 < n < 5 链接在…

mac m1调试aarch64 android kernel最终方案

问题 这是之前的&#xff0c;调试android kernel的方案还是太笨重了 完美调试android-goldfish(linux kernel) aarch64的方法 然后&#xff0c;看GeekCon AVSS 2023 Qualifier&#xff0c;通过 sdk-repo-linux_aarch64-emulator-8632828.zip 进行启动 完整编译的aosp kernnl…

Code-Audit(代码审计)习题记录4-5

4、习题4 题目内容如下&#xff1a; <?php error_reporting(0); show_source(__FILE__); $a $_REQUEST[hello]; eval("var_dump($a);"); 函数解释 $REQUEST — HTTP Request 变量&#xff0c;默认情况下包含了 [$GET]&#xff0c;[$POST] 和 [$COOKIE]的数…

Git合并固定分支的某一部分至当前分支

在 Git 中&#xff0c;通常使用 git merge 命令来将一个分支的更改合并到另一个分支。如果你只想合并某个分支的一部分代码&#xff0c;可以使用以下两种方法&#xff1a; 1.批量文件合并 1.1.创建并切换到一个新的临时分支 首先&#xff0c;从要合并的源分支&#xff08;即要…

S281 LoRa网关助力智慧城市建设的智能交通管理

S281 LoRa网关作为智慧城市建设中的重要组成部分&#xff0c;发挥着关键的作用&#xff0c;特别是在智能交通管理方面。通过连接各类传感器设备和物联网终端&#xff0c;S281 LoRa网关实现了对城市交通系统的远程监控、智能调度和信息化管理&#xff0c;为城市交通管理部门提供…

学习鸿蒙基础(5)

一、honmonyos的page路由界面的路径 新建了一个page,然后删除了。运行模拟器的时候报错了。提示找不到这个界面。原来是在路由界面没有删除这个page。新手刚接触找了半天才找到这个路由。在resources/base/profile/main_pages.json 这个和微信小程序好类似呀。 吐槽&#xf…