您的位置:首页 > 数据库 > Redis

SpringBoot整合Redis(单机+集群) —— 含Spring版附件文档

2018-01-19 00:57 896 查看
首先推荐一个文档:

redis单机/集群搭建部署及应用(Spring项目)


介绍了redis单机、集群的搭建,以及Spring项目中如何使用Jedis、JedisCluster进行redis操作,看不懂本文的看这个文档也行。

----------------------------------------------------------------------------------------------------------------------------

如果使用的是redis2.x,在项目中使用客户端分片(Shard)机制,已经很久之前的版本,该换新了(此处略过),

本文讲解基于redis3.x中的集群,通过两部分来阐述spring boot整合redis,在项目中使用jedisCluster机制。

第一部分:spring boot自带整合的redis,比较简单,看下来

1>不用多说,pom.xml文件增加redis与spring boot的依赖

[html]
view plain
copy

<!-- redis依赖包 -->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-redis</artifactId>  
            <version>1.4.7.RELEASE</version>  
        </dependency>  

2>application.properties增加redis节点配置

[html]
view plain
copy

#redis单服务器配置  
spring.redis.database=0  
spring.redis.host=127.0.0.1  
spring.redis.port=6379  
spring.redis.password=  
spring.redis.pool.max-active=8  
spring.redis.pool.max-wait=-1  
spring.redis.pool.max-idle=8  
spring.redis.pool.min-idle=0  
spring.redis.timeout=0  

3>在需要使用的地方增加RedisTemplate依赖,我只在controller试了下.代码如下:

[html]
view plain
copy

package com.xyy.controller;  
  
import java.util.HashMap;  
import java.util.Map;  
  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.core.ValueOperations;  
import org.springframework.ui.ModelMap;  
import org.springframework.web.bind.annotation.PathVariable;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  
import org.springframework.web.servlet.ModelAndView;  
  
import com.danga.MemCached.MemCachedClient;  
import com.xyy.model.Favorite;  
import com.xyy.service.FavoriteService;  
  
/**  
 * Favorite控制层  
 * @ClassName: FavoriteController   
 * @author wujing  
 * @date 2017-07-13 15:09:50  
 */  
@RestController  
@RequestMapping("/favorite")  
public class FavoriteController{  
    private static final Logger LOGGER = LoggerFactory.getLogger(FavoriteController.class);  
      
    @Autowired  
    private FavoriteService favoriteService;  
    @Autowired  
    private MemCachedClient  memCachedClient ;  
    @Autowired  
    private RedisTemplate redisTemplate;  
  
      
    /**  
     * Favorite编辑  
     * @Title: update  
     * @param favorite 修改对象  
     * @return Object  
     * @author wujing   
     * @date 2017-07-13 15:09:50  
     */  
    //@RequestMapping("/detail2/{id}")  
    public Object detail2(@PathVariable Long id,ModelMap modelMap) {  
        Map<String,Object> resultMap = new HashMap<String,Object>();  
        try {  
            Favorite tempFavorite = favoriteService.selectByPrimaryKey(id);  
            resultMap.put("status", "success");  
            resultMap.put("data", tempFavorite);  
        } catch (Exception e) {  
            resultMap.put("status", "error");  
            resultMap.put("errorMsg", "系统异常");  
            LOGGER.error("Favorite添加异常", e);  
        }  
        return resultMap;  
    }  
      
    @RequestMapping("/detail/{id}")  
    public Object detail(@PathVariable Long id,ModelMap modelMap) {  
        try {  
            /*Favorite tempFavorite = (Favorite) memCachedClient.get("favorite:"+id);  
            if(tempFavorite == null) {  
                tempFavorite = favoriteService.selectByPrimaryKey(id);  
                memCachedClient.set("favorite:"+id, tempFavorite);  
            }*/  
            ValueOperations<String, Favorite> operations = redisTemplate.opsForValue();  
            Favorite tempFavorite = operations.get("favorite:"+id);  
            if(tempFavorite == null) {  
                tempFavorite = favoriteService.selectByPrimaryKey(id);  
                operations.set("favorite:"+id, tempFavorite);  
            }  
            modelMap.put("tempFavorite", tempFavorite);  
              
        } catch (Exception e) {  
            LOGGER.error("Favorite查询异常", e);  
        }  
        return new ModelAndView("favorite/detail");  
    }  
}  

就是这么简单,不得不说spring boot做了很多事,极大的简化了开发的难度

..让我等屌丝完全沉沦于码农了
随着项目的扩大,数据的增加,项目面临的考验也越来越明显,性能,扩展,容灾..等都是很重要的,这时候分布式或集群就显得尤为重要了

第二部分:spring boot整合集群版的redis
redis 3.X,在项目中使用jedisCluster机制。

1>pom.xml增加jedisCluster依赖

[html]
view plain
copy

</dependency>  
                        <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-redis</artifactId>  
            <version>1.4.7.RELEASE</version>  
        </dependency>  

