java接口并发衡量_java 后端设计高并发接口总结

如何设置高并发接口

一、并发队列的选择

二、请求接口的合理设计

三、高并发下的数据安全

3.1 超发的原因

3.2 悲观锁思路

3.3 FIFO队列思路

3.4 乐观锁思路

一、并发队列的选择

Java的并发包提供了三个常用的并发队列实现,分别是:ArrayBlockingQueue、ConcurrentLinkedQueue 和 LinkedBlockingQueue 。

ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设定一个10大小的数组队列。

ConcurrentLinkedQueue使用的是CAS原语无锁队列实现,是一个异步队列,入队的速度很快,出队进行了加锁,性能稍慢。

LinkedBlockingQueue也是阻塞的队列,入队和出队都用了加锁,当队空的时候线程会暂时阻塞。

在请求预处理阶段,由于我们的系统入队需求要远大于出队需求,一般不会出现队空的情况,所以我们可以选择

ConcurrentLinkedQueue来作为我们的请求队列实现

二、请求接口的合理设计

一个秒杀或者抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是参与秒杀的Web后台请求接口。

通常静态HTML等内容,是通过CDN的部署,一般压力不大,核心瓶颈实际上在后台请求接口上。这个后端接口,必须能够支持高并发请求,同时,非常重要的一点,必须尽可能“快”,在最短的时间里返回用户的请求结果。为了实现尽可能快这一点,接口的后端存储使用内存级别的操作会更好一点。仍然直接面向MySQL之类的存储是不合适的,如果有这种复杂业务的需求,都建议采用异步写入。当然,也有一些秒杀和抢购采用“滞后反馈”,就是说秒杀当下不知道结果,一段时间后才可以从页面中看到用户是否秒杀成功。但是,这种属于“偷懒”行为,同时给用户的体验也不好,容易被用户认为是“暗箱操作”。

三、高并发下的数据安全

我们知道在多线程写入同一个文件的时候,会存现“线程安全”的问题(多个线程同时运行同一段代码,如果每次运行结果和单线程运行的结果是一样的,结果和预期相同,就是线程安全的)。如果是MySQL数据库,可以使用它自带的锁机制很好的解决问题,但是,在大规模并发的场景中,是不推荐使用MySQL的。秒杀和抢购的场景中,还有另外一个问题,就是“超发”,如果在这方面控制不慎,会产生发送过多的情况。我们也曾经听说过,某些电商搞抢购活动,买家成功拍下后,商家却不承认订单有效,拒绝发货。这里的问题,也许并不一定是商家奸诈,而是系统技术层面存在超发风险导致的。

3.1 超发的原因

假设某个抢购场景中,我们一共只有100个商品,在最后一刻,我们已经消耗了99个商品,仅剩最后一个。这个时候,系统发来多个并发请求,这批请求读取到的商品余量都是99个,然后都通过了这一个余量判断,最终导致超发。(同文章前面说的场景),在下面的这个图中,就导致了并发用户B也“抢购成功”,多让一个人获得了商品。这种场景,在高并发的情况下非常容易出现。

57c4baf0ff913b46402bf4480fc3050e.png

3.2 悲观锁思路

解决线程安全的思路很多,可以从“悲观锁”的方向开始讨论。

悲观锁,也就是在修改数据的时候,采用锁定状态,排斥外部请求的修改。遇到加锁的状态,就必须等待。

28618ce0fd80dceb14b85879855e2d91.png

虽然上述的方案的确解决了线程安全的问题,但是,别忘记,我们的场景是“高并发”。也就是说,会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里。同时,这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常。

3.3 FIFO队列思路

那好,那么我们稍微修改一下上面的场景,我们直接将请求放入队列中的,采用FIFO(First Input First Output,先进先出),这样的话,我们就不会导致某些请求永远获取不到锁。看到这里,是不是有点强行将多线程变成单线程的感觉哈。

6844903974206701581

