前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用REDIS做限定登录和LIST缓存?

如何使用REDIS做限定登录和LIST缓存?

作者头像
技术从心
发布2019-11-14 18:47:03
6910
发布2019-11-14 18:47:03
举报
文章被收录于专栏:技术从心技术从心

在工作中redis还是经常被使用到,所以对于一些简单的redis的使用还是要会使用的,在学习的过程中用用单机的就行,真实的生产环境用单机的redis还是较少的。

首先我们使用docker安装下redis,关于docker还不会用的可以去百度学习下,安装使用还是非常简单的。

1.拉取下redis镜像

docker pull redis:3.2

2.启动容器

dcker run -p 6699:6379 --name myredis -v $PWD/redis.conf:/etc/redis/redis.conf -v $PWD/data:/data -d redis:3.2 redis-server /etc/redis/redis.conf --appendonly yes --requirepass "123456"

命令说明:

--name myredis : 指定容器名称,这个最好加上,不然在看docker进程的时候会很尴尬。
-p 6699:6379 : 端口映射,默认redis启动的是6379,至于外部端口,随便玩吧,不冲突就行。
-v $PWD/redis.conf:/etc/redis/redis.conf : 将主机中当前目录下的redis.conf配置文件映射。
-v $PWD/data:/data -d redis:3.2 :将主机中当前目录下的data挂载到容器的/data
--redis-server --appendonly yes :在容器执行redis-server启动命令,并打开redis持久化配置
--requirepass "123456" 设置redis密码为123456

docker ps 查看下运行状态

使用RedisDesktopManager工具连接下redis测试下

接下就可以集成redis操作起来了。

spring:
  redis:
    database: 5 #redis中的db5(在命令行可用 select 5 来切换到当前的db)
    # 配置Redis的主机地址
    host: 192.168.1.174
    port: 6379
    password: 123456
    timeout: 5000
    jedis:
      pool:
        # 连接池中的最大空闲连接,默认值也是8。
        max-idle: 500
        # 连接池中的最小空闲连接,默认值也是0。
        min-idle: 50
        # 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
        max-active: 1000
        # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
        max-wait: 2000

封装一下java操作redis的工具类

package lee.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author :lyj
 * @email: : iclyj@iclyj.cn
 * @date :2019/11/5
 */
@Service
@Slf4j
public class RedisServiceUtil {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public static final  String userStringKey  = "lyj:";

    private RedisTemplate<Serializable, Object> redisTemplate;

    /**
     * set redis : string类型
     * @param key key
     * @param value value
     */
    public void setString(String key,String value){
        ValueOperations<String,String> valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.set(key,value);
    }

