我一直有一个疑问,看过一些秒杀代码,类中都会有一个 hashmap 来存储当前某个产品的库存,进入方法的时候获取对应商品的库存,如果够的话就执行之后的代码,如果不够的话就去库或者 redis 继续取。伪代码如下
private HashMap map = new HashMap(); /** * 库存判断 */ public void preHandle(int id) { //判断 map 中的数量 if(Integer.parseInt(map.get("id").toString())<1){ //获取库中的数量,并 put 到当前的 map 中,假定 result 为库中获取到的数量 int result = 10; //如果数量>0 ,则执行下单逻辑 if(result>0){ order(); }else { //抛出库存不足的异常 } } //执行下单逻辑 order(); } public void order(){ //订单逻辑 }
那如果现在我有 3 台机器,其中两台中的 map 中的 id 为 1 的商品数量为 0 了,只有一台 map 中 id 为 1 的数量为 10 。我是如何确保对应访问的流量是对应到有余量的服务上的呢
![]() | 1 7911364440 2022-09-21 14:54:15 +08:00 本地缓存只能在单机上用 |
2 lmshl 2022-09-21 15:02:24 +08:00 ![]() 鉴于秒杀系统的流量,没必要去平衡这点差异,还没等你把流量转发给有余量的进程上去,那点余量就已经被别人秒掉了。 |
3 bootvue 2022-09-21 15:03:30 +08:00 分布式缓存 分布式锁 |
4 lmshl 2022-09-21 15:04:27 +08:00 ![]() 如果你真的对”正确答案“感兴趣的话,可以了解一下什么是《位置透明( Location Transparency )》 https://doc.akka.io/docs/akka/current/general/remoting.html 它是分布式系统中的概念 |
![]() | 5 wolfie 2022-09-21 15:04:54 +08:00 ![]() 没请求到 有库存的实例上,算用户倒霉。下一个。 |
7 hytex OP @7911364440 单机、秒杀。 这两个词放在一起总感觉有点违和。 |
8 wdwwtzy 2022-09-21 15:32:40 +08:00 没懂,假设 3 台机器,真实库存是 100 ,那这个 map 存 100 还是 33 ? 100 的话那不就超卖了,33 的话还可以理解…… |
![]() | 9 oceanthe1h 2022-09-21 18:08:15 +08:00 为 0 了不应该先去 Redis 里找吗,为什么要把流量路由走呢 |
10 ailer 2022-09-21 20:43:38 +08:00 via Android 这个 map 是减轻 Redis 压力的吧?难道不是一种缓存措施吗? |