SpringBoot2.X整合Redis緩存
SpringBoot2.x集成SpringCache+Redis
1. 如何實(shí)現(xiàn)自定義ProtostuffRedisSerializer
在SpringBoot2.x環(huán)境下议经,若想使用Redis作為緩存,我們勢(shì)必要選擇一種合適的序列化工具悴了。Redis提供了一個(gè)公共接口org.springframework.data.redis.serializer.RedisSerializer<T>
寇钉。來(lái)完成數(shù)據(jù)的序列化和反序列化刀疙。
public interface RedisSerializer<T> {
@Nullable
byte[] serialize(@Nullable T t) throws SerializationException;
@Nullable
T deserialize(@Nullable byte[] bytes) throws SerializationException;
static RedisSerializer<Object> java() {
return java(null);
}
static RedisSerializer<Object> java(@Nullable ClassLoader classLoader) {
return new JdkSerializationRedisSerializer(classLoader);
}
static RedisSerializer<Object> json() {
return new GenericJackson2JsonRedisSerializer();
}
static RedisSerializer<String> string() {
return StringRedisSerializer.UTF_8;
}
}
我們?nèi)粝胧褂肞rotostuff作為Redis序列化數(shù)據(jù)的工具,那么就必須實(shí)現(xiàn)該接口扫倡。
引入依賴(lài)
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.6.0</version>
</dependency>
實(shí)現(xiàn)接口
public class ProtoStuffRedisSerializer implements RedisSerializer<Object> {
private static final Schema<ObjectWrapper> schema = RuntimeSchema.getSchema(ObjectWrapper.class);
@Override
public byte[] serialize(Object t) throws SerializationException {
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
byte[] bytes;
try {
bytes = ProtostuffIOUtil.toByteArray(new ObjectWrapper(t), schema, buffer);
} finally {
buffer.clear();
}
return bytes;
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length == 0) {
return null;
}
try {
ObjectWrapper objectWrapper = new ObjectWrapper();
ProtostuffIOUtil.mergeFrom(bytes, objectWrapper, schema);
return objectWrapper.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static class ObjectWrapper {
private Object object;
ObjectWrapper() {
}
ObjectWrapper(Object object) {
this.object = object;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
}
2. 性能比較
在Redis的包中谦秧,默認(rèn)提供了幾種序列化的工具,如JDK撵溃、Jackson疚鲤、Fastjson等等,我們自定義實(shí)現(xiàn)序列化方式性能和官方默認(rèn)的差距如何呢缘挑?
public void getAccInfoByTime(String customerId, String accType) {
//獲取Bean對(duì)象
Account accInfo = getAccInfo(customerId, accType);
//JDK的序列化時(shí)間
JdkSerializationRedisSerializer jdk = new JdkSerializationRedisSerializer();
ProtoStuffRedisSerializer pro = new ProtoStuffRedisSerializer();
Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
byte[] jdkBytes = getSerializeTime("JDK序列化", () -> jdk.serialize(accInfo));
byte[] proBytes = getSerializeTime("PRO序列化", () -> pro.serialize(accInfo));
byte[] jacksonBytes = getSerializeTime("JACK序列化", () -> jackson.serialize(accInfo));
Object deserializeTime = getDeserializeTime("JDK反序列化時(shí)間:", () -> jdk.deserialize(jdkBytes));
Object deserializeTime1 = getDeserializeTime("PRO反序列化時(shí)間:", () -> pro.deserialize(proBytes));
Object deserializeTime2 = getDeserializeTime("JACK序列化時(shí)間:", () -> jackson.deserialize(jacksonBytes));
}
/**
* 計(jì)算序列化的耗時(shí)時(shí)間
*
* @param supplier
* @return
*/
private byte[] getSerializeTime(String desc, Supplier<byte[]> supplier) {
long startTime = System.currentTimeMillis();
byte[] bytes = supplier.get();
System.out.println(desc + "時(shí)間:" + (System.currentTimeMillis() - startTime) + " ms");
System.out.println(desc + "大屑:" + bytes.length + " b");
return bytes;
}
/**
* 計(jì)算反的耗時(shí)時(shí)間
*
* @param supplier
* @return
*/
private Object getDeserializeTime(String desc, Supplier<Object> supplier) {
long startTime = System.currentTimeMillis();
Object obj = supplier.get();
System.out.println(desc + (System.currentTimeMillis() - startTime) + " ms");
return obj;
}
執(zhí)行結(jié)果:
JDK序列化時(shí)間:0 ms
JDK序列化大小:865 b
PRO序列化時(shí)間:0 ms
PRO序列化大杏锾浴:155 b
JACK序列化時(shí)間:15 ms
JACK序列化大谢逵睢:447 b
JDK反序列化時(shí)間:1 ms
PRO反序列化時(shí)間:0 ms
JACK反序列化時(shí)間:2 ms
可以看到,protostuff在壓縮時(shí)間惶翻,以及壓縮后的大小上都是比較占優(yōu)的姑蓝。