当前位置: 首页 > news >正文

SSM项目集成redis、Linux服务器安装redis

在SSM(Spring + Spring MVC + MyBatis)项目中引入Redis主要分为以下步骤,确保配置正确并能在业务中灵活使用:

1. 添加Redis依赖​

在Maven的pom.xml中添加Spring Data Redis和Jedis(或Lettuce)依赖:

	<!-- Spring Data Redis --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.5.2.RELEASE</version></dependency><!-- Jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.1</version></dependency><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>5.1.4.RELEASE</version></dependency>

​2. 配置Redis连接参数​

在Spring的配置文件(如srping-redis.xml)中配置Redis连接工厂和连接池:

	<!-- jedis 连接池配置 --><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="${redis.maxIdle}"/><property name="maxWaitMillis" value="${redis.maxWait}"/><property name="testOnBorrow" value="${redis.testOnBorrow}"/></bean><!-- redis连接工厂 --><bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="poolConfig" ref="poolConfig"/><property name="port" value="${redis.port}"/><property name="hostName" value="${redis.host}"/><property name="password" value="${redis.password}"/><property name="database" value="7"/><property name="timeout" value="${redis.timeout}"></property></bean><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory"/><property name="keySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="valueSerializer"><bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/></property></bean><!-- 配置 key 和 value 的序列化器 --><bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

​3. Redis连工具类

