Skip to content

总结

下单接口实现问题

下单接口并发提升严谨性其实还不怎么够,存在以下问题:

  1. 异步消息队列没有引入,导致库存放内存的性能提升方案还有漏库存的问题。
  2. 40001 错误没有彻底解决。
  3. 优惠卷异常 、积分不够等异常测试没有。
  4. 对下单所涉及的表简化了不少字段。

但若作为提升TPS性能方法的实验验证,对于真实下单接口具有参考意义。

性能的进一步提升

在做基于代码层面的提升时,还需要搭建 OpenTelemetry 可观测性平台,对数据库、缓存、Web服务资源使用情况做一个全方位的观测,提出性能瓶颈假设,验证它,最后才是想办法提升。否则,很多时候会想当然,事倍而功半。

运维常见问题

这里会收集一些常见的运维相关问题。

单实例生产部署

单实例并不意味着就部署一个服务,可部署多个通过LB分流,若升级则通过LB将流量转移至新实例上,旧实例流量清零。

至于密钥、队列,也可以慢慢引入微服务的解决方案,为微服务做准备。

Redis

  1. 故障恢复会出现什么? Redis 是先改内存后写日志,极端情况下主节点挂掉,需要从节点顶上的时候,会存在数据丢失 or 脏数据 的情况,从而触发超卖现象。

需要做库存流水(简单做就放在订单表字段中),在监测到故障时,依据库存流水+订单对账进行回补。RocketMQ 的事务消息就很适合做此类事情。

  1. Redis Cluster Function/Script 只支持所有key值在同一台Redis节点上运行。 Redis 哨兵模式。或者每次执行 lua 脚本只带有一个key 或加hashtag,强制相关key都在一台实例上运行。

数据库

1. 读写分离后读延迟?

读延迟来自于同步策略为异步,主节点改写数据负载过高,导致同步至从节点数据延迟。

解决方案:

  1. 数据库访问中间件+动态配置 将读请求路由至主库,但增加主库压力。
  2. 同步策略为强同步复制,但性能会降低。
  3. 分布式数据库,相比单实例,会小幅度增加读写延迟,提升吞吐。
  4. 业务服务将最新的数据打入备份,例如: Redis set + expire(类似订单这种,短期内用户只会有1条新增,若可能多条,需要用到 hmap + lua 脚本做map key 过期)。

2. 分库分表?

引入 shardingJDBC 去做,要根据业务决策考分库分表策略,避免数据倾斜和数据热点,且分库需要引入分布式事务解决方案,例如Seata。

若都用MySQL or PG,更省心的应该考虑分布式数据库的解决方案,或者走SQL代理中间件 or 框架。例如 Seata 是分布式事务框架。

队列

  1. 队列消息堆积? 无非就是堵与疏; 堵:生产者少生产,或过滤无效消息。 疏:队列扩容,消费者扩容。

后续

关于性能,还缺少最最最重要的一环:硬件对性能的影响。这个看后面有无机会实践一下。

还有最后的最后啰嗦一下:单机性能其实已经满足很多很多的业务需求,若不考虑代码工程师的因素,请尽量将硬件配置拉满后、引入异步队列后,再去考虑微服务。

微服务所带来的高吞吐收益,大部分中小型公司并不一定能发展到它兑现之日。