Skip to content
DAILY QUOTE

“ ”

(1)搭建服务集群并实现负载均衡

首先,在IDEA中启动两个SpringBoot程序,一个端口号是8081,另一个端口是8082(指定VM参数-Dserver.port=8082),模拟服务集群。

修改nginx.conf,在Nginx中配置负载均衡:

浏览器访问Nginx服务器(8080端口),nginx监听到8080带/api的请求,就会反向代理到backend,backend就会负载均衡到8081和8082端口。

(2)一人一单的并发安全问题

准备两个接口,两个接口的authorization相同确保两个接口是同一个用户发出,用于模拟集群下的用户重复下单。

这里虽然两个服务拿到的userId相同,但是仔细观察引用地址已经不再相同。锁不住查询订单都是0,造成集群环境下的一人一单超卖问题。

  • 有关锁失效的原因分析 每个Java对象在诞生时,底层都天生自带一个叫Monitor的隐式结构,当线程遇到synchronized时,它会去尝试获取这个对象的Monitor。synchronized只能保证单JVM多线程之间的互斥,由于多个tomcat节点的存在,每个tomcat都有一个自己的JVM,每个JVM都有自己的堆栈,方法区和常量池,在Java中,每一个对象都可以是一把锁。一个JVM内部可以存在成千上万、甚至上亿把,在JVM内部是一个锁监视器,多个JVM就有多个锁监视器,于是让原本本地互斥进行的线程变成了并行执行,就会发生并发安全问题。在这种情况下,我们就需要使用分布式锁(跨JVM锁、跨进程锁)来解决这个问题,让多个JVM只能使用同一把锁。