Java Web应用开发案例|模拟12306抢票

简介: 模拟12306网上抢票的业务场景。春节等高峰时期,车票资源非常紧张,因此在约定时间放票,会存在大量抢票行为。服务器为了缓解并发高峰时的压力,抢票请求会用消息中间件进行排队处理。出票行为在服务器的独立线程中进行,这样主线程主要用于接收购票请求,异步线程用于出票,会大大缓解服务器的压力。

image.png


模拟12306网上抢票的业务场景。春节等高峰时期,车票资源非常紧张,因此在约定时间放票,会存在大量抢票行为。服务器为了缓解并发高峰时的压力,抢票请求会用消息中间件进行排队处理。出票行为在服务器的独立线程中进行,这样主线程主要用于接收购票请求,异步线程用于出票,会大大缓解服务器的压力。
# 01、案例:12306抢票

操作步骤如下所述。
(1) 新建控制器支持异步模式。
js @WebServlet(asyncSupported = true,urlPatterns ="/AuctionSvl") public class AuctionSvl extends HttpServlet
(2) 控制器的service()方法是一个高并发环境。
每个HTTP请求都使用独立的request对象。调用request.startAsync(),为每个HTTP请求创建一个异步回应的环境。
js public void service(HttpServletRequest request HttpServletResponse response)throws ServletException,IOException (System.out.println("servlet 主线程:”+ Thread.currentThread().getId()) //lineNum 为行号String linenum = request.getParameter("lineNum”); AsyncContext act = request.startAsync(); act.getRequest().setAttribute("linenum”linenum); AuctionListener.add(act);
(3) 所有异步回应在独立线程中统一处理。
AuctionListener实现了ServletContextListener监听器,因此在Tomcat启动时被加载。BlockingQueue为阻塞队列,装载所有与请求对应的AsyncContext对象。
js public class AuctionListener implements ServletContextListener( private static final BlockingOueue < AsyncContext > queue= new LinkedBlockingOueue < AsyncContext >(); private volatile Thread thread; public static void add(AsvncContext c)queue.add(c); contextInitialized(); //参见下面的代码实现
ServletContextListener的contextInitialized()方法代码如下,独立的后台线程从队列queue中顺序提取AsyncContext对象,然后分别调用每个AsyncContext的response对象,给不同的客户端回应数据。
js public void contextInitialized(ServletContextEvent servletContextEvent) (thread = new Thread(new Runnable() public void run(){ while (true) AsyncContext acontext = null; while ( queue.peek() != null) try{ acontext = (AsyncContext)queue.poll(); ServletResponse response = acontext.getResponse();response.setContentType("text/html;charset = utf - 8");PrintWriter out = response.getWriter();Thread.sleep(200);String name ="异步线程:” +Thread.currentThread().getId();long duration = System.currentTimeMillis(); //提取前面输入的行号,并输出 out.println(acontext.getRequest().getAttribute("linenum") } "+ name +”"duration) out.close(); catch (Exception e) throw new RuntimeException(e.getMessage(),e);finally(if(acontext != null)acontext.complete(); thread.start(); } }
(4) 客户端模拟多用户并发抢票,循环发出20个异步请求。
js S.ajax( url:"AuctionSvl" type: "post" dataType:"html" data: data, timeout:50000 cache:false dataFilter:function (data,type) (return data; success:function(data,testStatus)var dataArray = Array();dataArray = data.split("")* 填充表格 *$("# tablel").append("< tr id='tr"+ i+ "class = 'mytr'></tr>") ;for(var j=0;j< dataArray.length; j++)[ $ ("#tr"+ i).append("< td>" + dataArray[j] + "</td>") error:function(msg) );
(5) 对比服务器异步回应和同步回应,异步抢票结果见图1。
在这个示例中,所有用户的并发购票请求,都会先存在一个阻塞队列中,然后由一个后台异步线程,顺序从阻塞队列中提取请求,当出票结束后再回应客户端。这样做的好处是服务器的压力很小,虽然用户的等待时间较长,但是这样保证了用户购票请求的正确处理。

image.png


■ 图1 12306抢票

目录
相关文章
|
5天前
|
存储 Java
java用base64编码案例
Java Base64编码示例:导入`java.util.Base64`,设置字符串`originalString`,使用`Base64.getEncoder().encodeToString()`编码并存储到`encodedString`,打印编码后字符串。解码用`Base64.getDecoder().decode()`。
11 0
|
1天前
|
Java 关系型数据库 测试技术
Java代码一键生成数据库文档(案例详解)
Screw是一个自动化数据库文档生成工具,能根据数据库表结构快速生成简洁、多格式(HTML、Word、Markdown)的文档,支持MySQL、MariaDB等多数据库。它使用Freemarker模板,允许用户自定义样式。依赖包括HikariCP数据库连接池和对应JDBC驱动。通过在Java代码或Maven插件中配置,可方便生成文档。示例代码展示了如何在测试用例中使用Screw。文档效果依赖于数据库中的表和字段注释。
|
1天前
|
开发框架 JavaScript 前端开发
【JavaScript 与 TypeScript 技术专栏】TypeScript 在 Web 开发中的前沿应用
【4月更文挑战第30天】TypeScript在Web开发中日益重要,以其强大的类型系统提升代码质量,支持组件化开发,与React、Vue、Angular等框架良好集成。在大型项目管理中,TypeScript助于代码组织和优化,提高团队协作效率。此外,它提升开发体验,提供智能提示和错误检测。众多成功案例证明其前沿应用,未来将在Web开发领域持续发挥关键作用。
|
2天前
|
Java 索引
Java String应用与开发
Java String应用与开发
10 0
|
2天前
|
前端开发 JavaScript 测试技术
【PHP开发专栏】PHP Web开发基础与流程
【4月更文挑战第29天】本文介绍了PHP Web开发的基础和流程,帮助初学者入门。内容包括Web服务器与PHP解释器的工作原理、HTML/CSS/JavaScript基础知识、PHP语法与数据库操作。开发流程涵盖项目规划、环境搭建、数据库设计、代码编写、测试与调试,以及部署与维护。此外,文中还强调了使用框架、代码组织、安全性及性能优化等进阶知识和最佳实践,旨在培养优秀PHP开发者。
|
3天前
|
安全 Java 开发者
构建高效微服务架构:后端开发的新范式Java中的多线程并发编程实践
【4月更文挑战第29天】在数字化转型的浪潮中,微服务架构已成为软件开发的一大趋势。它通过解耦复杂系统、提升可伸缩性和促进敏捷开发来满足现代企业不断变化的业务需求。本文将深入探讨微服务的核心概念、设计原则以及如何利用最新的后端技术栈构建和部署高效的微服务架构。我们将分析微服务带来的挑战,包括服务治理、数据一致性和网络延迟问题,并讨论相应的解决方案。通过实际案例分析和最佳实践的分享,旨在为后端开发者提供一套实施微服务的全面指导。 【4月更文挑战第29天】在现代软件开发中,多线程技术是提高程序性能和响应能力的重要手段。本文通过介绍Java语言的多线程机制,探讨了如何有效地实现线程同步和通信,以及如
|
3天前
|
前端开发 JavaScript 开发者
前端技术栈:探索现代Web开发的核心要素与代码实践
前端技术栈:探索现代Web开发的核心要素与代码实践
9 1
|
3天前
|
Java
【专栏】如何在 Java 8 中使用 Streams?结合多种案例剖析学习!
【4月更文挑战第28天】Java 8 的 Streams 提供了一种处理数据集合的新方式,增强了代码的可读性和可维护性。本文介绍了 Streams 的基本概念,如从数据源创建 Stream,以及中间和终端操作。通过过滤、映射、归并、排序、分组等案例,展示了 Streams 的使用,包括并行 Streams 提高效率。学习 Streams 可以提升代码质量和效率,文章鼓励读者在实际开发中探索更多 Streams 功能。
|
4天前
|
前端开发 数据管理 Ruby
blog-engine-10-middleman 静态站点生成器,利用了现代 Web 开发中的所有快捷方式和工具
这篇内容介绍了Middleman,一个基于Ruby的静态网站生成器。Middleman的特点包括静态网站生成、模板系统、前端技术支持、数据管理和简单的部署。安装步骤涉及安装Ruby和运行`gem install middleman`。使用方法包括在`source`目录编写内容,使用`middleman server`预览,`middleman build`构建网站,然后部署到服务器。Middleman的优势在于速度、灵活性和数据管理,但需要Ruby知识,且社区规模较小。适合熟悉Ruby并寻求强大建站工具的用户。
|
5天前
|
Java Apache
java读取excel数据案例
Java代码示例使用Apache POI库读取Excel(example.xlsx)数据。创建FileInputStream和XSSFWorkbook对象,获取Sheet,遍历行和列,根据单元格类型(STRING, NUMERIC, BOOLEAN)打印值。需引入Apache POI库并确保替换文件路径。
7 1