首页 > 数据库 >Quarkus系列——集成Redis(四)

Quarkus系列——集成Redis(四)

时间:2023-04-03 23:25:37浏览次数:45  
标签:集成 return redis Redis public Quarkus class objectMapper mapObjectMapper

前言

reids是我们在进行后端开发的时候常用到的一个中间件,常用于实现分布式缓存,分布式锁。我们在SpringBoot中可以很方便的通过stater来集成redis。在Quarkus中官方为我们提供了redis的client虽然比起Spring用起来略显简陋但是稍微改造下也能满足我们日常需要。

准备

我们继续之前的项目开发,我们需要在pom文件中引入相关的依赖。

 				<dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-redis-client</artifactId>
        </dependency>

配置

我们首先需要在配置文件中配置redis相关的配置信息。

quarkus.redis.hosts=redis://ip:port
quarkus.redis.password=password

编解码器

我们这里需要用到一个编解码器,我们直接把redisson的JsonJacksonCodec拿来用。++这里简单的说一下为啥不直接用redisson。redisson虽然也出了quarkus的相关jar包,在jvm模式下是可以正常使用的但是当我们尝试打成native镜像的时候会直接失败。++

public class JsonJacksonCodec{
    public static final JsonJacksonCodec INSTANCE = new JsonJacksonCodec();
    @JsonIdentityInfo(generator= ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY,
            getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
            setterVisibility = JsonAutoDetect.Visibility.NONE,
            isGetterVisibility = JsonAutoDetect.Visibility.NONE)
    public static class ThrowableMixIn {
    }
    protected final ObjectMapper mapObjectMapper;
    public JsonJacksonCodec() {
        this(new ObjectMapper());
    }
    public JsonJacksonCodec(ObjectMapper mapObjectMapper) {
        this.mapObjectMapper = mapObjectMapper.copy();
        init(this.mapObjectMapper);
        initTypeInclusion(this.mapObjectMapper);
    }
    protected void initTypeInclusion(ObjectMapper mapObjectMapper) {
        TypeResolverBuilder<?> mapTyper = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.NON_FINAL) {
            @Override
            public boolean useForType(JavaType t) {
                switch (_appliesFor) {
                    case NON_CONCRETE_AND_ARRAYS:
                        while (t.isArrayType()) {
                            t = t.getContentType();
                        }
                        // fall through
                    case OBJECT_AND_NON_CONCRETE:
                        return (t.getRawClass() == Object.class) || !t.isConcrete();
                    case NON_FINAL:
                        while (t.isArrayType()) {
                            t = t.getContentType();
                        }
                        // to fix problem with wrong long to int conversion
                        if (t.getRawClass() == Long.class) {
                            return true;
                        }
                        if (t.getRawClass() == XMLGregorianCalendar.class) {
                            return false;
                        }
                        return !t.isFinal(); // includes Object.class
                    default:
                        // case JAVA_LANG_OBJECT:
                        return t.getRawClass() == Object.class;
                }
            }
        };
        mapTyper.init(JsonTypeInfo.Id.CLASS, null);
        mapTyper.inclusion(JsonTypeInfo.As.PROPERTY);
        mapObjectMapper.setDefaultTyping(mapTyper);
    }
    protected void init(ObjectMapper objectMapper) {
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.setVisibility(objectMapper.getSerializationConfig()
                .getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
        objectMapper.addMixIn(Throwable.class, ThrowableMixIn.class);
    }
    /**
     * 解碼器
     * @param val
     * @return
     */
    public Object decoder(String val){
        try {
            ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
            try (ByteBufOutputStream os = new ByteBufOutputStream(buf)) {
                os.write(val.getBytes());
            }
            return mapObjectMapper.readValue((InputStream) new ByteBufInputStream(buf), Object.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 編碼器
     * @param obj
     * @return
     */
    public String encoder(Object obj){
        ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
        try {
            ByteBufOutputStream os = new ByteBufOutputStream(out);
            mapObjectMapper.writeValue((OutputStream) os, obj);
            return os.buffer().toString(StandardCharsets.UTF_8);
        } catch (IOException e) {
            out.release();
        }
        return null;
    }
}

项目使用

我这里用redis作为我们查询时候的缓存做为示例,我们这里提供一个新增,带过期时间的新增,以及一个删除方法。

@Singleton
public class Cache {


    @Inject
    RedisClient redisClient;


    JsonJacksonCodec codec = JsonJacksonCodec.INSTANCE;

    public <T> void setValue(String key, T value) {

        redisClient.set(Arrays.asList(key, codec.encoder(value)));
    }

    public <T> void setNxValue(String key, T value,Long time) {

        redisClient.set(Arrays.asList(key, codec.encoder(value),time+""));

    }

    public <T> T getValue(String key) {
        final Response response = redisClient.get(key);
        if (response != null) {
            String value = response.toString();
            return (T) codec.decoder(value);

        }
        return null;
    }

    public boolean delete(String key) {
        return redisClient.del(List.of(key)).toBoolean();
    }
}

我们直接在UserService中使用

这里仅简单的做个示例,不考虑在并发情况下缓存不一致的问题。

打包运行

首先我们先连接到我们的redis中看到当前数据库中是没有我们需要的数据的,然后查询。

这里可以看到我们已经把id为1的用户放到redis中了,查询也是没有问题的。这里我们就已经完成了reids的集成。

我们最后再测试一下打包成native镜像看看。

然后运行也是没有问题的。

后记

quarkus为我们提供的redis的client虽然比较简陋但是还是能够实现基本的功能,redisson提供的功能虽然强大但是在native模式下无法使用。所以我们在使用的时候需要根据自己的需求来选择适合自己的方式。

标签:集成,return,redis,Redis,public,Quarkus,class,objectMapper,mapObjectMapper
From: https://www.cnblogs.com/loveletters/p/QuarkusRedis.html

相关文章

  • Quarkus系列——Vert.x应用(番外篇)
    前言由于客观原因(穷)导致博客首页加载时间有点慢,大概需要3秒才能加载出服务端渲染的基础页面。所以想着能够提高首页加载速度,我决定在nginx上做个缓存。为了不影响内容的及时更新,我设置的缓存的有效期仅为10分钟。这样导致在缓存过期后第一次加载页面会cachemiss,所以为了解决这个......
  • Quarkus系列—— RESTEasy与SpringMVC(二)
    简述RestEasy在Quarkus中的作用跟SpringMVC在SpringBoot中类似。简介RESTEasy是JBoss的一个开源项目,提供各种框架帮助你构建RESTfulWebServices和RESTfulJava应用程序。我们以第一部分的代码为例来介绍如何通过RESTEasy的各种注解来开发Web应用,因为RESTEasy实现了JAX......
  • Quarkus系列——快速入门(一)
    介绍Quarkus在日常开发中是可以替代SpringBoot的。Quarkus是RedHat为GraalVM和HotSpot量身定制用程序。特点是启动超快,内存极低,并且在容器编排平台(如Kubernetes)中提供了近乎即时的向上扩展和高密度的内存利用率。并且基于GraalVM,为我们提供了编译成native程序的能力。如果......
  • 019redis3.0集群删除节点
    1:如果删除的节点是主节点,这里我们删除192.168.2.20:7006节点,这个节点有1000个哈希槽首先要把节点中的哈希槽转移到其他节点中,执行下面的命令cd /usr/local/redis3.0/src./redis-trib.rb reshard 192.168.2.20:7000系统会提示我们要移动多少哈希槽,这里移动1000个,因为192.168.2.20......
  • 018redis3.0集群添加节点
    1:首先把需要添加的节点启动cd /usr/local/cluster/mkdir 7006cp /usr/local/cluster/redis.conf  /usr/local/cluster/7006/cd /usr/local/cluster/7006/vi redis.conf##修改redis.conf中的port参数的值为7006redis-server redis.conf2:执行以下命令,将这个新节点添加到集群......
  • 016redis3.0集群简介
    一、基本概念1、redis集群是一个可以在多个节点之间进行数据共享的设施。redis集群提供了以下两个好处1.1将数据自动切分(split)到多个节点1.2当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。2、一个Redis集群包含16384个哈希槽(hashslot),数据库中的每......
  • 014redis的优化&redis工具的使用
    一、redis优化1、精简键名和键值键名:尽量精简,但是也不能单纯为了节约空间而使用不易理解的键名。键值:对于键值的数量固定的话可以使用0和1这样的数字来表示,(例如:male/female、right/wrong)2、当业务场景不需要数据持久化时,关闭所有的持久化方式可以获得最佳的性能内部编码优化(......
  • redis持久化概念
         ......
  • Linux如何让Redis-server在后台运行
    文档课题:Linux如何让Redis-server在后台运行.系统:rhel7.9数据库:redis6.2.61、问题描述redis安装后运行reids-server命令,内容显示如下.此时在该session中无法执行其它操作,当执行ctrl+c关闭界面后才能输入其它命令,但此时redis进程也会被关闭.[[email protected].......
  • 搭建redis主从复制集群环境时,当从库执行slaveof命令时报错“Error condition on socke
    问题描述:搭建redis主从复制集群环境时,当从库执行slaveof命令时报错“ErrorconditiononsocketforSYNC:Noroutetohost”,如下所示:操作系统:rhel7.964位数据库:redis6.2.6主机名:主库leo-redis626-a,从库leo-redis626-b.1、异常重现[[email protected]]#p......