第六章:超市精细化运营——补齐剩余核心知识点

6.1 收银台排队:Redis List模拟队列

超市收银台排队,可以用Redis的List结构模拟一个先进先出的队列。顾客结账时,LPUSH订单号到队列,收银员处理完后RPOP
List底层:当元素少时用ziplist,多时用linkedlist(quicklist)。quicklist是ziplist和linkedlist的结合,每个节点是一个ziplist,节省内存且支持两端操作。
应用场景:除了收银队列,还可以用于异步任务(如发短信),但生产环境更推荐消息队列(因为Redis List不支持消息确认、重试)。不过,对于简单的、允许丢失的场景,List足够轻量。

6.2 会员标签:Redis Set实现精准营销

超市想给会员打标签(如“高消费”、“生鲜爱好者”),用于定向推送。用Redis Set存储每个标签下的用户ID集合。
Set底层:元素全为整数且数量少时用intset(有序数组),否则用hashtable。
集合运算:计算“高消费且生鲜爱好者”的交集,用sinterstore,结果存入新key,后续推送用。
Bitmaps替代:如果标签数量固定且用户量大,可以用Bitmaps(如第1位表示高消费,第2位表示生鲜),占用内存极小。

6.3 店铺附近的人:Redis Geo实现LBS

超市要推“附近门店”功能,根据用户坐标查找最近的门店。
Geo底层:基于Sorted Set实现,将经纬度编码为52位整数(Geohash),作为score存入。
操作geoadd添加门店位置,georadius根据用户坐标查询附近门店(支持距离、排序)。
原理:Geohash将二维坐标降为一维字符串,相同前缀表示邻近区域,通过score范围快速定位。

6.4 超市日活统计:HyperLogLog

运营需要统计每天到店用户数(UV),精确计数可以用Set,但用户量巨大时内存吃不消。
HyperLogLog:用概率算法,占用12KB内存,标准误差0.81%,能统计2^64个元素。
用法PFADD添加用户ID,PFCOUNT统计。多个店铺的日活可以PFMERGE合并。

6.5 库存预警:Redis发布订阅

当某商品库存低于阈值时,通过Redis的发布订阅实时通知店员补货。
发布订阅PUBLISH到频道,所有订阅该频道的客户端接收消息。但消息不会持久化,如果客户端不在线就丢失,适合实时性高但可容忍丢失的场景。

6.6 缓存淘汰策略:当Redis内存满了

超市客流太大,Redis内存告急,需要配置淘汰策略。
maxmemory-policy

  • volatile-lru:从已设置过期时间的key中淘汰最近最少使用的。
  • allkeys-lru:从所有key中淘汰最近最少使用的(常用)。
  • volatile-lfu:从已设置过期时间中淘汰最不经常使用的。
  • allkeys-lfu:淘汰最不经常使用的。
  • volatile-ttl:淘汰即将过期的。
  • noeviction:返回错误(默认)。
    LRU vs LFU:LRU只考虑最近访问时间,LFU考虑访问频率,适合某些热点偶尔访问的场景。
    近似LRU:Redis的LRU是近似实现,随机采样N个key淘汰最旧的,可通过maxmemory-samples调整精度。

6.7 MySQL binlog深入:三种格式

Canal同步数据到ES时,需要理解binlog格式。

  • STATEMENT:记录SQL语句,体积小,但某些语句(如UUID())可能不一致。
  • ROW:记录每行变更,准确但体积大,Canal必须用ROW格式。
  • MIXED:混合模式,默认用STATEMENT,不确定时用ROW。
    ROW格式下的镜像:binlog包含变更前后的完整行数据,可用于数据恢复和异构同步。

6.8 MySQL高可用:MGR(组复制)

超市系统需要更高的可用性,引入MySQL Group Replication。
MGR原理:基于Paxos协议的组通信,多个节点组成复制组,支持多主或单主模式。

  • 多主模式:任何节点可写,需处理冲突检测。
  • 单主模式:只有一个主节点,其他自动选主。
    对比传统主从:MGR自动故障转移,数据强一致,但性能稍差,网络要求高。

6.9 微服务安全:OAuth2 + JWT

超市会员系统需统一认证,用OAuth2颁发token。
JWT结构:header.payload.signature,自包含用户信息,无状态。
认证流程:客户端登录,认证服务验证后返回JWT,后续请求携带JWT,网关解析并转发用户信息。
JWT vs Session:JWT避免Session共享,但无法主动失效(除非用黑名单)。
Spring Security集成:通过OAuth2资源服务器配置,解析JWT。

6.10 全链路压测:模拟双十一

