最近在做选房程序的优化工作,用到了 Nginx 负载均衡和 redis 分布式锁,特此分享一下。
业务场景:开学前新生集中选房。
集中选房涉及几千甚至更高的的并发量,之前的程序是单机部署,用 ReentrantLock 锁住方法,相当于把并行改成串行,效率很低。并发量大的时候,服务器还有崩溃的可能。优化的方案是做 Nginx 负载均衡,将同一份代码部署在多个服务器上,减轻单个服务器的压力。但是分布式部署后,又遇到了新的问题,两个学生有可能选择到同一个床位,这会导致 ReentrantLock 锁不起作用,所以又找到了分布式锁的实现,redis 就是其中一种。下面具体说明。
Nginx 负载均衡
话不多说,先看代码。
对,负载均衡就是这么简单!在 upstream 中配置代理服务器组,location 的 proxy_pass 配置成upstream 设置的组名。请求来了,Nginx 将会轮询指定 upstream 中的服务器来处理。upstream 中的 server 还可以增加参数,最常用的是 weight,指定这台服务器的权重,默认为 1。哪台服务器性能好,把它的权重设大一点,能者多劳。示例如下
redis 分布式锁
分布式锁的实现方式有三种:数据库,缓存和 zookeeper ,我们项目中有 redis ,所以我选择了用redis 实现。原理简单来说就是用一个 key 做锁,set 这个 key ,成功就是获得了锁,否则就失败。解锁的时候删除这个 key,并且判断 value 是不是当时设置的值,相等才删除,防止别的线程强制删除当前的 key 来获得锁。代码实现如下
后续问题
用分布式锁只解决了多个线程不能同时访问同一个资源的问题,如果多个线程访问不同的资源呢。比如服务器同一时间只能处理 50 个请求,但是一下来了 500 个,如何处理呢?我目前想到的是用 MQ 来排队,实现了再写一篇吧。
参考文档
http://blog.csdn.net/xyang81/article/details/51702900
http://www.importnew.com/27477.html
领取专属 10元无门槛券
私享最新 技术干货