Jedis

  • 即,Java语言连接redis服务

步骤

  • 导包
    <dependency>
    	 <groupId>redis.clients</groupId>
    	 <artifactId>jedis</artifactId>
    	 <version>2.9.0</version>
    </dependency>
    
  • 连接
    @Test
      public void testConnect() {
        Jedis jedis = new Jedis("119.23.64.216", 6379);
        String value = jedis.get("key");
        System.out.println(value);
        jedis.close();
      }
    
  • 通过Jedis池获取Jedis
    JedisPoolConfig config = new JedisPoolConfig();  // Jedis的配置
    config.setMaxTotal(maxTotal);  // 最大连接数
    config.setMaxIdle(maxIdle);  // 最大空闲数
    JedisPool jedisPool = new JedisPool(config, host, port);
    Jedis jedis = jedisPool.getResource();
    ...
    jedis.close();
    

案例:服务调用次数控制

  • 设定A、B、C三个用户,A用户限制10次/分调用,B用户限制20次/分调用,C用户限制30次/分调用
  • Jedis 获取类
    public class JedisUtils {
      private static JedisPool jedisPool = null;
      private static String host = null;
      private static int port;
      private static int maxTotal = 30;  // 最大连接数
      private static int maxIdle = 10;  // 最大空闲数
    
      static {
        ResourceBundle redis = ResourceBundle.getBundle("redis");
        host = redis.getString("host");
        port = Integer.parseInt(redis.getString("port"));
        try {
          maxTotal = Integer.parseInt(redis.getString("maxTotal"));
        } catch (MissingResourceException e) {
          e.printStackTrace();
        }
        try {
          maxIdle = Integer.parseInt(redis.getString("maxIdle"));
        } catch (MissingResourceException e) {
          e.printStackTrace();
        }
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        jedisPool = new JedisPool(config, host, port);
      }
    
      public static Jedis getJedis() {
        return jedisPool.getResource();
      }
    }
    
    # 配置文件 redis.properties
    host=119.23.64.216
    port=6379
    maxTotal=30
    maxIdle=10
    
  • 服务接口
    public interface Service {
      void service();
    }
    
  • 服务接口的实现方法
    public class CountService implements Service {
      private int maxTime;  // 最大次数
      private int id;  // 用户id
      private int liveSeconds;  // 限制的单位时间
    
      public CountService() {
      }
    
      public CountService(int maxTime, int id, int liveSeconds) {
        this.maxTime = maxTime;
        this.id = id;
        this.liveSeconds = liveSeconds;
      }
    
    
      @Override
      public void service() {
        try (Jedis jedis = JedisUtils.getJedis()) {
          // 这个代码会出现bug,当刚好检测到还有数据,但数据已经超出范围的时候,跳过了setex一步;到了incr的时候,如果突然数据到时间了,消失了,就会出现num从1开始的情况。
          // 因此,只能在incr之后,做一个判断,判断当前数值是否异常。
          String value = jedis.get("id:" + id);
          if (value == null) {
            jedis.setex("id:" + id, liveSeconds, String.valueOf(Long.MAX_VALUE - maxTime));
          }
          try {
            Long num = jedis.incr("id:" + id);
            // 判断是否异常,如果异常,就直接重新set一次
            if (num < Long.MAX_VALUE - maxTime) {
              jedis.setex("id:" + id, liveSeconds, String.valueOf(Long.MAX_VALUE - maxTime));
              num = jedis.incr("id:" + id);
            }
            business(maxTime - (Long.MAX_VALUE - num));
          } catch (JedisDataException e) {
            System.out.println("使用已经到达次数上限,请升级会员级别");
          }
        }
      }
    
      private void business(long val) {
        System.out.println("执行" + id + "的第" + val + "次业务");
      }
    }
    
  • Runnable 实现方法。Service以组合的方式进入方法,降低耦合,可以装配不同的Service实现类。
    public class ServiceTask implements Runnable {
      private Service service;
      private static final Random random = new Random();
    
      public ServiceTask() {
      }
    
      public ServiceTask(Service service) {
        this.service = service;
      }
    
      @Override
      public void run() {
        while (true) {
          service.service();
          try {
            Thread.sleep(100 + random.nextInt(20));
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }
    
  • 调用。切记:多线程不能用junit测试!
    public class ServiceTest {
      public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        threadPool.execute(new ServiceTask(new CountService(10, 1, 60)));
        threadPool.execute(new ServiceTask(new CountService(20, 2, 60)));
        threadPool.execute(new ServiceTask(new CountService(30, 3, 60)));
        threadPool.shutdown();
      }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值