2>添加redis集群节点配置文件,此处有两种方法
        1:直接在application.properties添加,此处就不详细介绍了

       
2:采用javaben的方式配置(此处需要注意spring boot 1.5以后的版本@ConfigurationProperties取消了locations属性),可以通过@PropertySource("classpath:redis.properties")引入配置文件,当然如果写在application.properties下,不需要引用该注解,如下

[html]
view plain
copy

package com.xyy.util.cached.redis;  
  
import org.springframework.boot.context.properties.ConfigurationProperties;  
import org.springframework.context.annotation.PropertySource;  
import org.springframework.stereotype.Component;  
  
/**  
 * redis集群配置文件  
 * @ClassName: RedisProperties   
 * @author wangqinghua  
 * @date 2017年7月24日 下午5:29:19  
 */  
@Component  
@ConfigurationProperties(prefix = "xyy.redis.pool")  
@PropertySource("classpath:redis.properties")  
public class RedisProperties {  
      
    /** redis集群节点 */  
    private String nodes;  
    /** 连接超时时间 */  
    private int timeout;  
    /** 重连次数 */  
    private int maxAttempts;  
    public String getNodes() {  
        return nodes;  
    }  
    public void setNodes(String nodes) {  
        this.nodes = nodes;  
    }  
    public int getTimeout() {  
        return timeout;  
    }  
    public void setTimeout(int timeout) {  
        this.timeout = timeout;  
    }  
    public int getMaxAttempts() {  
        return maxAttempts;  
    }  
    public void setMaxAttempts(int maxAttempts) {  
        this.maxAttempts = maxAttempts;  
    }  
      
}  

redis.properties配置文件如下:

[html]
view plain
copy

#redis集群配置  
xyy.redis.pool.nodes=127.0.0.1:6379,<span style="line-height: 1.5;"></span>127.0.0.1:6380,127.0.0.1:6381  
xyy.redis.pool.timeout=3000  
xyy.redis.pool.maxAttempts=5  

3>创建JedisCluster对象

[html]
view plain
copy

package com.xyy.util.cached.redis;  
  
import java.util.HashSet;  
import java.util.Set;  
  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
import redis.clients.jedis.HostAndPort;  
import redis.clients.jedis.JedisCluster;  
  
/**  
 * 生成JedisCluster对象  
 * @ClassName: JedisClusterConfig   
 * @author wangqinghua  
 * @date 2017年7月24日 下午7:08:03  
 */  
@Configuration  
public class JedisClusterConfig {  
  
    @Autowired  
    private RedisProperties redisProperties;  
  
    /**  
     * 注意:  
     * 这里返回的JedisCluster是单例的,并且可以直接注入到其他类中去使用  
     * @return  
     */  
    @Bean  
    public JedisCluster getJedisCluster() {  
        String[] serverArray = redisProperties.getNodes().split(",");//获取服务器数组(这里要相信自己的输入,所以没有考虑空指针问题)  
        Set<HostAndPort> nodes = new HashSet<>();  
<
10f69
span>  
        for (String ipPort : serverArray) {  
            String[] ipPortPair = ipPort.split(":");  
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));  
        }  
  
        return new JedisCluster(nodes, redisProperties.getTimeout(),redisProperties.getMaxAttempts());  
    }  
  
}  

4>自定义RedisTemplate

[html]
view plain
copy

package com.xyy.util.cached.redis;  
  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
import redis.clients.jedis.JedisCluster;  
  
/**  
 * 自定义redisTemplate  
 * @ClassName: XyyRedisTemplate   
 * @author wangqinghua  
 * @date 2017年7月24日 下午7:09:49  
 */  
@Component  
public class XyyRedisTemplate {  
    private static final Logger LOGGER    = LoggerFactory.getLogger(XyyRedisTemplate.class);  
  
    @Autowired  
    private JedisCluster        jedisCluster;  
  
    @Autowired  
    private RedisProperties     redisProperties;  
  
    private static final String KEY_SPLIT = ":"; //用于隔开缓存前缀与缓存键值   
  
    /**  
     * 设置缓存   
     * @param prefix 缓存前缀(用于区分缓存,防止缓存键值重复)  
     * @param key    缓存key  
     * @param value  缓存value  
     */  
    public void set(String prefix, String key, String value) {  
        jedisCluster.set(prefix + KEY_SPLIT + key, value);  
        LOGGER.debug("RedisUtil:set cache key={},value={}", prefix + KEY_SPLIT + key, value);  
    }  
  
    /**  
     * 设置缓存,并且自己指定过期时间  
     * @param prefix  
     * @param key  
     * @param value  
     * @param expireTime 过期时间  
     */  
    public void setWithExpireTime(String prefix, String key, String value, int expireTime) {  
        jedisCluster.setex(prefix + KEY_SPLIT + key, expireTime, value);  
        LOGGER.debug("RedisUtil:setWithExpireTime cache key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,  
            expireTime);  
    }  
  
