springboot整合redis高并发环境测试
中国加油,武汉加油!
篇幅较长,配合右边目录观看
项目准备
- 本案例基于springboot篇】十八. springboot整合redis
- jmeter
1. 案例
1.1 pom导包
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.0</version>
</dependency>
1.2 定义RedisConfig
package com.wpj.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
@SpringBootConfiguration
public class RedisConfig {
/**
* 配置Redis锁
* @return
*/
@Bean
public RedissonClient redissonClient(){
RedissonClient redissonClient = null;
Config config = new Config();
String url = "redis://47.98.33.215:6379";
config.useSingleServer().setAddress(url);
try {
redissonClient = Redisson.create(config);
return redissonClient;
} catch (Exception e) {
return null;
}
}
}
1.3 定义一个类用于加解锁
package com.wpj.lock;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 加锁的类
*/
@Slf4j
@Component
public class DistributeRedisLock {
@Autowired
private RedissonClient redissonClient;
// 加锁
public boolean lock(String lockName){
try {
if(null == redissonClient) {
log.info("注入redisson失败");
return false;
}
RLock lock = redissonClient.getLock(lockName);
lock.lock(30, TimeUnit.SECONDS);
log.info("加锁成功");
return true;
} catch (Exception e) {
log.info("未知错误");
return false;
}
}
// 释放锁
public boolean unlock(String lockName){
try{
if(null == redissonClient) {
log.info("释放锁失败"+lockName);
return false;
}
// 获取锁
RLock lock = redissonClient.getLock(lockName);
if(null!= lock) {
lock.unlock();
log.info("释放锁成功");
return true;
}
return false;
} catch (Exception e) {
log.info("未知错误");
return false;
}
}
}
1.5 定义业务实现
package com.wpj.service.impl;
import com.wpj.lock.DistributeRedisLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* 火车票减库存
*/
@Service
@Slf4j
public class TrainTickServiceImpl {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private DistributeRedisLock distributeRedisLock;
/**
* 减售火车票
*/
public synchronized String produceStock(){
String lock = "lock";
try {
boolean dLock = distributeRedisLock.lock(lock);
if (true == dLock) {
// 从redis取出数据
Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("trainticks"));
// 判断是否大于0
if(stock > 0) {
int rStock = stock - 1;
// 将真实的库存放到redis中去
stringRedisTemplate.opsForValue().set("trainticks", String.valueOf(rStock));
log.info("扣减库存成功,剩余库存:" + rStock);
} else {
log.info("库存不足");
}
} else {
return "";
}
} finally {
distributeRedisLock.unlock(lock);
}
return "抢票成功。。。";
}
}
1.6 controller添加方法
@Autowired
private TrainTickServiceImpl trainTickService;
@RequestMapping("/produceStockRedisson")
public String produceStockRedisson(){
return trainTickService.produceStock();
}
1.7 redis中添加数据
1.8 使用jMeter测试
2. 序列化
2.1 导包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
2.2 自定义序列化
package com.wpj.serializer;
import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
public class MySerializer implements RedisSerializer {
private Class clazz;
private MySerializer(Class clazz){
this.clazz = clazz;
}
/**
* 序列化,将对象转换成字符串
* @param o
* @return
* @throws SerializationException
*/
@Override
public byte[] serialize(Object o) throws SerializationException {
if(null==o){
return null;
}
//我们要将这个值转换成json对象存储到Redis中
String jsonString = JSON.toJSONString(o);
return jsonString.getBytes(Charset.forName("UTF-8"));
}
/**
* 反序列化,将redis的字符串转换成java对象
* @param bytes
* @return
* @throws SerializationException
*/
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if(null==bytes) {
return null;
}
String strResult = new String(bytes);
//将String类型的数据(JSON)转换成java对象
return JSON.parseObject(strResult, clazz);
}
}
2.3 RedisConfig配置
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new MySerializer(Object.class));
return redisTemplate;
}