08087e191c94728fc3eba3ef1e76d73f.png

然后,我们现在解决了锁的问题,全部请求采用“先进先出”的队列方式来处理。那么新的问题来了,高并发的场景下,因为请求很多,很可能一瞬间将队列内存“撑爆”,然后系统又陷入到了异常状态。或者设计一个极大的内存队列,也是一种方案,但是,系统处理完一个队列内请求的速度根本无法和疯狂涌入队列中的数目相比。也就是说,队列内的请求会越积累越多,最终Web系统平均响应时候还是会大幅下降,系统还是陷入异常。

3.4 乐观锁思路

这个时候,我们就可以讨论一下“乐观锁”的思路了。乐观锁,是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。实现就是,这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话,我们就不需要考虑队列的问题,不过,它会增大CPU的计算开销。但是,综合来说,这是一个比较好的解决方案。

b83aa4baab80a2f2b4508e9b94b7513f.png

有很多软件和服务都“乐观锁”功能的支持,例如Redis中的watch就是其中之一。通过这个实现,我们保证了数据的安全。

最后

欢迎大家有兴趣的可以关注我的公众号【java小瓜哥的分享平台】,文章都会在里面更新,还有各种java的资料都是免费分享的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA 取得当前目录的路径

在写java程序时不可避免要获取文件的路径...总结一下,遗漏的随时补上 1.可以在servlet的init方法里 String path getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 :E:/eclipseM9/workspace/tree/ tree是我web项目的根目录 2.你也可以随时在任意…

02.1-元素定位(find)