import com.alibaba.fastjson.JSON;
import io.lettuce.core.RedisConnectionException;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import zjhuiwan.cn.controller.fontPage.IndexController;
import zjhuiwan.cn.entity.NullCacheValue;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** Redis工具类**/
@Service
public class RedisPMCacheService {private static final Logger log = LoggerFactory.getLogger(RedisPMCacheService.class);private final StringRedisSerializer serializer = new StringRedisSerializer();@Resourceprivate RedisTemplate<String, Object> redisTemplate;private ValueOperations<String, Object> valueOperations;private HashOperations<String, String, Object> hashOperations;@PostConstructpublic void init(){setRedisTemplate(redisTemplate);}public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;if (redisTemplate != null) {valueOperations = redisTemplate.opsForValue();hashOperations = redisTemplate.opsForHash();}}public RedisTemplate<String, Object> getRedisTemplate() {return redisTemplate;}public void setValueOperations(ValueOperations<String, Object> valueOperations) {this.valueOperations = valueOperations;}/*** 默认过期时长,单位:秒*/private final static long DEFAULT_EXPIRE = 60 * 60 * 24;/*** 不设置过期时长*/private final static long NOT_EXPIRE = -1;public void set(String key, Object value, long expire) {try {if (expire != NOT_EXPIRE) {expire = getExpire(key, expire);valueOperations.set(key, value, expire, TimeUnit.SECONDS);} else {valueOperations.set(key, value);}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}public void set(String key, Object value) {set(key, value, DEFAULT_EXPIRE);}public <V> V get(String key, Class<V> clazz, Callable<? extends V> callable, long expire) {Object value = null;try {value = valueOperations.get(key);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("{}", ex);}if (value instanceof NullCacheValue) {V result = getDefault(callable);if (result == null) {return null;}set(key, result, expire);return result;}if (value != null) {if (clazz.isAssignableFrom(value.getClass())) {return (V) value;} else if (value instanceof String) {return parseToObj(value.toString(), clazz);}return null;}V result = getDefault(callable);if (result == null) {return null;}set(key, result, expire);return result;}public <V> V get(String key, Callable<? extends V> callable, long expire) {Object value = null;try {value = valueOperations.get(key);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("{}", ex);}if (value instanceof NullCacheValue) {V result = getDefault(callable);if (result == null) {return null;}set(key, result, expire);return result;}if (value != null) {try {return (V) value;} catch (Exception e) {log.error("callable", e);}}V result = getDefault(callable);if (result == null) {return null;}set(key, result, expire);return result;}/*** 不存null 值** @param key* @param clazz* @param callable* @param <V>* @return*/public <V> V get(String key, Class<V> clazz, Callable<? extends V> callable) {Object value = null;try {value = valueOperations.get(key);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("{}", ex);}if (value instanceof NullCacheValue) {V result = getDefault(callable);if (result != null) {set(key, result);}return result;}if (value != null) {if (clazz.isAssignableFrom(value.getClass())) {return (V) value;} else if (value instanceof String) {return parseToObj(value.toString(), clazz);}return null;}V result = getDefault(callable);if (result == null) {return null;}set(key, result);return result;}public static <T> T parseToObj(String content, Class<T> classz) {if (content == null || content.length() == 0){return null;}try {return JSON.parseObject(content, classz);} catch (Exception e) {log.error(" content:"+content+ "json反序列化失败", e);}return null;}public <V> V get(String key, Callable<? extends V> callable) {Object value = null;try {value = valueOperations.get(key);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("{}", ex);}if (value instanceof NullCacheValue) {V result = getDefault(callable);if (result != null) {set(key, result);}return result;}if (value != null) {try {return (V) value;} catch (Exception e) {log.error("callable", e);}}V result = getDefault(callable);if (result == null) {return null;}set(key, result);return result;}public <T> T get(String key, Class<T> clazz, long expire) {Object value = get(key, expire);if (value == null) {return null;}if (clazz.isAssignableFrom(value.getClass())) {return (T) value;} else if (value instanceof String) {return parseToObj(value.toString(), clazz);}log.error("不能解析数据 key:{} value:{}", key, value);return null;}public <T> T get(String key, Class<T> clazz) {return get(key, clazz, NOT_EXPIRE);}public Object get(String key, long expire) {try {Object value = valueOperations.get(key);if (expire != NOT_EXPIRE) {expire = getExpire(key, expire);redisTemplate.expire(key, expire, TimeUnit.SECONDS);}if (value instanceof NullCacheValue) {return null;}return value;} catch (RedisConnectionException ex) {//连接失败次数increaseError();return null;} catch (Exception ex) {log.error("get from cache error", ex);return null;}}public Object get(String key) {return get(key, NOT_EXPIRE);}public void delete(String key) {try {redisTemplate.delete(key);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}}public void matchingHashRemove(String key) {Set<String> keys = redisTemplate.keys(key);try {if(CollectionUtils.isNotEmpty(keys)){redisTemplate.delete(keys);}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}}/*** todo 待完善* @param key* @param hashKeys*/public void matchingHashRemove(String key,String... hashKeys) {Set<String> keys = redisTemplate.keys(key);try {Object[] args = new Object[hashKeys.length];System.arraycopy(hashKeys, 0, args, 0, hashKeys.length);if(CollectionUtils.isNotEmpty(keys)){for(String val:keys){hashOperations.delete(val, args);}}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}}public void clear(String key) {if (key == null || key.length() == 0) {return;}try {Set<String> sets = redisTemplate.keys(key);redisTemplate.delete(sets);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}}public boolean hasKey(String key) {if (key == null || key.length() == 0) {return false;}try {Boolean sets = redisTemplate.hasKey(key);return sets;} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("hasKey cache error", ex);}return false;}/*** 使用随机过期时间,解除缓存压力** @param key 本地操作不能使用前缀* @return*/private long getExpire(String key, long expire) {if (expire == NOT_EXPIRE) {return expire;}//取一个过期随机码,随机取之空间为 expire 的0.5 ~ 1.5倍 + 5s,避免redis集中命中return ((Double) (5 + (Math.random() + 0.5) * expire)).longValue();}Random random = new Random();/*** 使用随机过期时间,解除缓存压力** @return*/private long getExpireRand10Minitus(long expire) {if (expire == NOT_EXPIRE) {return expire;}return random.nextInt(1) + expire;}/*** 如果无效,暂时停止五分钟** @return*/private boolean checkValid() {/*if (firstErrorTime > 0 && errorCount.get() > 0) {return false;}*/return true;}private synchronized void increaseError() {/* int count = errorCount.getAndIncrement();if (count <= 0) {firstErrorTime = System.currentTimeMillis();}*/}public Long getLongValue(final String key) {try {return (long) redisTemplate.execute((RedisCallback<Long>) connection -> {byte[] result = connection.get(serializer.serialize(key));String s = serializer.deserialize(result);return parseLong(s);});} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}return 0L;}public long getAndIncrement(String key) {try {long result = redisTemplate.opsForValue().increment(key,0l);if (result > Integer.MAX_VALUE) {redisTemplate.delete(key);result = 0;}return result;} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("delete cache error", ex);}return 0L;}public void flushDb() {redisTemplate.execute((RedisCallback) connection -> {connection.flushDb();return "ok";});}public void hashAdd(String key, String hashKey, Object value, Integer expired) {if (hashOperations == null) {return;}try {hashOperations.put(key, hashKey, value);if (expired != null && expired > 0) {Long time = getExpireRand10Minitus(expired);redisTemplate.expire(key, time, TimeUnit.SECONDS);}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}public Boolean hashExists(String key, String hashKey) {if (hashOperations == null) {return false;}try {return hashOperations.hasKey(key, hashKey);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return false;}public void hashAdd(String key, HashMap<String, Object> value) {if (hashOperations == null) {return;}try {hashOperations.putAll(key, value);} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}private <V> V getDefault(Callable<? extends V> callable) {if (callable == null) {return null;}try {return callable.call();} catch (Exception e) {return null;}}public <V> V hashGet(String key, String hashKey, Class<V> tClass) {if (hashOperations == null || tClass == null) {return null;}try {Object value = hashOperations.get(key, hashKey);if (value instanceof NullCacheValue) {return null;}if (value != null) {if (tClass.isAssignableFrom(value.getClass())) {return (V) value;}}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return null;}public <V> V hashGet(String key, String hashKey, Callable<? extends V> callable,Integer expired) {if (hashOperations == null) {return getDefault(callable);}try {Object value = hashOperations.get(key, hashKey);if (value instanceof NullCacheValue) {V result = getDefault(callable);if (result != null) {hashOperations.put(key, hashKey, result);if (expired != null && expired > 0) {Long time = getExpireRand10Minitus(expired);redisTemplate.expire(key, time, TimeUnit.SECONDS);}}return result;}if (value != null) {try {return (V) value;} catch (Exception e) {log.error("callable", e);}}if (callable != null) {V result = callable.call();if (result != null) {hashOperations.put(key, hashKey, result);if (expired != null && expired > 0) {Long time = getExpireRand10Minitus(expired);redisTemplate.expire(key, time, TimeUnit.SECONDS);}}return result;}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return getDefault(callable);}public <V> V hashGetWithNull(String key, String hashKey, Callable<? extends V> callable) {if (hashOperations == null) {return getDefault(callable);}try {Object value = hashOperations.get(key, hashKey);if (value instanceof NullCacheValue) {return null;}if (value != null) {try {return (V) value;} catch (Exception e) {log.error("callable", e);}}if (callable != null) {V result = callable.call();hashOperations.put(key, hashKey, result);return result;}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return getDefault(callable);}public <V> List<V> hashGetList(String key, String hashKey, Callable<? extends List<V>> callable) {if (hashOperations == null) {return getDefault(callable);}try {Object value = hashOperations.get(key, hashKey);if (value instanceof NullCacheValue) {List<V> result = getDefault(callable);if (result == null) {return new LinkedList<>();}return null;}if (value != null) {try {return (List<V>) value;} catch (Exception e) {log.error("callable", e);}}if (callable != null) {List<V> result = callable.call();if (result == null) {return new LinkedList<>();}hashOperations.put(key, hashKey, result);return result;}} catch (RedisConnectionException ex) {//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return getDefault(callable);}public Map<String, Object> getMap(String key) {if (hashOperations == null) {return new HashMap<>();}try {return hashOperations.entries(key);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return new HashMap<>();}public void hashRemove(String key, String... hashKeys) {if (hashOperations == null || hashKeys == null || hashKeys.length == 0) {return;}Object[] args = new Object[hashKeys.length];System.arraycopy(hashKeys, 0, args, 0, hashKeys.length);try {hashOperations.delete(key, args);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}/*** 向缓存中添加值** @param key* @param values*/public void setAdd(String key, Object... values) {if (redisTemplate == null || key == null) {return;}try {SetOperations<String, Object> setOperations = redisTemplate.opsForSet();setOperations.add(key, values);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}/*** 判断缓存set中是否存在指定值** @param key* @param value* @return*/public Boolean setExists(String key, Object value) {if (redisTemplate == null || key == null) {return false;}try {SetOperations<String, Object> setOperations = redisTemplate.opsForSet();return setOperations.isMember(key, value);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return false;}/*** 获取缓存 set** @param key* @return*/public Set<Object> setMembers(String key) {if (redisTemplate == null || key == null) {return new HashSet<>();}try {SetOperations<String, Object> setOperations = redisTemplate.opsForSet();return setOperations.members(key);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}return new HashSet<>();}public void expire(String key, Integer second) {if (redisTemplate == null || key == null) {return  ;}try {redisTemplate.expire(key,second,TimeUnit.SECONDS);} catch (RedisConnectionException ex) {log.error("缓存加载异常", ex);//连接失败次数increaseError();} catch (Exception ex) {log.error("缓存加载异常", ex);}}public static long parseLong(Object obj) {if (obj == null){return 0;}if (obj instanceof Integer) {return (long)((Integer) obj);} else if (obj instanceof Long) {return (Long) obj;}String s = obj.toString();if(StringUtils.isEmpty(s)){return 0L;}if(s.length()>=32){throw new SecurityException("长整数转换失败,GUID 转整数临时方案使用:"+s);}if (isNumeric(s)){return Long.parseLong(s);}return 0L;}public static Pattern NUMBER_PATTERN = Pattern.compile("(?:[0-9]*)|(?:-[0-9]*)");private static boolean isNumeric(String str) {Matcher isNum = NUMBER_PATTERN.matcher(str);if (isNum.matches()) {return true;} else {return false;}}}

​常见问题排查​

