springboot luttuc redis 集成protobuf,手动序列化反序列化

前置需知:
1.本文章和网上大部分博客配置不太一样,各位看官要分析一下自己的需求。集成protobuf 本文章主要是手动调用protobuf的序列化方法,而不是交由springboot 去做,会偏向原生java 使用方式

2.由于为了和公司其他的项目达成一致,所以版本,依赖 都尽量保证一致,所以版本需要各位看官具体决定了哈(团队使用时不同版本会有冲突)
另外:看了网上用了protostuff https://blog.csdn.net/shenTiBeiTaoKongLa/article/details/107123596可以试一下(因为我没试,可以反馈成功与否哦)。

3.考虑到其他项目使用原生的luttuce,不支持key/value 结构不一致,所以对redis key field value 都进行压缩了(关注官网变更哦,后面会支持。或者看一下sprinboot-redis的源码(sprinboot支持的),对原生的Luttuce集成一下)在这里插入图片描述
在这里插入图片描述

4.由于初期设计的.proto文件,可能存在压缩不完全的问题(后面会具体聊),大家可以见仁见智了啊,欢迎反馈

话多说了,先上配置
pom依赖如下
<protobuf.version>3.24.0</protobuf.version>

  <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>${protobuf.version}</version> <!-- protobuf -->
            </dependency>
            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java-util</artifactId> <!--protobuf 工具类-->
                <version>${protobuf.version}</version>
            </dependency>
            <!-- Spring Data Redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>2.11.1</version> <!-- 请检查最新版本 -->
            </dependency>

继承RedisTemplate 对象 生成个性化RedisTemplate bean,配置序列化反序列化,自定义序列化RedisSerializer<byte[]> byteRedisSerializer = new RedisSerializer() 重写内部类是最核心的地方!

@Component
@AutoConfigureAfter(RedisAutoConfiguration.class)
@Import({RedisAutoConfiguration.class})
@Slf4j
public class ProtobufRedisTemplate extends RedisTemplate<Object, Object> {

    public ProtobufRedisTemplate( @Autowired() LettuceConnectionFactory lettuceConnectionFactory) {
        ProtobufRedisSerializer protobufRedisSerializer = new ProtobufRedisSerializer(Object.class);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        setConnectionFactory(lettuceConnectionFactory);
        afterPropertiesSet();
       **-- 重写RedisSerializer 序列反序列化方法,直接返回数据 ,核心!!!!**
        RedisSerializer<byte[]> byteRedisSerializer = new RedisSerializer() {

            @Override
            public byte[] serialize(Object o) throws SerializationException {
                if (o instanceof byte[]){
                    return (byte[])o;
                }
                return new byte[0];
            }

            @Override
            public byte[] deserialize(byte[] bytes) {
                return bytes;
            }
        };


        setKeySerializer(byteRedisSerializer);
        setValueSerializer(byteRedisSerializer);

        setHashKeySerializer(byteRedisSerializer);
        setHashValueSerializer(byteRedisSerializer);

        logger.warn("the Lettuce-protobuf starting success,date is -->"+ new Date());
    }
}

redis 工具类

@Component
@Slf4j
public class RedisUtils {

    @Autowired
    private ProtobufRedisTemplate protobufRedisTemplate;

    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean p_hmset(byte[] key, Map<byte[], byte[]> map, int time) {
        try {
            protobufRedisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
        /**
     * HashGetAll
     *
     * @return 值
     */
    public Map<byte[], byte[]> p_hgetall(byte[] key) {
        Map<Object, Object> map = protobufRedisTemplate.opsForHash().entries(key);
        Map<byte[], byte[]> resultMap = map.entrySet().stream().collect(Collectors.toMap(entry -> (byte[]) entry.getKey(), entry -> (byte[]) entry.getValue()));
        return resultMap;
        //return protobufRedisTemplate.opsForHash().entries(key);
    }
}
    

测试的代码

        RedisData.RedisValue redisValue2 = RedisData.RedisValue.newBuilder()
                .putValue("master_id", createRedisObject("xxxx"))
                .putValue("item_code", createRedisObject(""))
                .putValue("content_id", createRedisObject("xxxx"))
                .build();

        final byte[] byteArray2 = redisValue2.toByteArray();
        //序列化

        Map<byte[], byte[]> test = new HashMap<>();
        final byte[] byteField1 = RedisData.RedisKey.newBuilder().setKey("xxxx").build().toByteArray();
        test.put(byteField1, byteArray);
        final byte[] byteField2 = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();
        test.put(byteField2, byteArray2);

        byte[] bytes_key = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();
        byte[] bytes_value = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();

        redisUtils.p_hmset(bytes_value, test, 2592000);
        redisUtils.p_set(bytes_key, bytes_key, 2592000);

.proto文件数据结构如下(仅供参考):
这个是对可变的Map 进行压缩的,可能会压缩不完全
可以把map<string,RedisObject> value=1; 改成map<RedisKey,RedisObject> value=1;

syntax = "proto3";

package xxxx;
import public "google/protobuf/timestamp.proto";
option optimize_for=CODE_SIZE;
option java_outer_classname = "RedisData";

message RedisValue{
  map<string,RedisObject> value=1;
}


message RedisKey{
  string key=1;
}

message RedisObject{
  oneof value {
    string string_value = 1;
    int32 int_value = 2;
    double double_value = 3;
    google.protobuf.Timestamp Timestamp = 4;
  }
}

使用maven 将proto文件编译成java文件

 <os.detected.classifier>windows-x86_64</os.detected.classifier>
 <build>
        <extensions>
            <!--主要用于获取并设置与操作系统相关的属性-->
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <!--protobuf plugins 插件-->
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>
                        com.google.protobuf:protoc:3.24:exe:${os.detected.classifier}
                    </protocArtifact>
                    <!--默认值,proto源文件路径-->
                    <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

在这里插入图片描述
使用方式:直接copy ,当做普通的java类使用就可以了,注意要和proto文件里面的package xxxx; 路径一致,否则会报错。

效果如下
在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值