Web菜鸟入门教程 - Radis实现高性能数据库

Redis是用C语言开发的一个高性能键值对数据库,可用于数据缓存,主要用于处理大量数据的高访问负载。

也就是说,如果你对性能要求不高,不用Radis也是可以的。不过作为最自己写的程序有高要求的程序员,自然是要学一下的,毕竟大部分的网站都配置了radis。接下来一三部分来介绍radis:

  • 安装
  • 配置
  • 使用

    Radis安装

    有两种方式安装,一种是下载安装包安装,radis是微软出品的开源项目,代码位于github上,大家可以戳这里下载最新的release包。

    下载完后解压到指定目录后,打开命令行,输入启动命令

    redis-server.exe redis.windows.conf
    

    当然如果你用的是宝塔这种,你可以直接在软件商店搜索并安装,速度更快更便捷。

    不管是windows版本还是宝塔下载的版本,直接启动使用的默认配置。密码为空,端口为6379,host为本机127.0.0.1。好了接下来就是将他整合到Spring里面。

    整合到Springboot

    初一看你会觉得radis挺难的,不知道是什么玩意,但是如果结合前面两篇文章来看,radis的使用也无外乎以下三点:

    • 引入环境
    • 配置Radis
    • 使用RadisTemplate提供的功能实现自己想要的接口。

      使用起来感觉和mybatis的使用也都大差不差嘛。好勒话不多说直接开整。我们现在以接收手机验证码逻辑来整合radis。之所以需要在这个逻辑中引入Radis是因为客户再获取验证码的时候可能不是一次通过,它需要不断地获取验证码,实际上,在固定时间内验证码并不会变,他只是没有收到而已,我们重发一遍就好了。

      引入依赖

      在pom中引入依赖:

       org.springframework.boot spring-boot-starter-data-redis

      然后我们需要配置radis,尽管我们启动的时候使用的默认配置,但是springboot是不知道的,因此我们需要在spring的节点下引入radis的配置:

       redis:
          host: localhost # Redis服务器地址
          database: 0 # Redis数据库索引(默认为0)
          port: 6379 # Redis服务器连接端口
          password: # Redis服务器连接密码(默认为空)
          jedis:
            pool:
              max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
              max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
              max-idle: 8 # 连接池中的最大空闲连接
              min-idle: 0 # 连接池中的最小空闲连接
          timeout: 3000ms # 连接超时时间(毫秒)
      

      上面是关于radis链接的配置,我们还需要添加一些自定义key的配置,这个是radis业务上的。

      # 自定义redis key,在根节点添加
      redis:
        key:
          prefix:
            authCode: "portal:authCode:"
          expire:
            authCode: 120 # 验证码超期时间
      

      实现功能

      配置写好了,我们接下来实现功能。也就是定义一些radis相关的操作方便其他业务代码调用。Radis用的最多的几个功能:

      • 存储数据
      • 获取数据
      • 设置超时
      • 删除数据
      • 自增操作

        我们把这些功能定义好接口:

        package org.lange.study.service;
        /**
         * redis操作Service,
         * 对象和数组都以json形式进行存储
         */
        public interface RedisService { /**
             * 存储数据
             */
            void set(String key, String value);
            /**
             * 获取数据
             */
            String get(String key);
            /**
             * 设置超期时间
             */
            boolean expire(String key, long expire);
            /**
             * 删除数据
             */
            void remove(String key);
            /**
             * 自增操作
             * @param delta 自增步长
             */
            Long increment(String key, long delta);
        }
        

        然后注入StringRedisTemplate,实现RedisService接口:(他其实是RedisTemplate的一个子类,StringRedisTemplate将字符串的处理简化了,RedisTemplate可以处理任意对象,而StringRedisTemplate需要先转换成json字符串才能保存起来)

        多数时候我们频繁操作的数据都是以键值对的相识存在,这也是引入radis的原因。接下来我们通过接入到业务层更深刻理解Radis的使用。

        验证码就两个功能,一个是获取验证码,当用户获取到验证码之后会调用验证接口来验证他填写的验证码是否正确。所以我们先把接口定义一下:

        UmsMemberService.java

        package org.lange.study.service;
        import org.lange.study.common.api.CommonResult;
        /**
         * 会员管理Service
         */
        public interface UmsMemberService { /**
             * 生成验证码
             */
            CommonResult generateAuthCode(String telephone);
            /**
             * 判断验证码和手机号码是否匹配
             */
            CommonResult verifyAuthCode(String telephone, String authCode);
        }
        

        写一个控制器UmsMemberController:

        package org.lange.study.controller;
        import io.swagger.annotations.Api;
        import io.swagger.annotations.ApiOperation;
        import org.lange.study.common.api.CommonResult;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RequestParam;
        import org.springframework.web.bind.annotation.ResponseBody;
        /**
         * 添加根据电话号码获取验证码的接口和校验验证码的接口
         * 会员登录注册管理Controller
         */
        @Controller
        @Api(tags = "UmsMemberController", description = "会员登录注册管理")
        @RequestMapping("/sso")
        public class UmsMemberController { @Autowired
            private UmsMemberService memberService;
            @ApiOperation("获取验证码")
            @RequestMapping(value = "/getAuthCode", method = RequestMethod.GET)
            @ResponseBody
            public CommonResult getAuthCode(@RequestParam String telephone) { return memberService.generateAuthCode(telephone);
            }
            @ApiOperation("判断验证码是否正确")
            @RequestMapping(value = "/verifyAuthCode", method = RequestMethod.POST)
            @ResponseBody
            public CommonResult updatePassword(@RequestParam String telephone,
                                               @RequestParam String authCode) { return memberService.verifyAuthCode(telephone,authCode);
            }
        }
        

        然后我们要实现对应的Service,UmsMemberServiceImpl.java:

        假定我们的验证码业务场景为:

        生成验证码时,将自定义的Redis键值加上手机号生成一个Redis的key,以验证码为value存入到Redis中,并设置过期时间为自己配置的时间(这里为120s)。校验验证码时根据手机号码来获取Redis里面存储的验证码,并与传入的验证码进行比对。

        UmsMemberServiceImpl.java

        package org.lange.study.service.impl;
        import org.lange.study.common.api.CommonResult;
        import org.lange.study.service.RedisService;
        import org.lange.study.service.UmsMemberService;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.stereotype.Service;
        import org.springframework.util.StringUtils;
        import java.util.Random;
        @Service
        public class UmsMemberServiceImpl implements UmsMemberService { @Autowired
            private RedisService redisService;
            @Value("${redis.key.prefix.authCode}")
            private String REDIS_KEY_PREFIX_AUTH_CODE;
            @Value("${redis.key.expire.authCode}")//这个@value就是读取前面的配置
            private Long AUTH_CODE_EXPIRE_SECONDS;
            /**
             * 生成的时候设置超时间并保存到radis,然后将验证码返回给客户端
             */
            @Override
            public CommonResult generateAuthCode(String telephone) { StringBuilder sb = new StringBuilder();
                Random random = new Random();
                for (int i = 0; i < 6; i++) { sb.append(random.nextInt(10));
                }
                //验证码绑定手机号并存储到redis
                redisService.set(REDIS_KEY_PREFIX_AUTH_CODE + telephone, sb.toString());
                redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE + telephone, AUTH_CODE_EXPIRE_SECONDS);
                return CommonResult.success(sb.toString(), "获取验证码成功");
            }
            /**
             * 对输入的验证码进行校验,调用get方法就好了
             */
            @Override
            public CommonResult verifyAuthCode(String telephone, String authCode) { if (StringUtils.isEmpty(authCode)) { return CommonResult.failed("请输入验证码");
                }
                String realAuthCode = redisService.get(REDIS_KEY_PREFIX_AUTH_CODE + telephone);
                boolean result = authCode.equals(realAuthCode);
                if (result) { return CommonResult.success(null, "验证码校验成功");
                } else { return CommonResult.failed("验证码不正确");
                }
            }
        }
        

        在上述案例中,我只用到了Radis的设置和获取以及设置有效时间的方法,Radis的其他功能大家可以根据需要去探索。

        运行

        我们可以使用swagger进行接口调试

        访问Swagger的API文档地址http://localhost:8080/swagger-ui.html ,对接口进行测试。