  • ​连接失败​​:检查Redis服务是否启动、防火墙是否开放端口(默认6379)。
  • ​序列化错误​​:确保Key和Value的序列化方式一致,避免使用默认JDK序列化。
  • ​依赖冲突​​:调整Spring Data Redis与Jedis的版本,确保兼容性。(我的spring版本是4.1.7)

在Linux系统上安装并启动Redis的步骤如下:

下载Redis源码​

从官网下载最新稳定版(以7.0.12为例):

wget https://download.redis.io/releases/redis-7.0.12.tar.gz
tar xzf redis-7.0.12.tar.gz
cd redis-7.0.12

编译并安装Redis​

# 编译源码
make# 安装到系统目录(默认路径:/usr/local/bin)
sudo make install

配置Redis​

​1 创建配置文件目录和数据目录​
sudo mkdir /etc/redis
sudo mkdir /var/lib/redis
2 复制默认配置文件​
sudo cp redis.conf /etc/redis/redis.conf

3 修改配置文件​

编辑 /etc/redis/redis.conf,调整以下参数:

# 允许后台运行
daemonize yes# 数据存储路径
dir /var/lib/redis# 绑定IP(默认只能本地访问,如需远程访问改为 0.0.0.0)
bind 127.0.0.1# 设置密码(可选)
requirepass yourpassword# 日志文件路径
logfile /var/log/redis/redis-server.log

启动Redis​

直接启动​
redis-server /etc/redis/redis.conf

验证Redis运行状态

# 检查服务状态
sudo systemctl status redis# 测试连接
redis-cli ping
# 若设置了密码,需先认证
redis-cli -a yourpassword ping

输出 PONG 表示成功。

常用命令​

启动/停止/重启服务​​:

sudo systemctl start redis
sudo systemctl stop redis
sudo systemctl restart redis

​查看日志​​:

tail -f /var/log/redis/redis-server.log

常见问题​

Q1:编译时报错“jemalloc/jemalloc.h: No such file”​
  • ​解决​​:清理后重新编译:
make distclean
make
Q2:启动失败提示“Permission denied”​
  • ​解决​​:确保Redis用户有数据目录权限:
​sudo chown -R redis:redis /var/lib/redis

