需要的环境:jdk8、redis
使用场景:redis缓存优化,秒杀场景,比java本身提供的序列化性能更优
依赖的jar包:
<!-- redis 客户端 Jedis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- redis end -->
<!-- protostuff 序列化依赖-->
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version>
</dependency>
上代码:
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.HashMap;
/**
* Created by xpc on 2018/12/19.
* redis后端缓存优化编码
*/
public class DictDaoImpl{
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final JedisPool jedisPool;
//存放序列化对象
private RuntimeSchema<Dict> schema = RuntimeSchema.createFrom(Dict.class);
public DictDaoImpl(String ip, int port){
jedisPool = new JedisPool(ip,port);
}
//把字符串中的内容读取为字典数组对象
public Dict load(String dictId){
//redis操作逻辑
try{
Jedis jedis = jedisPool.getResource();
try{
String key = "seckill:"+dictId;
//并没有实现内部序列化操作
// get -> byte[] -> 反序列化 -> Object(Dict)
//采用自定义序列化,转换为二进制,需要protostuff的序列化依赖包
//protostuff:pojo.
byte[] bytes = jedis.get(key.getBytes());
//缓存中获取到
if(bytes != null){
//空对象
Dict seckill = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes,seckill,schema);
//seckill 被反序列化
return seckill;
}
}finally {
jedis.close();
}
}catch (Exception e){
logger.error(e.getMessage(),e);
}
return null;
}
//把数组保存到一个Dict对象中
public String store(Dict dict){
//set Object(Dict) -> 序列化 -> byte[]
try{
Jedis jedis = jedisPool.getResource();
try{
String key = "seckill:"+dict.getKey();
byte[] bytes = ProtostuffIOUtil.toByteArray(dict,schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
//超时缓存
int timeout = 60 * 60 ;//1小时
String result = jedis.setex(key.getBytes(),timeout,bytes);
return result;
}finally {
jedis.close();
}
}catch (Exception e){
logger.error(e.getMessage(),e);
}
return null;
}
static class Dict {
private String key;
private HashMap<String,String> map;
public Dict(String key, HashMap<String, String> map) {
this.key = key;
this.map = map;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public HashMap<String, String> getMap() {
return map;
}
public void setMap(HashMap<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "Dict{" +
"key=" + key +
", map=" + map +
'}';
}
}
public static void main(String [] args){
DictDaoImpl dictDaoImpl = new DictDaoImpl("localhost",6379);
for (int i = 0; i < 5; i++) {
String key = "k" + i;
for (int j = 0; j < 10; j++) {
String val = "v" + j;
String tmpKey = "k" + j;
HashMap<String,String> map = new HashMap<>();
map.put(tmpKey,val);
Dict dict = dictDaoImpl.load(val);
if(dict == null){
dict = new Dict(key,map);
if(dict != null){
String result = dictDaoImpl.store(dict);
// System.out.println(result);
dict = dictDaoImpl.load(key);
System.out.println(dict.toString());
}
}
}
}
}
}