    /**  
     * 设置缓存,并且由配置文件指定过期时间  
     * @param prefix  
     * @param key  
     * @param value  
     */  
    public void setWithExpireTime(String prefix, String key, String value) {  
        int EXPIRE_SECONDS = redisProperties.getTimeout();  
        jedisCluster.setex(prefix + KEY_SPLIT + key, EXPIRE_SECONDS, value);  
        LOGGER.debug("RedisUtil:setWithExpireTime cache key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,  
            EXPIRE_SECONDS);  
    }  
  
    /**  
     * 获取指定key的缓存  
     * @param prefix  
     * @param key  
     */  
    public String get(String prefix, String key) {  
        String value = jedisCluster.get(prefix + KEY_SPLIT + key);  
        LOGGER.debug("RedisUtil:get cache key={},value={}", prefix + KEY_SPLIT + key, value);  
        return value;  
    }  
  
    /**  
     * 删除指定key的缓存  
     * @param prefix  
     * @param key  
     */  
    public void deleteWithPrefix(String prefix, String key) {  
        jedisCluster.del(prefix + KEY_SPLIT + key);  
        LOGGER.debug("RedisUtil:delete cache key={}", prefix + KEY_SPLIT + key);  
    }  
      
    public void delete(String key) {  
        jedisCluster.del(key);  
        LOGGER.debug("RedisUtil:delete cache key={}", key);  
    }  
  
}  

5>如何使用,和spring boot自带的就很类似了

[html]
view plain
copy

package com.xyy.controller;  
  
import java.util.HashMap;  
import java.util.Map;  
  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.ui.ModelMap;  
import org.springframework.util.StringUtils;  
import org.springframework.web.bind.annotation.PathVariable;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  
import org.springframework.web.servlet.ModelAndView;  
  
import com.danga.MemCached.MemCachedClient;  
import com.xyy.model.Favorite;  
import com.xyy.service.FavoriteService;  
import com.xyy.util.JsonUtil;  
import com.xyy.util.cached.redis.XyyRedisTemplate;  
  
/**  
 * Favorite控制层  
 * @ClassName: FavoriteController   
 * @author wujing  
 * @date 2017-07-13 15:09:50  
 */  
@RestController  
@RequestMapping("/favorite")  
public class FavoriteController{  
    private static final Logger LOGGER = LoggerFactory.getLogger(FavoriteController.class);  
      
    @Autowired  
    private FavoriteService favoriteService;  
    @Autowired  
    private MemCachedClient  memCachedClient ;  
    @Autowired  
    private RedisTemplate redisTemplate;  
    @Autowired  
    private XyyRedisTemplate xyyRedisTemplate;  
      
    /**  
     * Favorite编辑  
     * @Title: update  
     * @param favorite 修改对象  
     * @return Object  
     * @author wujing   
     * @date 2017-07-13 15:09:50  
     */  
    //@RequestMapping("/detail2/{id}")  
    public Object detail2(@PathVariable Long id,ModelMap modelMap) {  
        Map<String,Object> resultMap = new HashMap<String,Object>();  
        try {  
            Favorite tempFavorite = favoriteService.selectByPrimaryKey(id);  
            resultMap.put("status", "success");  
            resultMap.put("data", tempFavorite);  
        } catch (Exception e) {  
            resultMap.put("status", "error");  
            resultMap.put("errorMsg", "系统异常");  
            LOGGER.error("Favorite添加异常", e);  
        }  
        return resultMap;  
    }  
      
    @RequestMapping("/detail/{id}")  
    public Object detail(@PathVariable Long id,ModelMap modelMap) {  
        try {  
            /*Favorite tempFavorite = (Favorite) memCachedClient.get("favorite:"+id);  
            if(tempFavorite == null) {  
                tempFavorite = favoriteService.selectByPrimaryKey(id);  
                memCachedClient.set("favorite:"+id, tempFavorite);  
            }*/  
            /*ValueOperations<String, Favorite> operations = redisTemplate.opsForValue();  
            Favorite tempFavorite = operations.get("favorite:"+id);  
            if(tempFavorite == null) {  
                tempFavorite = favoriteService.selectByPrimaryKey(id);  
                operations.set("favorite:"+id, tempFavorite);  
            }*/  
            Favorite tempFavorite = null;  
            String value = xyyRedisTemplate.get("favorite",String.valueOf(id));  
            if(StringUtils.isEmpty(value)) {  
                tempFavorite = favoriteService.selectByPrimaryKey(id);  
                xyyRedisTemplate.set("favorite",String.valueOf(id), JsonUtil.objToString(tempFavorite));  
            }else {  
                tempFavorite = JsonUtil.stringToObj(value, Favorite.class);  
            }  
            modelMap.put("tempFavorite", tempFavorite);  
              
        } catch (Exception e) {  
            LOGGER.error("Favorite查询异常", e);  
        }  
        return new ModelAndView("favorite/detail");  
    }  
}  

JsonUtil工具包,为公司自定义文件,这个就不公开了,可以自行采用各种json包来解析

....

redis整合,在这里,也将告一段落了,有什么疑问欢迎留言!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: