用压测模拟并发、并发处理(synchronized,redis分布式锁)
使用工具:Apache an
测压命令: ab -n 100 -c 100 http://www.baidu.com -n代表模拟100个请求,-c代表模拟100个并发,相当于100个人同时访问
ab -t 60 -c 100 http://www.baidu.com 60秒100个并发,不断发送请求
并发处理:
1.加synchronized锁单线程处理、缺点: 无法做到细粒度控制,处理速度也会很慢 只适合单点的情况
2.redis分布式锁:
可以支撑每秒10多万的并发,支持分布式,可以更细粒的控制代码(多台机器上多个线程对一个数据进行操作的互斥)
SETNX key value
将key设置值为value,如果key不存在,这种情况下等同于SET命令,当key存在时,什么也不做
GETSET key value
自动将key对应到value并且返回原来key和对应的value,如果key存在但是对应的value不是字符串,就返回错误
DEMO演示:
加锁处理方法:
@Component
@Slf4j
public class RedisLock {
@Autowired
private StringRedisTemplate stringRedisTemplate;
//加锁
/*
* @param key id
* @param value 当前时间+超时时间
*
* */
public boolean lock(String key,String value){
if (stringRedisTemplate.opsForValue().setIfAbsent(key,value)){
return true;//加锁成功就返回true
}
//不加下面这个可能出现死锁情况
//代码value加了过期时间* @param value 当前时间+超时时间
//获取上一个锁的时间,并判断是否小于当前时间,小于就下一步判断,就返回true加锁成功
//currentValue=A 这两个线程的value都是B 其中一个线程拿到锁
String currentValue=stringRedisTemplate.opsForValue().get(key);
//如果锁过期
if (!StringUtils.isEmpty(currentValue)
&& Long.parseLong(currentValue)<System.currentTimeMillis()){//存储时间要小于当前时间
//出现死锁的另一种情况,当多个线程进来后都没有返回true,接着往下执行,执行代码有先后,而if判断里只有一个线程才能满足条件
//oldValue=currentValue
//多个线程进来后只有其中一个线程能拿到锁(即oldValue=currentValue),其他的返回false
//获取上一个锁的时间
String oldValue=stringRedisTemplate.opsForValue().getAndSet(key,value);
if (!StringUtils.isEmpty(oldValue)&& oldValue.equals(currentValue)){//上一个时间不为空,并且等于当前时间
return true;
} }
return false;//失败返回false
} //解锁
public void unlock(String key,String value){//执行删除可能出现异常需要捕获
try {
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {//如果不为空,就删除锁
stringRedisTemplate.opsForValue().getOperations().delete(key);
}
}catch (Exception e){
log.error("[redis分布式锁] 解锁",e);
}
}
}
//秒杀demo
pprivate static final int TIMEOUT=10*1000;//超时时间设置为10s
@Autowrite
private RedisLock redisLock;
public void method(String id){ //加锁-死锁出现:即在加锁后运行程序出现意外报了异常,而此时还没调用解锁方法
//那么在下一个线程调用加锁方法是就不能set,直接返回fale,然后一直停留在加锁失败状态 这就出现了死锁
long time=System.currentTimeMillis()+TIMEOUT;
//如果加锁不成功就抛出异常 if(!redisLock.lock.get(id,String.valueof(time))){
throw new WechatSellException(101,"哎哟喂,人也太多了,换个姿势再试试");
}
//加锁成功就实现业务代码处理 //1.查询该商品库存,为0表示活动结束 //2.下单 3.扣库存 //解锁
redisLock.unlock(id,String.valueof(time))); }
用压测模拟并发、并发处理(synchronized,redis分布式锁)的更多相关文章
- springboot项目:Redis分布式锁的使用(模拟秒杀系统)
模拟秒杀系统: 第一步:编写Service package com.payease.service; /** * liuxiaoming * 2017-12-14 */ public interfac ...
- 漫谈Redis分布式锁实现
在Redis上,可以通过对key值的独占来实现分布式锁,表面上看,Redis可以简单快捷通过set key这一独占的方式来实现分布式锁,也有许多重复性轮子,但实际情况并非如此.总得来说,Redis实现 ...
- 使用AB对Nginx压测和并发预估
简介 ab命令会创建多个并发访问线程,模拟多个访问者同时对某一URL地址进行访问.它的测试目标是基于URL的. # 1.ab每次只能测试一个URL,适合做重复压力测试 # 2.参数很多,可以支持添加c ...
- 使用Redis分布式锁处理并发,解决超卖问题
一.使用Apache ab模拟并发压测 1.压测工具介绍 $ ab -n 100 -c 100 http://www.baidu.com/ -n表示发出100个请求,-c模拟100个并发,相当是100 ...
- synchronized的不足与redis分布式锁的使用
这里是一个简单模拟秒杀的逻辑,stock和orders为两个Map,分别模拟库存表和订单表 public void orderProductMockDiffUser(String productId) ...
- springboot+redis分布式锁-模拟抢单
本篇内容主要讲解的是redis分布式锁,这个在各大厂面试几乎都是必备的,下面结合模拟抢单的场景来使用她:本篇不涉及到的redis环境搭建,快速搭建个人测试环境,这里建议使用docker:本篇内容节点如 ...
- java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱
java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...
- Redis 分布式锁及缓存注释的使用方法
使用工具:Apache an 测压命令: ab -n 100 -c 100 http://www.baidu.com -n代表模拟100个请求,-c代表模拟100个并发,相当于100个人同时访问 ab ...
- Redis分布式锁解决抢购问题
转:https://segmentfault.com/a/1190000011421467 废话不多说,首先分享一个业务场景-抢购.一个典型的高并发问题,所需的最关键字段就是库存,在高并发的情况下每次 ...
随机推荐
- conda 管理 python 版本
conda常用命令 查看当前系统下的环境 conda info -e 创建新的环境 # 指定python版本为2.7 conda create -n env_name python=2.7 # 同时安 ...
- [Axiom3D]第一个Axiom3D程序
Axiom3D程序的基本渲染流程 #region Namespace Declarations using System; using System.Linq; using Axiom.Core; u ...
- 优雅的使用Laravel之phpstorm配置
优雅的使用Laravel之phpstorm配置 先打开一个Laravel 项目,然后在project tool 窗口选择根节点.然后右键->Composer | Init composer . ...
- 认识与设计Serverless(一)
一.什么是Serverless 定义:Serverless是一种无服务器的架构,区别于传统的Baas,SAAS,作为FAAS(函数即服务)而存在,函数由事件驱动触发并按需调用. 按需调用:区别于传统的 ...
- C#检查文件是否被占用
第一种方法: using System.IO; using System.Runtime.InteropServices; [DllImport("kernel32.dll")] ...
- 多线程Java面试题总结
57.Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指 ...
- Django中间件的5种自定义方法
阅读目录(Content) Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前 和视图函 ...
- 泰德激光打标软件 包含 #include "Main.h" 时 原本正确的单元却报错
问题:泰德激光打标软件 ,当新增单元需要包含 #include "Main.h" 时, 原本正确的单元却报错. 办法:包含 #include "Main.h" ...
- 手把手教你学node之搭建node.js开发环境
搭建node.js开发环境 本文只针对在Linux或者Mac下面.至于使用 Windows 并坚持玩新技术的同学,我坚信他们一定有着过人的.甚至是不可告人的兼容性 bug 处理能力,所以这部分同学麻烦 ...
- VS2010/MFC编程入门之二十四(常用控件:列表框控件ListBox)
前面两节讲了比较常用的按钮控件,并通过按钮控件实例说明了具体用法.本文要讲的是列表框控件(ListBox)及其使用实例. 列表框控件简介 列表框给出了一个选项清单,允许用户从中进行单项或多项选择,被选 ...