请求解析分布式系统中类内禁用static实例的原因及示例
为啥类里别用static实例?用示例给你讲明白
先给你举个实际场景的例子,你一看就懂:
假设你做了个在线商城,想用代码统计总下单数,要是图省事用static变量来存,代码大概是这样:
public class OrderCounter { // 用static变量存总下单数 public static int totalOrders = 0; // 新增订单时计数+1 public void addOrder() { totalOrders++; } // 获取当前总订单数 public int getTotalOrders() { return totalOrders; } }
现在你的商城用户变多,单台服务器扛不住,搞了两台服务器A和B组成集群,用户请求会被随机分到A或B上。
问题1:数据天然不一致
- 早上刚启动,A和B的
totalOrders都是0; - 用户1的请求分到A,下单后A的
totalOrders变成1; - 用户2的请求分到B,下单后B的
totalOrders变成1; - 这时候用户查总订单数,请求到A就显示1,请求到B也显示1,但实际总共有2单,数据已经对不上了。
问题2:服务器宕机直接丢数据
要是这时候服务器A突然挂了,A内存里存的totalOrders(值是1)直接就没了。之后所有用户请求都只能到B,查出来的总订单数永远是1,但实际已经有2个订单了,整个应用的状态彻底混乱,用户看到的数据全错了。
核心原因
static变量是存在单个服务器进程的内存里的,集群里每台服务器的static数据都是独立的,互相不共享;而且服务器一宕机,这台机器的内存数据直接清空,没法恢复。
所以真正生产环境里,这种需要共享、持久化的数据,得存在Redis、数据库这种所有服务器都能访问的共享存储里,不能用static实例存。
内容的提问来源于stack exchange,提问作者Aaquib Jawed
相关产品推荐
相关产品推荐

