
商城类项目通用技术
文章平均质量分 75
埃泽漫笔
OceanBase开源项目ODC(OceanBase Developer Center)的核心贡献者,Github地址:https://github.com/oceanbase/odc,希望大家能赏脸支持下我们OceanBase公司的开源项目,点亮一颗小星星就行。
Maven中央仓库OceanBase开源组件 https://central.sonatype.com/artifact/com.oceanbase/db-browser 和 https://central.sonatype.com/artifact/com.oceanbase/ob-sql-parser 的核心贡献者。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
统一状态机设计
状态机用于描述一个系统在不同状态之间的转换和行为,是状态模式的一种具体应用。状态机是一种抽象的计算模型,它包含有限个状态和转换规则,用于描述系统在不同状态下如何响应输入以及在不同输入下如何进行状态转换。在我们日常开发中,我们提到的状态机基本都是有限状态机,用于解决状态相关的问题。有限状态机可以通过状态转换和事件触发来描述程序的行为和状态迁移。状态(States):代表系统可能处于的各种状态,例如 "已下单"、"已支付"、"已发货" 等。原创 2025-04-19 23:34:32 · 416 阅读 · 0 评论 -
DDD 实践
我们的项目没有完全按照 DDD 的方式来做,因为其实 DDD 在业内用的也不多,并且大家也没有一个统一的共识,有人推崇,有人反对。但是我们还是从 DDD 中吸取了一些精华在使用的,比如分层架构、充血模型、事件驱动以及设计模式等等。原创 2025-04-19 22:50:36 · 258 阅读 · 0 评论 -
基于BloomFilter快速检查用户名重复
布隆过滤器是一种数据结构,用于快速检索一个元素是否可能存在于一个集合(bit 数组)中。它的基本原理是利用多个哈希函数,将一个元素映射成多个位,然后将这些位设置为 1。当查询一个元素时,如果这些位都被设置为 1,则认为元素可能存在于集合中,否则肯定不存在。所以,布隆过滤器可以准确的判断一个元素是否一定不存在,但是因为哈希冲突的存在,所以他没办法判断一个元素一定存在。只能判断可能存在。原创 2025-04-18 23:09:19 · 427 阅读 · 0 评论 -
策略模式+工厂模式
策略(Strategy)和工厂(Factory)是两种常见的设计模式,它们在不同的设计情景下可带来不同的好处这两者也可以结合使用,以便在软件设计中提供更灵活且可维护的解决方案。原创 2025-04-18 23:01:34 · 542 阅读 · 0 评论 -
自己实现TCC方案解决普通交易环节订单和库存的一致性
TCC(Try-Confirm-Cancel)是一种基于业务补偿的分布式事务解决方案,核心思想通过三个阶段保证分布式事务的一致性:1.Try(尝试)各参与服务预执行业务检查(资源预留),如库存冻结、账户余额预扣等2.Confirm(确认)所有Try成功时,协调者触发Confirm操作,各服务正式提交事务(如实际扣减库存、划转金额)。3.Cancel(取消)任一Try失败时,协调者触发Cancel操作,各服务回滚Try阶段的预留资源(如解冻库存、返还预扣金额)。原创 2025-04-17 23:39:12 · 1126 阅读 · 0 评论 -
引入事务表解决自实现TCC方案的空回滚和悬挂问题
(这里之所以是CANCEL_AFTER_TRY_SUCCESS而不是CANCEL_AFTER_CONFIRM_SUCCESS,是因为这个case就是盲盒模块confirm成功,但是订单模块confirm失败,然后进行的CANCEL,如果两个模块都CONFIRM成功,那就没有cancel啥事儿了。怎么解决呢,其实悬挂主要是因为TRY的时候无脑try,而我们只要在try的时候检查选,是否发生过cancel,如果发生过,就直接不try了就行了。SEATA的TCC的方案中,存在着空回滚和悬挂的问题。原创 2025-04-17 23:32:56 · 1187 阅读 · 0 评论 -
基于 Seata 的事务钩子+定时任务保障支付成功后上链的一致性
一旦出现网络延迟,中断,或者外部平台的不可用,就可能会导致整个事务回滚,更重要的是,即使我们做了分布式事务,用了AT模式,但是外部平台是无法回滚的,只有我们自己的数据库才能一起回滚,这里借助了seata的TransactionHook,这是个事务回调,他可以在事务的commit、rollbak等动作执行的时候,回调对应的方法。当然,调链服务,或者上链操作,有可能也会失败,只不过这种失败的概率就比较低了,我们只需要再引入一个定时任务针对失败的重试就可以了。但是第六步,我们并没有放到分布式事务中,原因是什么?原创 2025-04-16 23:34:28 · 461 阅读 · 0 评论 -
基于Seata分布式事务实现支付环节的数据一致性
那么,我们如何保证这个过程中的一致性呢?这里我们用到了seata的分布式事务,用的是AT模式,之所以用这个模式,是因为他的侵入性低,性能也不差。在项目中接入了seata之后,其实使用seata的AT模式还是比较简单的,只需要在事务发起处加一个,这样seata就会开启一个全局事务,就会通过和我们搭建好的seata服务端进行交互,进行整个分布式事务的协调。:事务协调器,负责管理全局事务的生命周期,包括开始事务、提交事务和回滚事务。:事务管理器,定义事务的范围,负责开启和结束全局事务。原创 2025-04-16 23:27:56 · 768 阅读 · 0 评论 -
TTL解决线程池中无法传递 ThreadLocal 的问题
而我们的回调方法需要知道支付的一些参数,要不然他没办法做回调的,比如我要知道支付单号吧,要不然我回调的时候怎么知道哪笔成功了呢?在他实现的接口PayChannelService中定义了两个方案,分别是 pay 方法和 notify 方法,一个是调外部渠道发起支付的,一个是接收外部渠道的回调消息的。而我们的 notify 定义的时候,入参是HttpServletRequest,想要把它构造出来那可太麻烦了,于是我就想了个办法,用 TTL 来传递参数。这样就实现了在线程池中的共享参数的传递。原创 2025-04-15 23:34:10 · 293 阅读 · 0 评论 -
微信支付对接
其他参数:https://pay.weixin.qq.com/docs/partner/apis/partner-native-payment/partner-jsons/partner-native-prepay.html。详细文档:https://pay.weixin.qq.com/docs/partner/apis/partner-native-payment/payment-notice.html。wx_cert.pem 微信平台证书绝对路径,证书需要通过接口获取,请参考 v3 文档。原创 2025-04-15 23:16:23 · 1120 阅读 · 0 评论 -
重复支付问题如何解决
那么一旦他成功了,就意味着同一笔订单,微信、支付宝都支付成功了,这就发生了重复支付的问题。那么也就说,如果用户针对同一笔订单,换了一个支付方式的话,比如之前用微信、现在改用支付宝,那么就可以重新发起一次新的支付了。3.1、如果订单状态为未支付成功,说明当前是第一次支付成功,则把订单推进到已支付成功,并记录当前的渠道和渠道流水号。还有一种多付的场景,那就是用户已经尝试支付的时候,支付单还未失效,然后去微信支付了,但是支付。在生成支付链接的时候,我们是做了幂等控制的,严格的遵守了"一锁、二判、三更新"的。原创 2025-04-15 00:00:23 · 444 阅读 · 0 评论 -
基于主动+被动组合方式实现订单的关闭
这里用了虚拟线程,发起关单操作,这里通过异步实现,不阻塞主线程,主线程直接返回告诉用户订单状态无法支付即可,等他再次刷新时,异步线程执行完了,这个订单也就被关闭了。我们选择了一种相对轻量并且也比较可靠的方案,那就是 XXL-JOB 定时任务,并且为了减少 XXL-JOB 关单的延迟问题,我们同时引入了被动关单的逻辑。所谓被动关单,就是说当用户想要操作这个订单的时候,我们去检查下是不是已经超时了,如果超时了,并且状态还不是已关闭的话,那就执行一次关单操作。这里为啥就不是异步而是同步了呢?原创 2025-04-14 23:48:07 · 165 阅读 · 0 评论 -
基于SpringEvent+XXL-JOB实现订单确认自动推进
同时我们定义一个事件的监听器,用来处理这个事件@Component@Autowired@EventListener(OrderCreateEvent.class)表示接收并处理OrderCreateEvent事件@Async("orderListenExecutor") 表示将使用名称为orderListenExecutor的自定义线程池来异步执行该方法。原创 2025-04-10 22:06:27 · 936 阅读 · 0 评论 -
全局唯一订单号生成(分布式ID)
其中系统标识码用于区分具体是什么业务(如交易订单、库存、积分等),表下标为了兼容分库分表的场景,序列号采用雪花算法生成。这里的雪花算法,采用IdUtil.getSnowflake实现的。为了生成一个这样一个全局的订单号,我自定义了一个分布式 ID 生成器,其中包含了三部分内容,分别是系统标识码、表下标以及序列化。业务码用来区分具体的业务,如交易订单、支付单等,然后雪花算法用来保证唯一性,分表信息用来实现分表后的订单号查询。在我们的项目中,我们需要定义一些全局唯一的 ID,比如订单号,支付单号等等。原创 2025-04-10 21:46:29 · 317 阅读 · 0 评论 -
基于InventoryHint实现库存的热点扣减
当我们是使用等hint标记了一条SQL之后,就相当于告诉MySQL内核,这行可能是热点更新。于是,MySQL的内核层就会自动识别带此类标记的更新操作,在一定的时间间隔内,将收集到的更新操作按照主键或者唯一键进行分组,这样更新相同行的操作就会被分到同一组中。为了进一步提升性能,在实现上,使用两个执行单元。当第一个执行单元收集完毕准备提交时,第二个执行单元立即开始收集更新操作;当第二个执行单元收集完毕准备提交时,第一个执行单元已经提交完毕并开始收集新一批的更新操作,两个单元不断切换,并行执行。原创 2025-04-10 21:30:49 · 1007 阅读 · 0 评论 -
秒杀方案概述
4、还有就是我们其实在后端,也就是网关这一层也做了个限流,我们的经验是根据我们系统的承载能力,在结合本次秒杀的藏品数,进行精准限流,限制同一个藏品的同时下单流量。预扣减通过 Redis 做一些流量的过滤,利用他的单线程、高性能机制,限制只有一部分用户可以"下单成功",其他用户则被拦住。其实,我们的流量并不是都是后端服务在抗的,因为一方面是没必要,另外一方面是成本高,所以其实我们在前面还做了很多事情。2、秒杀高峰期有验证码,有一些明星的周边这种藏品,甚至还有一些和明星有关的问题,要回答对才能下单。原创 2025-04-10 21:16:59 · 493 阅读 · 0 评论 -
责任链模式实现校验
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,可以通过将一系列处理器按顺序链接起来,使得每个处理器都有机会处理请求,从而实现请求的传递和处理。原创 2025-04-10 20:42:53 · 374 阅读 · 0 评论 -
基于ThreadLocal传递token
同时,这个 token 我们也会当作订单创建时候的幂等号来用,一方面他是唯一的,可以帮我们做幂等判断,另外借助他也能实现 Redis 库存和订单的一致性核对。但是 token 的传递是在 Header 中的,在 tokenFilter 中校验完成后,Redis 中的 token 就删除了。在我们的项目中,为了避免订单的重复下单,我们用了 token 的机制,这个 token 是用户访问页面的时候获取到的。然后再做 token 校验的时候把 token 放到这个 tl 中,如以下代码的第15行。原创 2025-04-09 23:59:08 · 243 阅读 · 0 评论 -
基于Redis的ZSET实现用户邀请排行榜
假设现在的时间戳是1680417299000,除以1e13得到0.1680417299000,再加上一个固定的分数(比如10),那么最终的分数就是10.1680417299000,可以将它作为zset中某个成员的分数,用来排序。前面的实现中,如果分数相同,那么排序的结果是不确定的,那么如果我们想要实现多维度排名,即先按照分数排,分数相同的话按照上榜时间排,如何实现呢?在我们的项目中,有用户的邀请功能,每一次邀请别人注册,会有一定的积分,然后我们同时提供了一个排行榜的功能,可以基于这个积分进行排名。原创 2025-04-05 17:18:19 · 866 阅读 · 0 评论 -
用户信息的缓存设计
用户信息是一个非常基本的信息,很多地方都需要查询用户信息,但是用户信息其实变化并不频繁,所以为了提升性能, 我们针对用户信息做了缓存。原创 2025-04-05 17:02:02 · 474 阅读 · 0 评论 -
自定义 TypeHandler 实现隐私数据自动加解密
GCM需要AES密钥使用256位AES密钥随机IV初始化向量(IV)的作用是确保即使多次用同一密钥加密相同数据,加密后的数据也是唯一的一个12字节的数组来存储IV生成逻辑// 生成AES密钥// 使用256位AES密钥// 输出 Base64 编码的字符串// 生成随机IV// GCM推荐的IV长度是12字节// 输出 Base64 编码的字符串// 生成AES密钥// 使用256位AES密钥// 输出 Base64 编码的字符串。原创 2025-04-05 16:44:37 · 399 阅读 · 0 评论 -
用户鉴权设计
我们根据用户的状态/角色分成了以下几种:1、未登录用户2、未实名认证用户3、已实名认证用户4、管理员用户5、已被冻结用户权限的具体控制管理如下:1、未登录用户可以查看商品无法查看个人信息不能下单2、未实名认证用户可以查看商品可以查看/操作个人信息不能下单3、已实名认证用户可以下单不能管理商品4、管理员用户啥都能干管理商品5、已被冻结用户不能下单。原创 2025-04-04 22:51:15 · 347 阅读 · 0 评论 -
Gateway网关设计
在如今的SpringCloud生态中,SpringCloud Gateway是一个至关重要的组件。Spring Cloud Gateway 是一个在 Spring 生态系统中建立的 API 网关,网关的作用就是提供统一接入,意味着所有的流量都需要先经过网关,然后再由网关转发出去。原创 2025-04-04 22:01:57 · 993 阅读 · 0 评论 -
统一认证的简单实现
我们的项目是一个分布式的项目,每一个模块的话其实都需要做鉴权,就是判断下是不是用户已经登录了,查看的信息是不是属于这个用户的。而为了方便,我们做了统一的认证,也就是说可以在一个地方做认证即可。原创 2025-04-04 21:52:21 · 340 阅读 · 0 评论