常用的一些方法 一、导包 from selenium import webdriver二、打开火狐(空白页) b webdriver.Firefox()三、跳转到指定的网站 b.get(https://www.baidu.com/)四、将浏览器页面最大化 b.maximize_window()五、通过F12可查看当前的贴吧为超链接形式 …

快速傅里叶变换(FFT)——按时间抽取DIT的基

目录【1】前言1、DIF计算量2、利用性质改善【2】公式推导1、N 到 2*N/2a、分解原序列b、分解后的DFT变换c、一系列化简操作之后d、蝶形信号流e、计算量总结2、N/2 到 2*N/4a、分解X2(k)序列b、蝶形信号流(2列)3、N/4 到 2*N/8a、蝶形信号流(3…

快速傅里叶变换(FFT)——按频率抽取DIF的基

目录【1】回顾DIT【2】算法原理【3】运算特点【1】回顾DIT https://blog.csdn.net/qq_42604176/article/details/105559756 【2】算法原理 设序列点数:N2^M,M为正整数。将输入序列按照前一半、后一半分开。(并非按照奇偶分) 由于&#xf…

莫比乌斯函数---C++

【问题描述】 莫比乌斯函数,数论函数,由德国数学家和天文学家莫比乌斯(Mobius,1790-1868)提出。梅滕斯(Mertens)首先使用μ(n)作为莫比乌斯函数的记号。而据说,高斯(Gauss)比莫比乌斯早三十年就曾考虑过这个函数。莫比乌斯函数在数…

Opencv——findContours函数再探(由轮廓联想连通域)

目录关于调参的一些思考分析图像的一些角度面积、周长、矩形度、圆形度、宽长比例1:找出汽车轮毂圆孔(从轮廓和连通域两个角度)例2:找出芯片中间正方形物体例3:桌面上橘色物体总结关于调参的一些思考 合理的参数设置&…

modelsim 编译 xilinx库

1.为单个工程加入库 在某一个目录建立工程 然后 vlib unisim vcom -work unsim *.vhd 然后就加入了unisim库 如果是windows的话,工程文件mpf应该是记录了这个库的信息,所以重新打开这个工程时,依然有这个库 linux,不用gui界面…

php 载入css就可以显示,如何在进度条加载后显示页面

1.思路:加入很多图片,以延迟加载时间,实现加载完后显示图片。定义一个外层p,覆盖住图片,在内层p中引入加载时显示的图片,让内层p居中在页面上,利用setInterval定时器设置3秒后将外层p隐藏&#…

如何获取轮廓(连通域)的面积、周长、矩形度、圆形度、宽长比、周径比等形状描述符?

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录前言1、轮廓面积获取函数2、轮廓周长获取函数3、轮廓圆形度计算4、矩形度计算…

01-基础部分

一、tensorflow和opencv测试 import tensorflow as tf import cv2hello tf.constant(hello tensorflow) session tf.Session() print(session.run(hello))print(hello opencv)运行效果如下: 二、基础部分 1、opencv基础 代码三部曲: 1、引入Open…

网络和通信 - Silverlight 中的 HTTP 通信和安全

Silverlight 支持几种使用 HTTP/HTTPS 的方案。虽然可以使用多种方式和技术执行 HTTP 调用,但是下表描述的是针对这些 HTTP 通信方案的建议方法 执行 HTTP 调用的选项 确定应由浏览器还是客户端来执行应用程序的 HTTP 处理后,应在创建任何 Web 请求之前指…

WT2605C高品质音频蓝牙语音芯片:外接功放实现双声道DAC输出的优势

在音频处理领域,双声道DAC输出能够提供更为清晰、逼真的音效,增强用户的听觉体验。针对这一需求,唯创知音的WT2605C高品质音频蓝牙语音芯片,通过外接功放实现双声道DAC输出,展现出独特的应用优势。 一、高品质音频处理…

角点检测(Harris角点检测法)

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录原理讲解【1】为何选取角点作为特征?【2】角点的定义:…

02-图像的几何变换

一、图片缩放 imageInfo:图片宽、高、通道个数等 缩放: 等比例缩放:宽高比不变 任意比例缩放:图片拉伸、非拉伸 窗体大小 实现步骤: 1,完成图像的加载,拿到图像的数据信息 2,图片的宽…

微机原理——8086中断类型以及中断向量表、中断响应、中断返回

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录先验知识回顾控制寄存器回顾1、8086中断类型1、外部可屏蔽中断2、外部不可屏蔽…

资料整理-工具篇

* 代码利器 Resharper 作为一个C#er,非常感谢有Resharper这样的代码利器。在VS系列的IDE中,使用Resharper后,你会发现,原来写代码也可以是一种享受! 1. 首先,下载Resharper。下载地址:http://ww…

企业级php第三方支付平台,ThinkPHP新版企业级php第三方api第四方支付平台程序源码商业版 带接口文件等 某宝售价3000元...

本帖最后由 商业源码网 于 2017-12-21 11:23 编辑7 h$ . , C u0 R3 R y$ z! ] q( D D$ s( Y源码说明:) G: y; R# G0 0 g N. ; \0 w, A9 {5 # P今天黑锐给大家分享给好东西!很不错的支付系统!喜欢研究支付接口的朋友别错过!ThinkP…

OpenCV实战【2】HOG+SVM实现行人检测

目录HOG是什么?HOG vs SIFTHOG步骤HOG在检测行人中的方式Opencv实现HOGDescriptor的构造函数:行人检测HOGSVM步骤简化版的HOG计算HOG是什么? 方向梯度直方图( Histogram of Oriented Gradient, HOG )特征是一种在计算机视觉和图像处理中用来进…

03-图像特效

一、灰度处理 方法一:imread方法 彩色图的颜色通道为3,即RGB;而灰度图只有一个颜色通道。 import cv2 img0 cv2.imread(E:\Jupyter_workspace\study\data/cat.png,0) img1 cv2.imread(E:\Jupyter_workspace\study\data/cat.png,1) print…

解析linux根文件系统的挂载过程

------------------------------------------ 本文系本站原创,欢迎转载!转载请注明出处:http://ericxiao.cublog.cn/------------------------------------------ 一:前言前段时间在编译kernel的时候发现rootfs挂载不上。相同的root选项设置旧版的image却可以。为了…