    public String getString(String key){
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * set redis: hash类型
     * @param key key
     * @param filedKey filedkey
     * @param value value
     */
    public void setHash(String key, String filedKey, String value){
        HashOperations<String, Object, Object> hashOperations = stringRedisTemplate.opsForHash();
        hashOperations.put(key,filedKey, value);
    }

    /**
     * get redis: hash类型
     * @param key key
     * @param filedkey filedkey
     * @return
     */
    public String getHash(String key, String filedkey){
        return (String) stringRedisTemplate.opsForHash().get(key, filedkey);
    }


    /**
     * set redis:list类型
     * @param key key
     * @param value value
     * @return
     */
    public long setList(String key, String value){
        ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
        return listOperations.leftPush(key, value);
    }

    /**
     * get redis:list类型
     * @param key key
     * @param start start
     * @param end end
     * @return
     */
    public List<String> getList(String key, long start, long end) {
        return stringRedisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 设置key失效时间
     * @param key key
     * @param timeout timeout
     * @return
     */
    public boolean setTimeOut(String key, long timeout){
        return stringRedisTemplate.expire(key,timeout, TimeUnit.SECONDS);
    }

    /**
     * 根据key删除值
     * @param key
     * @return
     */
    public boolean delKey(String key){
        return stringRedisTemplate.delete(key);
    }

    /**
     * 设置值并设置失效时间
     * @param key
     * @param value
     * @param timeOut
     */
    public void setCachesData(String key,String value,long timeOut){
        if (log.isDebugEnabled()) {
            log.debug("String, String, int - start"); //$NON-NLS-1$
        }
        setString(key,value);
        setTimeOut(key,timeOut);
        if (log.isDebugEnabled()) {
            log.debug("String, String, int - start"); //$NON-NLS-1$
        }
    }

    /**
     * 从缓存中删除数据
     *
     * @param key
     * @return
     */
    public boolean removeValue(String key) {
        if (log.isDebugEnabled()) {
            log.debug("String - start"); //$NON-NLS-1$
        }

        boolean returnlong = delKey(key);
        if (log.isDebugEnabled()) {
            log.debug("String - end"); //$NON-NLS-1$
        }
        return returnlong;
    }


    /**
     * 批量删除对应的value
     * @param keys
     */
    public void remove(final String...  keys){
       for (String key : keys){
          remove(key);
       }
    }

    /**
     * 批量删除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate
                .opsForValue();
        result = operations.get(key);
        return result;
    }


    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
//            ValueOperations<Serializable, Object> operations = redisTemplate
//                    .opsForValue();
//            operations.set(key, value);
            redisTemplate.opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate
                    .opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    public  void batchDel(String... pattern){
        for (String kp : pattern) {
            redisTemplate.delete(redisTemplate.keys(kp + "*"));
        }
    }

    public Set<Object> getKeys(){
        return redisTemplate.opsForSet().members("*".getBytes());
    }

    public void setRedisTemplate(
            RedisTemplate<Serializable, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

}

现在实现第一个功能限定用户登录非常的简单

只需要登录成功之后将用户信息设置到redis中给定一个过期时间,登录之前根据key值去查询下redis是否存在当前用户如果有就直接返回当前用户已被登录。当然登出的时候我们也要做相应的操作。

接下来完成第二个功能我们需要用到一个工具类

package lee.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

/**
 * @author :lyj
 * @email: : iclyj@iclyj.cn
 * @date :2019/11/6
 */
public class JsonUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    public JsonUtils() {
    }

    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException var2) {
            var2.printStackTrace();
            return null;
        }
    }

    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception var3) {
            var3.printStackTrace();
            return null;
        }
    }

    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, new Class[]{beanType});

        try {
            List<T> list = (List)MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception var4) {
            var4.printStackTrace();
            return null;
        }
    }

}

相同的道理在查询之前将值转成josn设置到redis中,查询之前根据设置的key值查询出来value值将转换为list返回出去即可。

到这我们redis的操作的两个简单的功能就完成了,操作起来还是非常的简单的,但是到了真实的项目中往往只会这些简单的操作还是不行的。

可以思考思考如下的问题:

答案可以到这里查看:https://doocs.github.io/advanced-java/#/?id=%e7%bc%93%e5%ad%98

1.在项目中缓存是如何使用的?缓存如果使用不当会造成什么后果?

2.Redis 和 Memcached 有什么区别?Redis 的线程模型是什么?为什么单线程的 Redis

3.比多线程的 Memcached 效率要高得多?

4.Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?

5.Redis 的过期策略都有哪些?手写一下 LRU 代码实现?

6.如何保证 Redis 高并发、高可用?Redis 的主从复制原理能介绍一下么?Redis 的哨兵原理能介绍一下么?

.Redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?

8.Redis 集群模式的工作原理能说一下么?在集群模式下,Redis 的 key 是如何寻址的?

9.分布式寻址都有哪些算法?了解一致性 hash 算法吗?如何动态增加和删除一个节点?

10.了解什么是 redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?系统该如何应对

11.这种情况?如何处理 Redis 的穿透?

12.如何保证缓存与数据库的双写一致性?

13.Redis 的并发竞争问题是什么?如何解决这个问题?了解 Redis 事务的 CAS 方案吗?14.生产环境中的 Redis 是怎么部署的?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术从心 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在工作中redis还是经常被使用到,所以对于一些简单的redis的使用还是要会使用的,在学习的过程中用用单机的就行,真实的生产环境用单机的redis还是较少的。
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档