 Q3:远程连接失败​

  • ​解决​​:
    1. 检查 bind 0.0.0.0 是否已配置。
    2. 确认防火墙已开放端口。
    3. 检查Redis服务是否监听正确IP:
sudo netstat -tulnp | grep redis

云服务器安全组检查(关键!)

如果服务器位于云平台(如阿里云、腾讯云),即使本地防火墙已开放端口,仍需检查云厂商的安全组规则

  • 登录云控制台,找到对应服务器的安全组配置。
  • 添加规则:协议 TCP,端口 6379,来源 0.0.0.0/0(测试用)或指定客户端 IP。

相关文章:

  • idea启动报错:java: 警告: 源发行版 11 需要目标发行版 11(亲测解决)
  • InforSuite AS 可以发布django和vue项目是否可行
  • L - Strange Mirroring (思维)
  • 大模型浪潮下,黑芝麻智能高性能芯片助力汽车辅助驾驶变革
  • maven dependencyManagement标签作用
  • MyBatis XML配置和入门使用
  • <C++> MFC自动关闭对话框(MessageBoxTimeout)
  • Java对象的GC回收年龄的研究
  • 反病毒反垃圾U-Mail邮件系统从容应对
  • python制造一个报错
  • websocket简介与基本使用
  • 15:00开始面试,15:06就出来了,问的问题有点变态。。。
  • 《MySQL:MySQL事务特性》
  • uniapp中vue3和pinia安装依赖npm install失败
  • Web安全科普:构建数字世界的“防盗门”
  • Xinference 命令大全:从模型部署到管理
  • coze从入门到入土:excel表格批量导入数据库工作流制作【解决节点使用上限】 + API接口上传文件和用户需求
  • .NET 通过命令行解密web.config配置
  • PostgreSQL MCP 使用案例
  • Ascend的aclgraph(九)AclConcreteGraph:e2e执行aclgraph
  • 不是10点!乌克兰官员称尚未就俄乌谈判开始时间达成一致
  • 制造四十余年血腥冲突后,库尔德工人党为何自行解散?
  • 微软宣布将裁员3%
  • 学习教育期间违规吃喝,李献林、叶金广等人被通报
  • 加强战略矿产出口全链条管控工作部署会召开
  • 中美瑞士会谈后中国会否取消矿产出口许可要求?外交部回应