# gulimall **Repository Path**: Mrzhugq/gulimall ## Basic Information - **Project Name**: gulimall - **Description**: 谷粒商城后端+谷粒商城前台 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-19 - **Last Updated**: 2022-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, SpringBoot, SpringCloud, SpringCloudeAlibaba ## README # gulimall #### 介绍 商城项目 (运维篇没完成) #### 软件架构 版本:Spring Cloud Hoxton.SR12 + Spring Boot 2.3.12 + Spring Cloud Alibaba 2.2.8.RELEASE 配置,注册中心:Nacos 熔断,降级,限流:Sentinel 分布式事务:Seata 链路追踪:Zipkin + Sleuth 服务接口调用:OpenFeign 服务负载均衡:Ribbon 数据库:Mysql5.7 ORM框架:MyBatisPlus 网关:GateWay 缓存:Redis,SpringCache 分布式锁:Redisson 分布式Session共享:SpringSession 部署:Docker 动静分离,反向代理,负载均衡:Nginx 检索:ElasticSearch 消息队列:RabbitMQ 第三方服务:Alibaba-OSS,Gitee-OAuth2,Alipay #### 数据一致性解决方案 常见解决方案: 1. 双写模式 2. 失效模式 问题:无论是双写模式还是失效模式,都会导致缓存的脏数据,即多个实例同时更新会出事,怎么办 ? 1. 如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加上过期时间,每隔一段时间触发读的主动更新即可 2. 缓存数据+过期时间也足够解决大部分业务对于缓存的要求 3. 如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式 4. 通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。 (业务不关心脏数据,允许临时脏数据可忽略) 总结: 1. 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保证每天拿到当前最新数据即可。 2. 我们不应该过度设计,增加系统的复杂性 3. 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。 该电商系统数据一致性解决方案: 1. 所有缓存都有设置过期时间 2. 失效模式 + 读写锁 (偶尔修改性能不会有太大影响) #### 分布式事务问题 1. seata-AT (适合流量小的事务) 2. 柔性事务+可靠消息+最终一致性方案(异步确保型) #### 消息问题 防止消息丢失: 1. 发送方确认:每一个发送的消息都在数据库做好记录(表:mq_message),定期将失败的消息再次发送一遍 2. 接收方确认:手动ack 防止消息重复: 1. 消费业务接口保证幂等性(状态标识) 2. 使用防重复表,发送消息每一个都有业务唯一标识,处理过就不用处理了 3. rabbitMq每个消息都有redelivered字段,可判断是否是被重新投递过来的 防止消息积压: 1. 上线更多的消费者 2. 上线专门的队列消费服务,将消息先批量取出来,记录数据库,离线慢慢处理