1、下载地址:https://www.apachehaus.com/cgi-bin/download.plx
直接下载和解压。
2、修改apache服务的配置文件(服务器的根目录)
安装在哪了,就修改哪个根部目录。
3、启动服务
去到apache的bin目录运行cmd,输入命令:httpd.exe启动服务。
如果有端口被占用输入命令查看:netstat -ano | findstr “443”,并杀掉该进程
这里因为nginx用的是80端口,所以为了防止冲突,把httpd.conf文件的端口80改为81
4、在没有锁的服务端直接崩溃,打印一堆重复的value值
在bin目录中打开命令窗口cmd,输入命令:
ab -c 200 -n 1000 http://redistest/testRedisson
压力测试:-c并发数 -n总请求数 地址
总共1000请求:200并发 压5次
在防止缓存击穿,使用分布式锁,不同线程拿到相同的value值,去删锁,这个致命的bug。
在高度的请求压力下,人们即使拿到锁也很快直接被删除,导致无法访问页面!!!
到redis服务器get k查看value值,竟然是224。
发了1000次请求,理应该value值每个都不同,应该是加到第1000,而这里却是224。
至少有每5次请求的value值是相同的,这是一个多么恐怖攻击!
5、这里使用redisson框架分布式锁,直接在java类层面设置锁解决缓存击穿删锁的问题。
而使用redis自带的分布式锁,是在redis数据库里设置锁
两者的区分:
redisson上锁:
RLock lock = redissonClient.getLock("lock");
lock.lock();
//中间测试value值是否重复,来证明该技术是防止缓存击穿,让线程有序的访问数据库。
redisson解锁:
lock.unlock();
//必须要解锁才能上锁。
redis数据库自带的分布式锁,为了防止缓存击穿,需要设置锁,再删除锁。
而删除锁会导致一系列的问题出现。UUID防止误删别人的锁,lua脚本防止在做判断删锁的时候锁过期,的两种情况。
这里压了一下京东商城玩一下,第1000次请求超时了,反压力测试!qwq
测试代码:
@Controller
public class RedissonController {
@Autowired
RedisUtil redisUtil;
@Autowired
RedissonClient redissonClient;
@RequestMapping("testRedisson") // 访问http://redisTest/testRedisson,先把host文件的localhost本地地址解析成redisTest
@ResponseBody //再配置nginx代理本地地址redisTest,并去端口
public String testRedisson(){
//防压力测试代码,未加分布式锁,测试是否有重复的v
//当很多条线程高压力的访问的时候,就很容易出现异常,导致v重复!!!!
Jedis jedis = redisUtil.getJedis();
RLock lock = redissonClient.getLock("lock");
lock.lock();
try {
String v = jedis.get("k"); //查询"k",返回v字符串
if(StringUtils.isBlank(v)){ //v为空
v="1"; //v等于字符串1
}
System.out.println("v值:"+v); //打印v值
jedis.set("k",(Integer.parseInt(v)+1)+""); //存入"k",value为:(把v字符串转为int类型,再+1)+"" 字符串
}finally {
jedis.close();
lock.unlock();
}
return "success";
}
}