这是一个秒杀系统,即大量用户抢有限的商品,先到先得 用户并发访问流量非常大,需要分布式的机器集群处理请求 系统实现使用Java
来源:互联网 发布:写jquery必须会js么 编辑:程序博客网 时间:2024/05/19 03:46
1、用户请求分发模块:使用Nginx或Apache将用户的请求分发到不同的机器上。
2、用户请求预处理模块:判断商品是不是还有剩余来决定是不是要处理该请求。
3、用户请求处理模块:把通过预处理的请求封装成事务提交给数据库,并返回是否成功。
4、数据库接口模块:该模块是数据库的唯一接口,负责与数据库交互,提供RPC接口供查询是否秒杀结束、剩余数量等信息。
第一部分就不多说了,配置HTTP服务器即可,这里主要谈谈后面的模块。
用户请求预处理模块:
并发队列的选择
Java的并发包提供了三个常用的并发队列实现,分别是:ConcurrentLinkedQueue 、 LinkedBlockingQueue 和 ArrayBlockingQueue。
ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设定一个10大小的数组队列。
ConcurrentLinkedQueue使用的是CAS原语无锁队列实现,是一个异步队列,入队的速度很快,出队进行了加锁,性能稍慢。
LinkedBlockingQueue也是阻塞的队列,入队和出队都用了加锁,当队空的时候线程会暂时阻塞。
由于我们的系统入队需求要远大于出队需求,一般不会出现队空的情况,所以我们可以选择ConcurrentLinkedQueue来作为我们的请求队列实现:
用户请求模块
2、用户请求预处理模块:判断商品是不是还有剩余来决定是不是要处理该请求。
3、用户请求处理模块:把通过预处理的请求封装成事务提交给数据库,并返回是否成功。
4、数据库接口模块:该模块是数据库的唯一接口,负责与数据库交互,提供RPC接口供查询是否秒杀结束、剩余数量等信息。
第一部分就不多说了,配置HTTP服务器即可,这里主要谈谈后面的模块。
用户请求预处理模块:
经过HTTP服务器的分发后,单个服务器的负载相对低了一些,但总量依然可能很大,如果后台商品已经被秒杀完毕,那么直接给后来的请求返回秒杀失败即可,不必再进一步发送事务了,示例代码可以如下所示:
package seckill; import org.apache.http.HttpRequest; /** * 预处理阶段,把不必要的请求直接驳回,必要的请求添加到队列中进入下一阶段. */public class PreProcessor { // 商品是否还有剩余 private static boolean reminds = true; private static void forbidden() { // Do something. } public static boolean checkReminds() { if (reminds) { // 远程检测是否还有剩余,该RPC接口应由数据库服务器提供,不必完全严格检查. if (!RPC.checkReminds()) { reminds = false; } } return reminds; } /** * 每一个HTTP请求都要经过该预处理. */ public static void preProcess(HttpRequest request) { if (checkReminds()) { // 一个并发的队列 RequestQueue.queue.add(request); } else { // 如果已经没有商品了,则直接驳回请求即可. forbidden(); } }}
并发队列的选择
Java的并发包提供了三个常用的并发队列实现,分别是:ConcurrentLinkedQueue 、 LinkedBlockingQueue 和 ArrayBlockingQueue。
ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设定一个10大小的数组队列。
ConcurrentLinkedQueue使用的是CAS原语无锁队列实现,是一个异步队列,入队的速度很快,出队进行了加锁,性能稍慢。
LinkedBlockingQueue也是阻塞的队列,入队和出队都用了加锁,当队空的时候线程会暂时阻塞。
由于我们的系统入队需求要远大于出队需求,一般不会出现队空的情况,所以我们可以选择ConcurrentLinkedQueue来作为我们的请求队列实现:
package seckill; import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.http.HttpRequest; public class RequestQueue { public static ConcurrentLinkedQueue<HttpRequest> queue = new ConcurrentLinkedQueue<HttpRequest>();}
用户请求模块
package seckill; import org.apache.http.HttpRequest; public class Processor { /** * 发送秒杀事务到数据库队列. */ public static void kill(BidInfo info) { DB.bids.add(info); } public static void process() { BidInfo info = new BidInfo(RequestQueue.queue.poll()); if (info != null) { kill(info); } }} class BidInfo { BidInfo(HttpRequest request) { // Do something. }}
数据库模块:
数据库主要是使用一个ArrayBlockingQueue来暂存有可能成功的用户请求。
package seckill; import java.util.concurrent.ArrayBlockingQueue; /** * DB应该是数据库的唯一接口. */public class DB { public static int count = 10; public static ArrayBlockingQueue<BidInfo> bids = new ArrayBlockingQueue<BidInfo>(10); public static boolean checkReminds() { // TODO return true; } // 单线程操作 public static void bid() { BidInfo info = bids.poll(); while (count-- > 0) { // insert into table Bids values(item_id, user_id, bid_date, other) // select count(id) from Bids where item_id = ? // 如果数据库商品数量大约总数,则标志秒杀已完成,设置标志位reminds = false. info = bids.poll(); } }}
三、结语
看起来大体这样应该就可以了,当然还有细节可以优化,比如数据库请求可以都做成异步的等等。
0 0
- 这是一个秒杀系统,即大量用户抢有限的商品,先到先得 用户并发访问流量非常大,需要分布式的机器集群处理请求 系统实现使用Java
- 判断来访问网站的用户是手机用户还是Web浏览器的用户【即判定用户当前使用的系统】
- 用户是怎样访问我们的系统
- Java使用限流处理大量的并发请求
- 一个在运行的活的大系统是一个怪兽,需要大量年富力强的程序员的献祭
- springMVC一个Controller处理所有用户请求的并发问题
- 高并发,大流量分布式系统要点
- 商品用户推荐系统的研究
- 利用Java GUI 实现一个简易的用户管理系统
- 大数据实战:用户流量分析系统
- 大数据实战:用户流量分析系统
- java web 处理大量用户并发提交的简单思路:队列加定时提交
- 用户访问MVC页面后,系统的处理机制
- 网站高并发 大流量访问的处理及解决方法
- 网站高并发 大流量访问的处理及解决方法
- 网站高并发大流量访问的处理及解决方法
- 网站高并发 大流量访问的处理及解决方法?
- 网站高并发 大流量访问的处理及解决方法
- <intent-filter>隐式intent的用法
- hdu 1028 Ignatius and the Princess III
- 实现滑动隐藏标题栏布局ListView所碰到的问题
- Kill -HUP详解
- linux利用sendmail发送邮件的方法
- 这是一个秒杀系统,即大量用户抢有限的商品,先到先得 用户并发访问流量非常大,需要分布式的机器集群处理请求 系统实现使用Java
- JAVA基础(16) Servlet/Filter/Listener/Interceptor区别与联系
- spring的AOP和事务
- 今天是我在CSDN安家的第一天
- IIS上传和下载文件的大小限制
- Apple Pay教程(附示例代码)(1)
- 文本组件的事件和属性设置方案之Spannable
- 【官方方法】xcode7免证书真机调试
- Double类型保留小数的n种方法