电商系统,核心通用架构案例设计方案浅析
一、用户系统案例设计
1、用户信息的存储方案
如果数据不多,一张表可以存储。
数据多的话就考虑异地多活(北京、广州)。
异地多活涉及数据的同步,使用CDC。
2、用户注册确保唯一
单表、主从:通过数据库唯一索引。
多活注册保唯一:
1、第三方登录绑定(比如用户扫码微信登录,如果已经绑定微信则属于已注册状态,可以保证唯一)
2、手机号发短信验证码保证唯一(注册前发送验证码,输入验证码通过注册,相当于短信平台做了唯一性)
3、通过中间件(redis)保证唯一
3、用户数据合并方案
基于版本/时间戳的合并,新数据覆盖旧数据。
4、用户敏感信息加密存储
对称加密、非对称加密、散列加密、混淆、编码、压缩。
需要解密出结果的,就用对称加密(效率高)、非对称加密(效率低)。
不需要解密出结果的,比如密码,就用散列加密(比如md5)。
查询的话,加密后查询,但是无法模糊查询。
如果要模糊查询,模糊查询的部分不要加密(比如身份证)。或者将数据拆开存储,每个数字单独加密存储。
5、数据传输安全性
使用https。
数据进行签名+盐,可以保证不被人改
。
6、多用户数据隔离性
比如订单,A用户只能查询A用户的,B用户只能修改B用户的。
可以考虑对查询出来的数据,进行创建人的判断,如果创建人不是当前登录用户,则操作非法。
7、防止恶意注册
验证码(手机、图形验证码、人机识别、人脸、IP频率)
黑名单(IP)
实名(保险、银行、医疗、政府等单位)
审核(很少,一般对公会做审核,政府部门)
8、用户好友关系存储方案
用户表(User):存储用户的基本信息,用户ID、昵称、头像、性别、年龄等。
好友关系表(Friendship Tible):存储好友关系,包括好友关系ID、用户ID和好友ID。
关注关系表(Following Table):存储用户的关注关系,包括关注关系的ID、用户ID和关注对象ID。
粉丝关系表(Follower Table):存储用户的粉丝关系,包括粉丝关系的ID、用户ID和粉丝ID。
好友关系的优化:
1、分库分表(先分库、再分表)
按照用户ID进行分库:将不同用户的好友关系数据存储在不同的数据库中,这样可以提高查询效率和并发性能,减少单库的压力。
按照好友关系ID进行分表:将同一用户的好友关系数据拆分到多个表中,可以提高单表的读写性能。
2、加缓存
9、用户登录token方案
session(服务端key + value,客户端保存key)
Token(jwt)
10、会员优先处理设计
可以每个会员等级设置一个队列,每次优先取最高等级会员队列的数据进行处理,处理完成之后再从头取。
或者设置一个队列,取的时候先按照会员等级排序。
二、网关系统设计
1、网关的功能
路由转发:将来自客户端的请求,按照预先定义的路由规则进行转发,使请求能够到达正确的后端服务。包括:请求的地址、方法、参数等信息。
协议转换:支持多种协议,如HTTP、Websotket、gRPC等,并进行协议转换。
安全控制:根据定义的策略,对请求进行安全控制,比如请求的身份验证、加解密、黑名单、限流、鉴权等。
流量控制:对请求进行限流、熔断、降级等操作,保证系统的稳定性。
缓存:对热点数据进行缓存,减轻后端服务的压力,提高系统的性能。
监控:性能监控。
2、安全控制
鉴权:用户认证(未经授权的访问),权限判断。
加解密:外部加密数据,内部明文调用,扩展https。
黑名单:ip、设备、用户。
限流:计数器。
3、权限模型:RBAC
RBAC(Role-Based Access Control)是一种基于角色的访问控制模型,它可以控制用户对系统资源(一般是对接口)
的访问权限。
1.用户表(User):用于存储用户的基本信息,例如用户ID、用户名、密码等。
2.角色表(Role):用于存储角色的基本信息,例如角色ID、角色名、角色描述等。
3.权限表(Permission):用于存储权限的基本信息,例如权限ID、权限名、权限描述等。
4.用户角色关联表(ser_Role):用于记录用户与角色之间的关联关系,例如用户ID、角色ID等字段。
5.角色权限关联表(Role Permission):用于记录角色与权限之间的关联关系,例如角色ID、权限ID等字段.
基于组织、岗位、个人的数据权限,最好是在业务表加上对应的id,就需要对查询条件加上对应的条件。
(业务数据如果也参与RBAC,就会很臃肿)
即:资源放RBAC,具体数据权限放在业务系统。
4、数据安全
对称加密、非对称加密、散列、签名、https等。
5、黑名单、白名单
黑名单不允许访问,白名单允许访问。
存储到redis中。
识别1秒内访问超过10次的IP,并自动添加到黑名单。(可以用消息队列、钩子、轮询、长连接、zk)
6、流量控制
限流:限制客户端在特定时间内发起的请求数量。
限流的依据:
IP:根据客户端的P地址进行限流,这种方式可以防止单个!P地址的流量过大,导致服务不稳定。但这种方式可能误伤同一|P下的多个用户,比如公司内网、公共Wi-Fi等。
设备:应用或客户端:根据应用ID、客户端ID或其他应用标识进行限流。这种方式可以为每个应用或客户端分配独立的限流配额,避免恶意应用或客户端影响其他正常应用。
用户:根据用户ID、用户名或其他用户标识进行限流,这种方式可以为每个用户分配独立的限流配额,更加公平。但需要在网关层实现用户身份识别和认证。
API接口:根据清求的API接口进行限流。这种方式可以为不同的AP!接口分配不同的限流配额,确保关键接口的可用性,但需要维护API接口的限流配置。
地理位置:根据客户端的地理位置进行限流。这种方式可以为不同的国家、地区分配不同的限流配额,满足法规要求或业务需求。
请求方法:根据请求的HTTP方法(GET、POST等)进行限流。这种方式可以为不同的请求类型分配不同的限流配额,确保关键操峰的可用性。
熔断:当后端服务出现异常或响应时间过长时,熔断器会拦截请求,直接返回错误或默认值,防止请求继续传递到后端服务。熔断器可以根据一定的策略自动恢复,例如在一段时间后重试或者根据成功率进行判断。
降级:根据系统的负载情况,动态调整提供的服务质量。例如,当系统压力较大时可以关闭一些非关键功能,或者返回简化的响应数据。降级可以手动触发,也可以根据监控数据自动触发。
负载均衡:将请求分发到多个后端服务实例,以确保每个实例的负载均衡。负载均衡算法包括轮询、随机、加权轮询、最少连接数等。负载均衡可以在网关层实现,也可以通过DNS、负载均衡器等其他组件实现。
请球拦截:请求非法,不要蔓延到后端服务。
优先级调度:根据请求的优先级,动态调整请求的处理顺序。例如,可以为付费用户、实时性要求高的请求分配更高的优先级。优先级调度可以结合队列、堆等数据结构实现。
三、电商订单系统设计
1、涉及模块与功能
涉及功能:购物车、下单、支付、配送、售后跟踪等。
订单创建,订单支付,订单-库存管理,订单配送,订单查询,订单修改与取消,售后服务。
2、高可用方案
提高组件的可靠性(公有云)。
冗余设计&容错(主从、故障切换)。
负载均衡&故障切换。
微服务架构:熔断/降级。
监控与告警:CPU、内存、磁盘、网络,电话、短信通知。
过载保护:限流。
异步,解耦,削峰(消息队列)。
缓存,预热(缓存是数据库的一种冗余)。
3、抢单系统
防止超卖,可以使用Redisson的信号量。
4、订单超时关闭设计
1、定时任务(不推荐)
2、JDK 延迟队列 DelayQueue(不推荐)
3、redis 过期监听(不推荐)
4、Redisson 分布式延迟队列:RDelayedQueue(推荐!)
5、RocketMQ 延迟消息(推荐)
6、RabbitMQ 死信队列(可以用)
5、提交订单接口做了哪些事?
幂等,库存、营销、优惠券、支付、回调……
订单ID
(唯一性、可读性、安全性、扩展性……)
(UUID、自增ID、redis自增、雪花算法、百度的uidgenerator、美团的Leaf)
ID不能被猜出来
6、订单状态的变更
待支付、支付中、已支付、待发货、发货中、已发货、已签收、已完成、申请退款、退货、退款退货中、已退款、已退货、已取消。
注意点:
连贯性,比如说待发货状态只能变为发货中状态,不能变为支付中状态。
排他性,保证并发安全,保证幂等。
异常处理,用分布式事务保证异常下的正常处理。
7、库存扣减方案
下单扣库存,风险点:只下单不付钱。
付款扣库存,风险点:付款后发现库存没了,体验很差。
完美方案:预扣库存。提交订单后,30分钟不付款恢复库存。
安全反作弊:给经常下单不付款的用户拉黑、设置商品每人最大购买数。
8、订单拆单
一次下单多个店铺,需要拆成多个子订单。一次下单多个不同商品,也需要拆单。
梳理好父子订单关系即可,有父订单ID、级别。分成两个表也可以。
9、库存分层
销售层:显示商品库存情况,用户查看商品是否有货
。销售层的数据需要定期从调度层同步保持准确性。(需要做库存的锁定、扣减、回滚
)
调度层:中间层,基于各个仓库的实际库存情况,进行库存的分配和调度。用户下单后需要决定从哪个仓库发货。还用于库存的同步。存数据可以减轻仓库层压力,并且会有数据一致性问题。也可以不存数据
仓库层:管理实体SKU、库存盘点核对、入库出库。
分层问题:一致性问题没法100%保证,并发问题,安全与权限。
为什么分层?
高内聚,低耦合;分离关注点(区分系统边界)
四、商品系统设计
1、SPU(Single Product Unit)用户查询
定义:SPU是一种将不同的产品变种或规格汇总为一个单一实体或产品的标识符,通常用于商品分类和在线商店的产品列表中。
例子:继续以鞋子店为例,不论鞋子的颜色和尺码如何,同一款运动鞋都被视为一个SPU。这意味着无论你销售多少不同颜色和尺码的鞋子,它们都属于同一个SPU,例如:
型号:ABC123(运动鞋的通用型号) 这样,无论你销售多少不同变种的鞋子,它们都被列为同一款产品的不同变种,方便顾客在在线商店中浏览和比较。
综上所述,SKU用于管理单个产品的不同变种,而SPU用于将所有这些变种汇总到一个单一的产品实体中,以便于销售和分类。
2、SKU(Stock Keeping Unit)库存管理
定义:SKU是一种唯一的编码或标识符,用于区分不同的产品变种或规格,通常与库存管理和销售跟踪有关。
例子:假设你经营一个鞋店。你卖同一款运动鞋,但有不同的颜色和尺码可供选择。每个不同的颜色和尺码组合都可以分配一个独特的SKU,例如:
黑色,尺码39:SKU001
白色,尺码37:SKU002
蓝色,尺码38:SKU003
这样,每个SKU代表了特定颜色和尺码的鞋子,使你能够准确追踪库存和销售情况。
表设计:
https://blog.csdn.net/weixin_42057187/article/details/139180929
3、组合SKU
比如桌子和凳子组合,选择1个桌子+4个凳子,同时下单。
如果库房桌子5个,凳子8个,那么这个组合SKU就是2个。
4、SPU编码设计
SPU编码通常包含以下部分:
类别代码:用于表示商品所属的大类别,如服装、电子产品等。
品牌代码:用于表示商品所属的品牌。
系列代码:用于表示商品所属的产品系列。
序列号:用于表示同一类商品的不同型号或版本。
例如,假设我们为一款电子产品指定SPU编码。类别代码为“01”(表示电子产品),品牌代码为“02”(表示品牌B),系列代码为“03”(表示系列C),列号为“0001”。则该商品的SPU编码为:0102030001。
5、SKU编码设计
SKU编码中包含对应商品的SPU编码,以便于关联和查询。
属性代码:用于表示商品的各种规格属性,如颜色、尺寸等。属性代码可以分为多个字段,分别表示不同的属性。
序列号:用于表示同一商品规格的不同批次或生产日期等信息。
例如,假设我们为上述电子产品的某个规格(颜色为红色,尺寸为大)指定SKU编码。属性代码为“01”(表示红色)和“02”(表示大尺寸),序列号为“0001”。则该商品规格的SKU编码为:0102030001-01020001。
6、69码(商品编码)以及校验码的思路
中国大陆生产的商品,都是69开头的,每个商品都是唯一的。
注册与查询网站:http://www.gs1cn.org/
校验码校验思路:
从右向左,将奇数位置的数字相加,然后乘以3。
再从右向左,将偶数位置的数字相加。
将步骤1和步骤2的结果相加,得到一个总和。
找到一个最小的整数(包括0),使其(校验位,即最后一位)与总和相加能够被10整除。这个整数就是校验位。
通过这个计算过程,我们可以得到一个校验位。当条形码被扫描时,扫描设备可以通过使用同样的计算方法检査校验位是否正确。如果计算出的校验位与扫描到的校验位不匹配,那么说明条形码数据可能存在问题,需要重新扫描或者检查数据。总之,69码中的校验位是用于确保条形码数据的正确性和完整性,防止扫描错误和数据传输问题导致的错误。
7、SPU还能做什么功能
评论、搜索、推荐
8、商品类别的设计(自关联,自解释)
category_id:类目ID,是每个类目的唯一标识,通常设为主键。
category_name:类目名称,是用户在界面上看到的类目名字。
parent id:父类目ID,用来表示这个类目的上一级类目。如果这个类目是最顶级的类目,那么这个字段可以为空或者设为0。
level:类目级别,用来表示这个类目在类目层级中的位置。最顶级的类目的级别为1,其下一级的类目级别为2,以此类推。
status:类目状态,用来表示这个类目是否可用。例如,可以设为1表示可用,0表示不可用。
sort order:排序顺序,用来表示在同一级别的类目中,这个类目的排序位置。
用户看到的不一定和配置的一样,有可能会根据季节或热度变化。
自关联设计,并且自解释。
比如父id存储为set类型(111,222,333),参考省市区,111000,111001……
9、商品品牌的设计(关联商品、历史存储)
brand id:品牌ID,每个品牌的唯一标识符,通常设为主键。
brand name:品牌名称,用于显示的品牌名。
brand logo:品牌Logo的URL,用于在页面上展示品牌的Logo。
brand website:品牌的官方网站URL。
brand description:品牌描述,一段简短的文字来描述这个品牌的特点和历史等信息。
brand status:品牌状态,例如,可以设为1表示品牌可用,0表示品牌不可用。
sort order:排序顺序,用来控制品牌在页面上的显示顺序。
与商品关联:一般商品中有个品牌字段,或者使用关联表。
历史变更的存储,重要数据是可以追溯的(修改的话需要保存历史)。
或者根据品牌变更的时间,根据订单时间进行对应的追溯。
或者订单表进行冗余品牌的名称等信息。
10、商品属性的设计
attribute id:属性ID,为每个属性的唯一标识符,通常设置为主键。
attribute name:属性名称,描述属性的类型(如颜色、尺寸等)。
attribute type:属性类型,用于描述属性值的类型,例如文本、数字、日期等。
关联(或许需要一个分类和属性的关联表):category id:分类ID,表示此属性与哪个商品类别相关联。这个字段可以帮助你将相应的属性分配给对应的商品类别。(比如黑色,手机和衣服都有颜色属性)
为了存储每个具体商品的属性值,你可能需要另一个表--商品属性值表(ProductAttribute Value Table)
。这个表可能包含product id(商品ID)、attribute id(属性ID)和value(值)等字段,用于存储每个商品具有的特定属性值。
或者,在商品表中,使用一个大json存储商品的属性
这就意味着,属性不光要跟分类关联,同时,商品也需要跟属性关联
。
11、通用规格设计(区分属性,用于用户搜索、选择)
specification id:规格ID,为每个规格的唯一标识符,通常设置为主键。
specification name:规格名称,例如"屏幕尺寸"、“存储容量”等。
specification values:规格值,一般以字符串数组或者其他形式存储可能的值,例如"32寸”、"64寸"等。
status:状态,表示这个规格是否可用。可以设为1表示可用,0表示不可用。
规格和属性的区别:属性是地基,规格是地基上面的衍生品。也可以在属性表中加一个字段,用于区分是否是规格。
规格最终决定价格、用户搜索,可以参考属性的参考:
12、税率(税率有周期)
税率id、税率名称、税率,国家,地区,是否有效,开始时间,结束时间
。
同时也需要历史记录。
13、生产信息设计
production id:生产信息ID,为每个生产信息的唯一标识符,通常设置为主键。
manufacturer id:制造商ID,关联到制造商信息。
manufacturing date:生产日期。
expiration date:过期日期,如果适用的话,
batch number:批次号,用于识别同一批次的商品。
location:生产地点,可以是具体的工厂或者城市等。
quality control result:质量控制结果,记录该批次商品的质量检测结果。
inspection certification:检验证明,如果有相关的质量检验证明文件,可以记录其文件编号或者链接url。
status:状态,表示该生产信息是否有效或者当前的状态,例如在生产,已完成等。
需要一张生产信息与商品关联表。
14、商品列表功能设计
功能上:
搜索:用ES/Opensearch等搜索引擎,分词过滤、搜索提示和自动完成、搜索结果高亮、搜索历史(存在前端中)、缓存。
过滤:在用户商品列表页,进一步过滤用户的商品范围,对通用结果搜索的第二次筛选。个人权重(喜好)
排序(根据权重)。
商品信息展示(列表、图表)。
推荐(人工智能)。
性能上:
分页&懒加载(滚动加载)
压缩&解压(缩略图)
缓存(缓存一致性)
数据库优化(索引,优化sql,正反范式设计,数据分区,读写分离,分库分表,视图和存储过程-多条sql有关联,上搜索引擎)
CDN
15、商品详情功能设计
减少cookie(减少与服务器的cookie传输,cookie会传输到后端)
图片做压缩(降低像素、色彩)
js、css压缩(删除无效字符、注释、代码语义的缩减)
请求响应压缩(gzip)
减少请求(一次请求多个js、使用雪碧图/精灵图:一张图包含很多图,图片转base64存在css中)
计算能力转移到客户端
CDN
ajax异步加载
缓存(前端缓存cache-control、后端缓存)(文件名、版本号、时间戳来判断是否过期)
预加载(DNS预加载<meta http-equiv="x-dns-prefetch-control" content="on">
)
16、购物车的设计
购物车的存储:客户端(未登录)/浏览器,服务端(登录后)
商品存放购物车后,价格有可能会有变动,下单时需要提醒用户。
五、支付系统设计
1、支付的对接
对账、支付、回调等等。
原文地址:https://blog.csdn.net/A_art_xiang/article/details/144613917
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!