双十一前,对超市系统进行全链路压测,找出瓶颈。
压测工具:JMeter、Locust、阿里PTS。
压测策略

  • 逐步增加并发,观察QPS、RT、CPU、内存、GC。
  • 发现瓶颈后优化(加索引、扩容、调参)。
  • 全链路压测需考虑数据隔离(测试数据不影响线上)。
    影子表:在MySQL中创建同名影子表,压测流量路由到影子表,避免污染真实数据。

6.11 混沌工程:故意搞破坏

为验证系统韧性,引入混沌工程。
工具:ChaosBlade、Litmus。
实验:随机杀死Pod、延迟网络、CPU满载,观察系统是否降级、熔断、恢复。
超市例子:模拟一个订单服务实例宕机,看网关是否自动重试到其他实例,Sentinel是否触发熔断。

6.12 任务调度进阶:DAG工作流

XXL-JOB支持任务依赖(DAG),用于复杂的报表生成流程。
示例:日报生成任务 -> 周报聚合任务 -> 邮件发送任务,依次依赖。
实现:通过任务分片和回调,或使用Apache Airflow这类专业工作流引擎。

6.13 消息队列选型:为什么选RocketMQ

假设超市未来要对接Kafka,需要知道选型依据。

  • RocketMQ:适合电商交易,支持事务消息、延迟消息、死信队列,社区在阿里,Java系友好。
  • Kafka:适合日志、大数据吞吐,分区多副本,但事务支持较弱。
  • RabbitMQ:轻量,支持多种协议,但吞吐量不如前两者。
    选型时考虑:是否需事务、延迟消息、吞吐量、开发语言生态。

6.14 服务网格进阶:Istio流量管理

引入Istio实现更精细的流量控制。
VirtualService:定义路由规则,如10%流量到新版本(金丝雀发布)。
DestinationRule:定义负载均衡、连接池。
故障注入:模拟延迟或异常,测试服务容错。
超市例子:新会员服务上线,只让内部员工账号流量切过去,验证无误后全量。

6.15 Helm:K8s包管理

超市服务越来越多,用Helm统一打包部署。
Chart:包含模板和values.yaml,可参数化配置。
Release:部署到K8s的一个实例。
钩子:在安装、升级时执行特定任务(如数据库初始化)。

6.16 Operator:自动化运维

用Operator管理有状态应用,如Redis Operator、MySQL Operator。
原理:自定义控制器监听CRD(自定义资源),根据期望状态自动调整集群(如故障转移、扩缩容)。

6.17 业务监控:自定义指标

除了基础设施监控,还需监控业务指标(如订单量、销售额)。
实现:用Micrometer埋点,暴露给Prometheus,Grafana展示。
告警:订单量暴跌可能意味着系统故障,触发告警。

6.18 全链路压测数据隔离

压测流量如何识别?
请求头标记:压测工具添加x-request-source: stress,网关识别后将请求路由到影子库。
影子库:在MySQL、Redis中准备影子库/表,所有写操作落到影子区,不影响线上数据。

6.19 设计模式补遗

  • 工厂方法:在Spring中创建Bean。
  • 抽象工厂:用于不同中间件客户端创建(如JedisConnectionFactory)。
  • 建造者模式:RedisTemplate的配置。
  • 原型模式:Bean的作用域prototype。
  • 适配器模式:Spring MVC的HandlerAdapter。
  • 装饰器模式:BufferedInputStream包装。
  • 代理模式:AOP。
  • 外观模式:门面服务封装复杂调用。
  • 策略模式:负载均衡算法。
  • 模板方法:JdbcTemplate、RedisTemplate。
  • 观察者模式:Spring事件监听。
  • 责任链模式:Sentinel的ProcessorSlotChain。
  • 命令模式:Runnable。
  • 状态模式:工作流状态机。
  • 访问者模式:ASM字节码操作。
  • 中介者模式:消息队列解耦。

6.20 JVM细节补充

  • 直接内存:Netty使用DirectByteBuffer,需监控-XX:MaxDirectMemorySize
  • 类加载机制:双亲委派模型,Tomcat打破双亲委派隔离应用。
  • 逃逸分析:栈上分配、同步消除。
  • TLAB:线程本地分配缓冲区,减少锁竞争。
  • GC日志分析工具:GCeasy、GCEasy。

6.21 并发编程补充

  • Fork/Join框架:用于并行计算,如统计所有门店销售数据。
  • CompletableFuture:实现异步编排,如同时调用商品、库存、营销服务。
  • ThreadLocal:存储用户上下文,但需注意内存泄漏(remove)。
  • AQS:AbstractQueuedSynchronizer,ReentrantLock、CountDownLatch等的基础,实现同步状态管理。

6.22 网络协议细节

  • HTTP/2:多路复用、头部压缩,Gateway可开启。
  • gRPC:基于HTTP/2,使用Protobuf,适合内部高性能RPC。
  • WebSocket:用于实时推送(如库存预警)。