初探Springboot-Redis

仅用缓存功能,不与JPA结合。Redis及Docker的基础用法自行查询。

环境准备,安装配置

Win7

1.官网下载redis, 在解压后的目录打开cmd(按住shift, 鼠标右键),输入

1
redis-server redis.windows.conf

出现如下界面为启动成功
redis_win-start

2.再打开一个cmd,执行 redis-cli 如下

redis_win_cli

3.在系统变量Path中添加redis目录,下次执行redis-server和redis-cli不必在redis安装目录下

redis_win_path

Centos7

1.安装redis

1
yum install -y redis

2.配置

1
2
3
vim /etc/redis.config,更改配置,如
bind 由127.0.0.1改为0.0.0.0, 可供外网访问
requirepass解开注释,设置密码

3.连接

1
redis-cli -h 127.0.0.1 -p 6379 -a root

Centos7 Docker

1.官网docker.io经常不可访问,加入镜像

1
2
3
vim /etc/docker/daemon.json
可加如下镜像
"registry-mirror" : ["http://33bfbfda.m.daocloud.io"]

2.查看下载redis镜像

1
2
docker search redis
docker pull redis

3.起redis服务

1
docker run -d --name myredis -p 6379:6379 -v $PWD/data:/data c53 --requirepass root --appendonly yes

参数解读:
-d : 后台运行

–name : 命名容器名

-p 6379:6379 : 指定端口映射,前一个6379为宿主机端口号,后一个6379为容器端口号

-v $PWD/data:/data : 将主机中当前目录下的data挂载到容器的/data

–requirepass root : 设置密码为root,保护 Redis 服务器

–redis-server –appendonly yes :在容器执行redis-server启动命令,并打开redis持久化配置

4.连接redis-server

1
redis-cli -h host -p port -a password

或者如下图
redis-centos-connect

注:auth password 和配置文件中的密码相符,服务器会返回 OK 并开始接受命令输入; 密码错误或不输入密码,虽然可以连接上redis,但不可使用其他redis命令。redis容易遭受密码猜测攻击,所以要确保密码足够复杂和足够长。

SpringBoot 引入 Redis

1.引入依赖, 版本与spring-boot-starter-parent一致

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>

2.从配置中获取redis连接信息,若从application.properties中获取,则设置如下

1
2
3
4
5
6
7
8
9
10
## redis服务器地址
redisCon.host = 115.159.204.52
## 端口号
redisCon.port = 6379
## 密码
redisCon.password = root
## 数据库索引
redisCon.dbIndex = 0
## 连接超时时间,单位毫秒
redisCon.timeout = 5000

配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "redisCon")
@Component("redisCon")
public class RedisCon {
/**
* redis服务器地址
*/
private String host;
/**
* 端口号
*/
private int port;
/**
* 密码
*/
private String password;
/**
* 数据库索引
*/
private int dbIndex;
/**
* 连接超时时间,单位毫秒
*/
private int timeout;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getDbIndex() {
return dbIndex;
}
public void setDbIndex(int dbIndex) {
this.dbIndex = dbIndex;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
}

3.配置连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisConfig {
private final RedisCon redisCon;
@Autowired
public RedisConfig(RedisCon redisCon) {
this.redisCon = redisCon;
}
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisCon.getHost());
factory.setPort(redisCon.getPort());
factory.setPassword(redisCon.getPassword());
factory.setTimeout(redisCon.getTimeout());
factory.setDatabase(redisCon.getDbIndex());
factory.afterPropertiesSet();
return factory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
return template;
}
}

4.方法封装,以HashMap为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisUtil {
private static RedisTemplate redisTemplate;
private static HashOperations<String, String, Object> hashOperations;
@Autowired
@SuppressWarnings("unchecked")
public RedisUtil(RedisTemplate redisTemplate) {
RedisUtil.redisTemplate = redisTemplate;
RedisUtil.hashOperations = RedisUtil.redisTemplate.opsForHash();
}
/**
* 获取指定hash值
*
* @param hashName hash表名称
* @param hashKey hash表key
* @return hash value, 若不存在返回null
*/
public static Object getHashValue(String hashName, String hashKey) {
return RedisUtil.hashOperations.get(hashName, hashKey);
}
/**
* 写入指定的hash值
*
* @param hashName hash表名称
* @param hashKey hash表key
* @param hashValue hash value
* @return 写入成功返回true
*/
public static boolean setHashValue(String hashName, String hashKey, Object hashValue) {
RedisUtil.hashOperations.put(hashName, hashKey, hashValue);
return true;
}
/**
* 增加指定的HashKey
*/
public static Long incrementHashValue(String hashName, String hashKey, Long increment) {
return RedisUtil.hashOperations.increment(hashName, hashKey, increment);
}
/**
* 删除指定数据
*/
@SuppressWarnings("unchecked")
public static void deleteKey(String key) {
RedisUtil.redisTemplate.delete(key);
}
}

5.测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import com.kodgames.bus.component.config.redis.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@Api(value = "测试接口")
@RequestMapping(path = "testtest")
@RestController
public class TestController {
private static Logger logger = LoggerFactory.getLogger(TestController.class);
@ApiOperation(value = "测试redis hash")
@RequestMapping(path = "hash/redis", method = RequestMethod.GET)
public Long testHashRedis() {
String hashName = "testHash";
String hashKey = "testKey1";
Long hashValue = 123L;
Long firstGetHashValue = (Long) RedisUtil.getHashValue(hashName, hashKey);
logger.info("firstGetHashValue: {}", firstGetHashValue);
logger.info("set hash value: {}", RedisUtil.setHashValue(hashName, hashKey, hashValue));
logger.info("secondGetHashValue: {}", RedisUtil.getHashValue(hashName, hashKey));
RedisUtil.deleteKey(hashName);
logger.info("thirdGetHashValue: {}", RedisUtil.getHashValue(hashName, hashKey));
String hashIncre = "incrementMap";
String hashKeyIncre = "incrementKey";
long num = RedisUtil.incrementHashValue(hashIncre, hashKeyIncre, 1L);
logger.info("incrementValue: {}", num);
return num;
}
}

测试结果如下:
redis_test_request

redis_test_result

共享sessoin

为多点部署,借助redis实现共享session

1.引入依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>

2. 注解

只需在上述的RedisConfig加一行注解即可

1
2
3
4
5
@Component
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisConfig {
//省略
}

3.测试接口

1
2
3
4
5
6
7
8
9
10
@ApiOperation(value = "测试session")
@GetMapping("session/uid")
public Object getSessionUid(HttpSession session){
UUID uid = (UUID) session.getAttribute("uid");
if (uid == null) {
uid = UUID.randomUUID();
}
session.setAttribute("uid", uid);
return session.getAttribute("uid");
}

请求结果如下:
redis_session_request
连上redis,查看
session_redis_cli

4.身份验证

未使用redis session前,重启服务后,session失效,需重新验证。
接入redis session后,重启服务,访问,无需身份验证,session已存储在redis中。