Redis的nodejs开发案例,Redis可视化学工业具Web

一、简介

  方今因为工作须求,使用了某个单机版Redis的界面化管理工具,使用进度中这痛楚的心得真正唯有用过的人才能体味;为此作者和小伙伴准备入手三个Redis可视化学工业具,可是因为小伙伴近来工作比较忙,搞了大多数没有时间继续(会有一而再,界面不敢说,使用体验方面肯定要比现有的好);自身对wpf不是很熟,再想到很久在此之前的web迅雷,就想发轫达成一个web版的Redis的界面化管理工科具;近来那几个工具已伊始成型,所以放出去分享一下。

Java Spring mvc 操作 Redis 及 Redis 集群,mvcredis

 本文原创,转发请注解:

有关 Redis 集群搭建能够参考小编的另一篇小说 Redis集群搭建与简单利用

Redis 是什么,能做哪些

Redis
是二个开源(BSD许可),内部存款和储蓄器存款和储蓄的数据结构服务器,可用作数据库,高速缓存和音讯队列代理。它支持字符串、哈希表、列表、集合、有序聚集,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不一致级别磁盘持久化功用,同时通过Redis
Sentinel 提供高可用,通过 Redis Cluster 提供自动分区。(摘自 Redis 官网)

作为内部存款和储蓄器数据库,在现代网络 web 系统中,照旧根本将 Redis
作为缓存使用。大型互联网 Web
系统对质量须要很高,而在前者和数据层之间扩大数量缓存已成为必不可少的手腕之一,当前可比盛行的七个技术正是 Redis
和 Memcached,至于双方有哪些不一样,不是本文要说的剧情。本文首要讲 Java
web 如何操作 Redis 及 Redis 集群。

相似 Java 程序操作Redis

Redis 提供了多样语言的客户端,在 Java 中最风靡的是
Jedis 。访问可查阅源码及使用方法。近日 Jedis
最新版本是2.9.0。无论是单机依然集群,Jedis
都有很详细的证实和实例代码,那里只做简单表明。即使用 Maven
做包管理,必要引用  jedis 包,本例使用最新的2.9.0版本,如下:

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
</dependency>  

操作 Redis 单机

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Created by fengdezitai on 2016/10/9.
 */
public class JedisClient {

    private static final String host= "192.168.31.121";

    private static final JedisClient jedisClient = new JedisClient();

    private Jedis jedis = null;
    /**
     * 私有构造函数
     */
    private JedisClient(){}

    public static JedisClient getInstance(){
        return jedisClient;
    }

    private JedisPoolConfig getPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxTotal(100);
        jedisPoolConfig.setMaxWaitMillis(3000);
        return jedisPoolConfig;
    }

    /**
     * 添加
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    public Boolean add(String key,String value) throws Exception{
        JedisPool pool = new JedisPool(getPoolConfig(),host);
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            if(jedis.exists(key)){
                throw new Exception(String.format("key (%s) 已存在 ",key));
            }
            jedis.set(key,value);

        }catch (Exception e){
            throw e;
        }
        finally {
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        return true;
    }

    /**
     * 获取值
     * @param key
     * @return
     * @throws Exception
     */
    public String get(String key) throws Exception{
        JedisPool pool = new JedisPool(getPoolConfig(),host);
        Jedis jedis = null;
        String result = "";
        try {
            jedis = pool.getResource();
            result = jedis.get(key);
        }catch (Exception e){
            throw e;
        }
        finally {
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        return result;
    }

    public static void main(String[] args) {
        JedisClient jedisClient = JedisClient.getInstance();
        try {
            /*Boolean result = jedisClient.add("hello", "redis1");
            if(result){
                System.out.println("success");
            }*/

            System.out.println(jedisClient.get("hello"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

操作 redis 集群

import redis.clients.jedis.*;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by fengdezitai on 2016/10/13.
 */
public class JedisClusterClient {

    private static int count = 0;

    private static final JedisClusterClient redisClusterClient = new JedisClusterClient();

    /**
     * 私有构造函数
     */
    private JedisClusterClient() {}

    public static JedisClusterClient getInstance() {
        return redisClusterClient;
    }

    private JedisPoolConfig getPoolConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(1000);
        config.setMaxIdle(100);
        config.setTestOnBorrow(true);
        return config;
    }

    public void SaveRedisCluster() {
        Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7000));
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7001));
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7002));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7003));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7004));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7005));

        JedisCluster jc = new JedisCluster(jedisClusterNodes,getPoolConfig());
        jc.set("cluster", "this is a redis cluster");
        String result = jc.get("cluster");
        System.out.println(result);
    }

    public static void main(String[] args) {
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        jedisClusterClient.SaveRedisCluster();
    }
}  

Spring mvc 操作 Redis

在 Spring mvc 中操作 Redis ,首先当然要搭好 Spring mvc
框架了。以下是在借使 Spring mvc 环境已经架好的情况下。本例中 Spring
版本为 4.3.2 RELEASE。关于 Spring 的 maven 引用如下:

<!-- spring版本号 -->
<spring.version>4.3.2.RELEASE</spring.version>

<!-- spring核心包 -->
    <!-- springframe start -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- springframe end -->

操作 Redis 单机

只用 Jedis 自个儿实现注入(差距于上边包车型地铁引用spring-data-redis) 

把前边的 JedisClient 代码拿过来引用即可,只需兑现三个走访 Redis 的
Service ,就足以融合为一到 Spring mvc 。Service 代码如下:

import org.springframework.stereotype.Service;
import util.JedisClient;

/**
 * Created by fengdezitai on 2016/10/9.
 */
@Service
public class RedisService {

    public String get(String key) throws Exception{
        JedisClient jedisClient = JedisClient.getInstance(); //上面实现的JedisClient
        String result = "";
        try {
            result = jedisClient.get("hello");
        }catch (Exception e){
            throw e;
        }
        return result;
    }
}

Controller 完毕如下:

@Controller
@RequestMapping(value = "redisAllInOne")
public class RedisAllInOneController {

    @Autowired
    private RedisService redisService;

    @RequestMapping(value = "get",method = RequestMethod.GET)
    @ResponseBody
    public Object getByMyService(String key){
        try {
            String result = redisService.get(key);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}  

用 spring-data-redis 包做集成

下面是温馨完成的注入,这里用 spring-data-redis
进行合并,只需简单安插即可,必要引用 maven 包如下,版本为眼下洋气版
1.7.2.RELEASE:

<dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>1.7.2.RELEASE</version>
    </dependency>

采用 spring-data-redis
,即省去了团结达成注入的进度,通过它提供的部分配置,即可兑现连接池配置、RedisTemplate
配置、JedisConnectionFactory 配置;通过 JedisConnectionFactory
可配备连接池参数、redis
服务器、端口、密码、超时时间、database索引等;RedisTemplate 即注入的bean
,能够运用 RedisTemplate 自动注入的实业进行 redis
的一星罗棋布操作,具体看计划;

redis 服务属性配置文件:

redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis.host=192.168.31.121
redis.port=6379
redis.password=password
redis.timeout=3000

spring-data-redis xml 配置文件 redis-context.xml:

<!-- 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="timeout" value="${redis.timeout}" ></property>
        <property name="database" value="1"></property>
    </bean>

    <bean id="commonRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

    <bean id="connectionFactory1"  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="timeout" value="${redis.timeout}" ></property>
        <property name="database" value="2"></property>
    </bean>

    <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean id="cacheRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory1" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

后来在 spring 配置文件中引用以上文件:

<import resource="redis-context.xml" />  

解释一下上边的布局:

美高梅开户网址 ,poolConfig 即配置 redis 连接池,之后布署了八个 JedisConnectionFactory 和
RedisTemplate ,三个 RedisTemplate 对应1个 JedisConnectionFactory
,那样能够陈设依照气象布局分裂的 Redis
连接,比如超时时间须求不雷同、database 0-15
能够储存分裂的数据等。那里就配备了database 1 和 2
,调用 commonRedisTemplate 会存到 database1 ,调用 cacheRedisTemplate
会存到 database2。

从此在 Service 层即可注入并引述这多个 RedisTemplate ,如下代码:

import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.*;

@Repository
public class RedisCache {
  
    @Resource(name = "cacheRedisTemplate")
    private RedisTemplate<String, String> cacheRedisTemplate;

    public void put(Object key, Object value) {
        if(null == value) {
            return;
        }

        if(value instanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }

        // TODO Auto-generated method stub
        final String keyf = key + "";
        final Object valuef = value;
        final long liveTime = 86400;

        cacheRedisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    public Object get(Object key) {
        final String keyf = (String) key;
        Object object;
        object = cacheRedisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);

            }
        });

        return object;
    }

    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }

    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }
}

最后在 Controller 中调用即可

    @Autowired
    private RedisCache redisCache;


    @RequestMapping(value = "get", method = RequestMethod.GET)
    @ResponseBody
    public Object getByMyService(String key) {
        try {
            String result = redisService.get(key);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(value = "save", method = RequestMethod.GET)
    @ResponseBody
    public Object save() {
        Token token = new Token();
        token.setAccess_token("token");
        token.setExpires_in(1000);
        try {
            redisCache.put("token", token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "ok";
    }  

操作 Redis 集群

只用 Jedis 本人完结注入(区别于上边包车型客车引用spring-data-redis)

把前边的 JedisClusterClient 代码拿过来引用即可,只需兑现3个访问 Redis
的 Service ,就足以融为一炉到 Spring mvc 。Service 代码如下:

import org.springframework.stereotype.Service;
import util.JedisClusterClient;

/**
 * Created by fengdezitai on 2016/10/13.
 */
@Service
public class RedisClusterService {

    public void save() throws Exception{
        //调用 JedisClusterClient 中的方法
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        try {
            jedisClusterClient.SaveRedisCluster();
        }catch (Exception e){
            throw e;
        }
    }
}

末尾在 Controller 中调用完结的 Service 即可

@Controller
@RequestMapping(value = "redisCluster")
public class RedisClusterController {

    @Autowired
    private RedisClusterService redisClusterService;

    @RequestMapping(value = "save",method = RequestMethod.GET)
    @ResponseBody
    public Object save(){
        try{
            redisClusterService.save();
        }catch (Exception e){
            e.printStackTrace();
            return String.format("error: %s",e.getMessage());
        }
        return "ok";
    }
}  

用 spring-data-redis 包做集成 

Spring 和 spring-data-redis maven
包引述和前面一致,之所以引用 spring-data-redis 1.7.2.RELEASE,是因为脚下唯有那些最新版本才支撑集群操作。

redis 集群服务性质配置

redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=false
redis.timeout=3000

spring-data-redis xml 集群配置文件 redis-cluster-context.xml

<!-- 连接池 配置 -->
    <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>


    <bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <property name="maxRedirects" value="3"></property>
        <property name="clusterNodes">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7000"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7001"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7002"></constructor-arg>
                </bean>
                 <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7003"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7004"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7005"></constructor-arg>
                </bean>
            </set>
        </property>
    </bean>

    <bean id="redis4CacheConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <constructor-arg name="clusterConfig" ref="redisClusterConfig" />
        <property name="timeout" value="${redis.timeout}" />
        <property name="poolConfig" ref="poolConfig"/>
    </bean>


    <bean name="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="redis4CacheConnectionFactory" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

从此在 Spring 配置文件中引用

<import resource="redis-cluster-context.xml" />

解释以上配置

poolConfig是连接池配置,redisClusterConfig 配置了 Redis
集群的逐一节点(节点 host 和 port 最佳写在性质配置文件中),集群搭建可见笔者的 另一篇博客 。然后下边和单机配置一样了,一对 JedisConnectionFactory
和 RedisTemplate 。

然后在 Service 层即可注入并引用那些 RedisTemplate,代码如下:

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.io.*;

/**
 * Created by fengdezitai on 2016/9/29.
 */
@Repository
public class RedisClusterCache {

    @Autowired
    private RedisTemplate clusterRedisTemplate;


    public void put(Object key, Object value) {
        if(null == value) {
            return;
        }

        if(value instanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }

        // TODO Auto-generated method stub
        final String keyf = key + "";
        final Object valuef = value;
        final long liveTime = 86400;

        clusterRedisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    public Object get(Object key) {
        final String keyf = (String) key;
        Object object;
        object = clusterRedisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);

            }
        });

        return object;
    }

    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }

    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }
}

最后在 Controller 中调用即可

@Controller
@RequestMapping(value = "redisCluster")
public class RedisClusterController {

    @Autowired
    private RedisClusterCache redisClusterCache;

    @RequestMapping(value = "clusterSave",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public Object clusterSave(){
        //redisClusterCache.put("cluster","save cluster");
        Token token = new Token();
        token.setExpires_in(1000);
        token.setAccess_token("hello world");
        redisClusterCache.put("token",token);
        return "ok";
    }

    @RequestMapping(value = "getKey",method = RequestMethod.GET)
    @ResponseBody
    public Object getCluster(String key){
        Object val = redisClusterCache.get(key);
        return val;
    }
} 

注意事项:

  • 本子难题,如若用 spring-data-redis 做集成操作 Reids
    集群,只有 spring-data-redis
    近来风行版本1.7才含有对集群的操作,而最新的 spring-data-redis
    中的有个别意义对 Spring mvc
    的版本也有个别限制,所以尽可能采取高版本的 Spring mvc 对应。
  • 要是存款和储蓄的value值是1个实体对象,那么必然要实现 Serializable 接口

 

Spring mvc 操作 Redis 及 Redis
集群,mvcredis
本文原创,转载请评释:
关于 Redis 集群搭建能够参见笔者的另…

 本文原创,转发请表明:

作为一名曾今的pythoner,在既往的web开发工作时,接触过Django、Flask、Tornado等框架;而现在投入nodejs的怀抱,任其自然接触到了Express和Restify框架,上面就依据本人的入门经验,写3个restify+mongoose+redis举办web开发的大约示例。

贰 、基本选拔手续

  首先下载包,并解压打开,如下图:

  美高梅开户网址 1

  接下去双击文件WebRedisManager.exe运行,假如不能够运营以来,只怕必要安装.net
framework 4.5,成功开拓界面如下:

  美高梅开户网址 2

  然后打开浏览器,地址栏按上边提醒输入url,界面如下:

  美高梅开户网址 3

  那些时候就足以添加redis服务器了:

  美高梅开户网址 4

  添加事业有成后会自动展现在左手:

  美高梅开户网址 5

  美高梅开户网址 6

  美高梅开户网址 7

  一些例行的增加和删除改查的效能都有,如今还有部分询问功用、集群管理等没有完毕,今后询问项默许都以四贰拾个,后续再稳步加上吧。  

关于 Redis
集群搭建能够参照小编的另一篇文章 Redis集群搭建与不难利用

零、开发条件

1.使用的nodeRedis的nodejs开发案例,Redis可视化学工业具Web。版本为v6.11.3
LTS(故意申明:示范代码应用了ES6的特点);
2.MongoDB和Redis请自行下载(为何要同时采取那五个吗?因为懒
得写restify+mongoose和restify+redis两篇);
3.依赖的node_modules包括:restify、mongoose、redis,
4.装置好node后自带包管理工科具npm(比Python的pip更有力一丝丝)
— npm install xxx -g 全局安装
— npm install xxx –save 安装在本项目
1个名为package.json的文件是它的好基友,不信自身慢慢看

③ 、开发简介

  上面根本是基于SAEA.Socket通讯框架中的SAEA.RedisSocket、SAEA.WebApi八个零部件来兑现redis通信、webserver以及仿asp.net
mvc的神速风格的后端程序,web端使用的是layui+ajax。项目源码结构:

  美高梅开户网址 8

 

Redis 是怎么,能做怎么着

一 、创造3个施用restify API的新服务器

借使运营文件为app.js,直接上代码

var restify = require('restify');

// 可配置项
var addr = '127.0.0.1';
var port = '8888';

var server = restify.createServer({
    name: 'test',
    version: '0.0.1'
});

// 使用插件
server.use(restify.pre.userAgentConnection());          // work around for curl  
server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());

server.listen(port, addr, function() {
    console.log("server %s is listening on port <%s>", server.name, server.url);
});

运营node app.js,本机的8888端口就开启了三个应用restify
API的服务器,因为从没扩展别的接口,所以无法访问。

  • use部分应用的是restify内置的作用插件,当前引入的是用来分析参数,更具象更丰盛的插件成效看这里
  • createServer的参数当然不只这多个,具体能够参考这里

上边即将进入业务逻辑的支付,先假使工作为三个部分:使用MongoDB管理用户数据、使用redis管理会话中的Cookie。

④ 、大旨技术详细

  1.SAEA.RedisSocket:那些是根据SAEA.Socket达成的Redis编解码命令的客户端,方今包裹了多方的redis数据操作命令和全部的redis
cluster命令,越多详细可参照。

  2.SAEA.WebApi:这些是基于SAEA.Socket达成的http编解码命令的服务端,如今已实现了get、post的处理,帮衬二种form的解码;并且已合二为一了mvc风格的编码框架,更加多详细可参考。

  3.LayUI:这几个是故事中面向后端开发职员的Web框架,排版上是仿Bootstrap的风骨,集成了汪洋的插件,能够便捷实现相关的web页面功用,越来越多详细可参照:。

Redis
是四个开源(BSD许可),内部存款和储蓄器存款和储蓄的数据结构服务器,可用作数据库,高速缓存和音信队列代理。它帮忙字符串、哈希表、列表、集合、一如既往聚集,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不相同级别磁盘持久化功能,同时通过Redis
Sentinel 提供高可用,通过 Redis Cluster
提供自动分区。(摘自 Redis
官网)

二、使用mongoose访问MongoDB

mongoose对于三个pythoner来说,使用起来并不是很顺手,因为它跟mongoengine卓殊见仁见智,后者使用Documentation来定义数据模型,而它用的是Schema和Model,至于实际怎么个弄法,依然看这里。

我们的示范呢,不难地持续,创制文件mongo.js,代码如下:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// 使用node的Promise替换mongoose的Promise,否则会报错
mongoose.Promise = global.Promise;

// 可配置项
var host = '127.0.0.1';
var port = '27017';
var dbName = 'test';

var dbUri = `${host}:${port}/${dbName}`;
var dbConnection = mongoose.createConnection(dbUri);
dbConnection.on('error', (err) => {
    console.log('connect mongodb failed: ' + err);
    process.exit();
});

var dbSchemas = {
    // 定义user的Schema
    // 包括身份证号码、姓名、性别、手机等
    userSchema: {
        idno: {type: String, require: true, unique: true},
        name: {type: String, require: true},
        gender: {type: Number, require: true},
        phone: {type: String},
        created: {type: Date, default: Date.now}
    }
};

// 定义UserModel
class UserModel {
    constructor(connection, schema) {
        this.name = 'user';
        this.schema = new Schema(schema);
        this.model = connection.model(`userModel`, this.schema, this.name);
    }

    // 封装查询
    findByIdno(idno) {
        return new Promise((resolve, reject) => {
            this.model.findOne({'idno': {$eq: idno}}, (err, record) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(record);
                }
            });
        });
    }

    // 封装插入or更新
    insertOrUpdateByIdno(data) {
        return new Promise((resolve, reject) => {
            this.model.findOne({'idno': {$eq: data.idno}}, (err, record) => {
                if (err) {
                    reject(err);
                } else {
                    if (record == undefined) {
                        // 插入
                        var instance = new this.model(data);
                        instance.save((err) => {
                            if (err) {
                                reject(err);
                            } else {
                                resovle(data);
                            }
                        });
                    } else {
                        // 更新
                        this.model.findOneAndUpdate({'idno': {$eq: data.idno}}, data, {new: true, upsert: true}, (err, res) => {
                            if (err) {
                                reject(err);
                            } else {
                                resolve(res);
                            }
                        });
                    }
                }
            });
        });
    }
}

var user = new UserModel(dbConnection, dbSchemas.userSchema);

exports.user = user;

地点代码中使用到了ES6的千千万万特色,包蕴Promise机制、Class以及“箭头”函数等,做的劳作则有:

  1. 建立与MongoDB的连接dbConnection
  2. 使用Node的Promise来替换mongoose的Promise(被弃用)
  3. 申明user的数据结构userSchema
  4. 构造UserModel的类
  5. 在UserModel中封装了对MongoDB的询问(findOne)、插入(save)、更新(findOneAndUpdate)操作
  6. 实例化UserModel对象,并export以供调用

⑤ 、完整封装及源代码分享

  那些种类按SAEA简洁高效的不二法门开始展览编码的,很多地点都应用的暗中同意值,无论是查看代码照旧继续衔接都很自在方便,上边是本项指标运维力源码:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             ConsoleHelper.Title = "WebRedisManagerService";
 6 
 7             MvcApplication mvcApplication = new MvcApplication(10240, 3000);
 8 
 9             mvcApplication.Start();
10 
11             ConsoleHelper.WriteLine("WebRedisManager服务已启动");
12 
13             ConsoleHelper.WriteLine("http://localhost:39654/html/index.html,按回车结束......");
14 
15             Process.Start("http://localhost:39654/html/index.html");
16 
17             ConsoleHelper.ReadLine();
18         }
19     }

  更加多源码请访问 

 

转发请标明本文来源:
越多内容欢迎star作者的github:
比方发现本文有哪些难题和任何建议,也随时欢迎沟通~

用作内部存款和储蓄器数据库,在现世互连网 web 系统中,依旧关键将 Redis
作为缓存使用。大型网络 Web
系统对质量要求很高,而在前端和数据层之间增添数据缓存已成为不可或缺的手段之一,当前可比盛行的八个技巧正是 Redis
和 Memcached,至于双方有如何界别,不是本文要说的内容。本文首要讲 Java
web 怎么着操作 Redis 及 Redis 集群。

三、使用redis访问Redis

Redis绝比较MongoDB而言,速度更快,因为存储在内部存款和储蓄器中嘛(可持久化),因而比MongoDB更符合用来治本Session。
Redis的利用也更简明,不论是写代码依旧在redis-cli中敲命令,帮助7种数据类型的读写(从前写的5种是因为本人也是看的二手资料,现改过),各类数据类型的授命都不可同日而语,具体的要么看一下原味的redis数据类型介绍,直接看一手音信以防入坑,然后代码交互的话能够参见一下node-redis.

此间示例继续,成立redisClient.js,代码如下:

var redis = require('redis');

// 可配置项
var host = '127.0.0.1';
var port = 6379;

var client = redis.createClient(port, host, {});

client.on('ready', (res) => {
    console.log('redis ready: ' + res);
});

client.on('error', (err) => {
    console.log('connect redis error: ' + err);
    process.exit(2);
});

// 假设cookie为哈希,token为string
class Session {
    constructor(client) {
        this.client = client;
    }

    // 设置/更新Cookie以及设置/重设有效期,默认10分钟。
    updateCookie(uuid, cookie, t) {
        t = t ? t: 600;    // 默认10分钟
        return new Promise((resolve, reject) => {
            let key = uuid + ':cookie';
            this.client.hmset(key, cookie, (err, res1) => {
                if (err) {
                    console.log('redis hmset error: ' + err);
                    reject(err);
                } else {
                    // 设置有效期
                    this.client.expire(key, t, (err, res2) => {
                        if (err) {
                            console.log('erdis hmset expire error: ' + err);
                            reject(err);
                        } else {
                            resolve(res2 === 1);
                        }
                    });
                }
            });
        });
    }

    // 查询Cookie
    getCookie(uuid) {
        return new Promise((resolve, reject) => {
            let key = uuid + ':cookie';
            this.client.hgetall(key, (err, record) => {
                if (err) {
                    console.log('redis hgetall error: ' + err);
                } else {
                    resolve(record);
                }
            });
        });
    }

    // 设置or更新token,同样设置有效期,默认10分钟
    updateToken(uuid, token, t) {
        t = t ? t : 600;
        return new Promise((resolve, reject) => {
            let key = uuid + ':token';
            this.client.set(key, token, (err, res1) => {
                if (err) {
                    console.log('redis set error: ' + err);
                    reject(err);
                } else {
                    this.client.expire(key, t, (err, res2) => {
                        if (err) {
                            console.log('redis set expire error: ' + err);
                            reject(err);
                        } else {
                            resolve(res2 === 1);
                        }
                    });
                }
            });
        });
    }

    getToken(uuid) {
        return new Promise((resolve, reject) => {
            let key = uuid + ':token';
            this.client.get(key, (err, record) => {
                if (err) {
                    cosole.log('redis get error: ' + err);
                    reject(err);
                } else {
                    resolve(record);
                }
            });
        });
    }

    delUuid(uuid) {
        this.client.del(uuid + ':cookie');
        this.client.del(uuid + ':token');
    }
}

var session = new Session(client);

module.exports =  {
    session: session
};

上边完结的行事包涵:

  1. 建立redis的client
  2. 定义Session的model
  3. 封装hash和string三种数据类型(Cookie和Token)的读写以及去除
  4. 实例化Session并export以供调用(那里的export操作使用了另一种格局)

诚如 Java 程序操作Redis

④ 、设计并贯彻api接口

于今数据模型的概念已经到位,就能够起来开始展览作业逻辑的兑现。
依照model的定义,大家驾驭已完结的数据库操作包罗user、token、cookie的革新(包蕴创设)和询问,由于后两者都以redis的操作,大家就完结user和cookie的操作好了。
在app.js中,server.use代码块下方、server.listen上方区域增加如下代码:

var route = require('./route');

// api route
server.post('/user/update', route.updateUser);
server.get('/user/get', route.getUser);

server.post('/cookie/update', route.updateCookie);
server.get('/cookie/get', route.getCookie);

可以看到引用了二个route.js文件,最近还没有该公文,必要新建route.js来贯彻业务逻辑,代码如下:

var user = require('./mongo').user;
var session = require('./redisClient').session; 

// 创建/更新user
// post的数据通过req.body传递
// 此处约定使用json格式,bodyParser可解析
exports.updateUser = function(req, res) {
    // 此处省略数据合法性的检查
    let data = {
        idno: req.body.idno,
        name: req.body.name,
        gender: req.body.gender,
        phone: req.body.phone
    };

    // 设置response为utf-8编码
    res.charSet('utf-8');   
    // 设置返回数据格式为json
    res.setHeader('Content-Type', 'application/json');
    user.insertOrUpdateByIdno(data)
        .then(function(record) {
            res.send({code: 0, msg: '创建/更新user成功', result: record});
        }, function(err) {
            console.log(err);
            res.send({code: 1, msg: '创建/更新user失败', result: {}});
        });
};

// 查询user
// get的参数直接在url中,queryParser可解析
exports.getUser = function(req, res) {
    let idno = req.query.idno;
    // 设置response为utf-8编码
    res.charSet('utf-8');   
    // 设置返回数据格式为json
    res.setHeader('Content-Type', 'application/json');
    user.findByIdno(idno)
        .then(function(record) {
            res.send({code: 0, msg: 'user查询成功', result: record});
        }, function(err) {
            console.log(err);
            res.send({code: 1, msg: 'user查询失败', result: {}});
        });
};

// 设置/更新Cookie
// post提交的数据,有uuid为更新,没uuid为新建
exports.updateCookie = function(req, res) {
    let uuid = req.body.uuid ? req.body.uuid : genUuid();
    let cookie = req.body;
    delete cookie.uuid;        // 不论有没有都是true
    res.charSet('utf-8');
    res.setHeader('Content-Type', 'application/json');
    session.updateCookie(uuid, cookie)
        .then(function(r) {
            res.send({code: 0, msg: '更新/新建Cookie成功', 
                result: {uuid: uuid, data: cookie}});
        }, function(e) {
            console.log(e);
            res.send({code: 1, msg: '更新/新建Cookie成功', result: {}});
        });
};

// 根据uuid查询Cookie
exports.getCookie = function(req, res) {
    let uuid = req.query.uuid;
    res.charSet('utf-8');
    res.setHeader('Content-Type', 'application/json');
    session.getCookie(uuid)
        .then(function(record) {
            res.send({code: 0, msg: '获取Cookie成功', result: record});
        }, function(err) {
            console.log(err);
            res.send({code: 1, msg: '获取Cookie失败', result: {}});
        });
};

function genUuid() {
    return Math.random().toString() + Math.random().toString();
}

Redis 提供了各类语言的客户端,在 Java 中最风靡的是
Jedis 。访问可查阅源码及利用办法。近来Jedis 最新版本是2.9.0。无论是单机照旧集群,Jedis
都有很详细的辨证和实例代码,那里只做不难表明。假如用 Maven
做包管理,必要引用  jedis 包,本例使用新型的2.9.0版本,如下:

⑤ 、接口测试

在MongoDB和Redis数据库都运转起来的景色下,运营node
app.js运转服务器,然后利用Postman来效仿http请求。

  1. 向接口”/user/update”发送post请求

美高梅开户网址 9

updateUser.png

ps:你可能注意到了,这里存款和储蓄的是格林威治时间。

  1. 透过接口”/user/get”查询上述记录

美高梅开户网址 10

getUser.png

  1. 查阅此时MongoDB的场地

美高梅开户网址 11

MongoDB.png

  1. 向接口”/cookie/update”发送post请求

美高梅开户网址 12

updateCookie.png

  1. 透过接口”cookie/get”查询上述记录

美高梅开户网址 13

getCookie.png

  1. 此时Redis数据库内

美高梅开户网址 14

redis.png

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
</dependency>  

六、代码repo

本文中拥有代码均在此restify_mongoose_redis_sample

操作 Redis 单机

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Created by fengdezitai on 2016/10/9.
 */
public class JedisClient {

    private static final String host= "192.168.31.121";

    private static final JedisClient jedisClient = new JedisClient();

    private Jedis jedis = null;
    /**
     * 私有构造函数
     */
    private JedisClient(){}

    public static JedisClient getInstance(){
        return jedisClient;
    }

    private JedisPoolConfig getPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxTotal(100);
        jedisPoolConfig.setMaxWaitMillis(3000);
        return jedisPoolConfig;
    }

    /**
     * 添加
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    public Boolean add(String key,String value) throws Exception{
        JedisPool pool = new JedisPool(getPoolConfig(),host);
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            if(jedis.exists(key)){
                throw new Exception(String.format("key (%s) 已存在 ",key));
            }
            jedis.set(key,value);

        }catch (Exception e){
            throw e;
        }
        finally {
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        return true;
    }

    /**
     * 获取值
     * @param key
     * @return
     * @throws Exception
     */
    public String get(String key) throws Exception{
        JedisPool pool = new JedisPool(getPoolConfig(),host);
        Jedis jedis = null;
        String result = "";
        try {
            jedis = pool.getResource();
            result = jedis.get(key);
        }catch (Exception e){
            throw e;
        }
        finally {
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        return result;
    }

    public static void main(String[] args) {
        JedisClient jedisClient = JedisClient.getInstance();
        try {
            /*Boolean result = jedisClient.add("hello", "redis1");
            if(result){
                System.out.println("success");
            }*/

            System.out.println(jedisClient.get("hello"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

操作 redis 集群

import redis.clients.jedis.*;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by fengdezitai on 2016/10/13.
 */
public class JedisClusterClient {

    private static int count = 0;

    private static final JedisClusterClient redisClusterClient = new JedisClusterClient();

    /**
     * 私有构造函数
     */
    private JedisClusterClient() {}

    public static JedisClusterClient getInstance() {
        return redisClusterClient;
    }

    private JedisPoolConfig getPoolConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(1000);
        config.setMaxIdle(100);
        config.setTestOnBorrow(true);
        return config;
    }

    public void SaveRedisCluster() {
        Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7000));
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7001));
        jedisClusterNodes.add(new HostAndPort("192.168.31.245", 7002));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7003));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7004));
        jedisClusterNodes.add(new HostAndPort("192.168.31.210", 7005));

        JedisCluster jc = new JedisCluster(jedisClusterNodes,getPoolConfig());
        jc.set("cluster", "this is a redis cluster");
        String result = jc.get("cluster");
        System.out.println(result);
    }

    public static void main(String[] args) {
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        jedisClusterClient.SaveRedisCluster();
    }
}  

Spring mvc 操作 Redis

在 Spring mvc 中操作 Redis ,首先当然要搭好 Spring mvc
框架了。以下是在若是 Spring mvc 环境已经架好的状态下。本例中 Spring
版本为 4.3.2 RELEASE。关于 Spring 的 maven 引用如下:

<!-- spring版本号 -->
<spring.version>4.3.2.RELEASE</spring.version>

<!-- spring核心包 -->
    <!-- springframe start -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- springframe end -->

操作 Redis 单机

只用 Jedis 本人实现注入(差异于上边包车型客车引用spring-data-redis) 

把前边的 JedisClient 代码拿过来引用即可,只需兑现多个拜访 Redis 的
瑟维斯 ,就可以融为一炉到 Spring mvc 。Service 代码如下:

import org.springframework.stereotype.Service;
import util.JedisClient;

/**
 * Created by fengdezitai on 2016/10/9.
 */
@Service
public class RedisService {

    public String get(String key) throws Exception{
        JedisClient jedisClient = JedisClient.getInstance(); //上面实现的JedisClient
        String result = "";
        try {
            result = jedisClient.get("hello");
        }catch (Exception e){
            throw e;
        }
        return result;
    }
}

Controller 完成如下:

@Controller
@RequestMapping(value = "redisAllInOne")
public class RedisAllInOneController {

    @Autowired
    private RedisService redisService;

    @RequestMapping(value = "get",method = RequestMethod.GET)
    @ResponseBody
    public Object getByMyService(String key){
        try {
            String result = redisService.get(key);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}  

用 spring-data-redis 包做集成

下面是和谐完毕的流入,那里用 spring-data-redis
举行集成,只需不难布署即可,供给引用 maven 包如下,版本为当前时髦版
1.7.2.RELEASE:

<dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>1.7.2.RELEASE</version>
    </dependency>

使用 spring-data-redis
,即省去了上下一心达成注入的长河,通过它提供的有的配备,即可兑现连接池配置、RedisTemplate
配置、JedisConnectionFactory 配置;通过 JedisConnectionFactory
可陈设连接池参数、redis
服务器、端口、密码、超时时间、database索引等;RedisTemplate 即注入的bean
,能够动用 RedisTemplate 自动注入的实体举行 redis
的一多重操作,具体看布置;

redis 服务属性配置文件:

redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis.host=192.168.31.121
redis.port=6379
redis.password=password
redis.timeout=3000

spring-data-redis xml 配置文件 redis-context.xml:

<!-- 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="timeout" value="${redis.timeout}" ></property>
        <property name="database" value="1"></property>
    </bean>

    <bean id="commonRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

    <bean id="connectionFactory1"  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="timeout" value="${redis.timeout}" ></property>
        <property name="database" value="2"></property>
    </bean>

    <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean id="cacheRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory1" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

后来在 spring 配置文件中引用以上文件:

<import resource="redis-context.xml" />  

解释一下上边的配置:

poolConfig 即配置 redis 连接池,之后布署了七个 JedisConnectionFactory 和
RedisTemplate ,3个 RedisTemplate 对应1个 JedisConnectionFactory
,那样能够布置依据气象布局分化的 Redis
连接,比如超时时间须求不雷同、database 0-15
能够储存分歧的多寡等。那里就布局了database 1 和 2
,调用 commonRedisTemplate 会存到 database1 ,调用 cacheRedisTemplate
会存到 database2。

随后在 Service 层即可注入并援引那多少个 RedisTemplate ,如下代码:

import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.*;

@Repository
public class RedisCache {
  
    @Resource(name = "cacheRedisTemplate")
    private RedisTemplate<String, String> cacheRedisTemplate;

    public void put(Object key, Object value) {
        if(null == value) {
            return;
        }

        if(value instanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }

        // TODO Auto-generated method stub
        final String keyf = key + "";
        final Object valuef = value;
        final long liveTime = 86400;

        cacheRedisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    public Object get(Object key) {
        final String keyf = (String) key;
        Object object;
        object = cacheRedisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);

            }
        });

        return object;
    }

    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }

    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }
}

最终在 Controller 中调用即可

    @Autowired
    private RedisCache redisCache;


    @RequestMapping(value = "get", method = RequestMethod.GET)
    @ResponseBody
    public Object getByMyService(String key) {
        try {
            String result = redisService.get(key);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(value = "save", method = RequestMethod.GET)
    @ResponseBody
    public Object save() {
        Token token = new Token();
        token.setAccess_token("token");
        token.setExpires_in(1000);
        try {
            redisCache.put("token", token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "ok";
    }  

操作 Redis 集群

只用 Jedis 自个儿落成注入(不一样于上面包车型地铁引用spring-data-redis)

把前边的 JedisClusterClient 代码拿过来引用即可,只需兑现叁个走访 Redis
的 Service ,就足以融为一体到 Spring mvc 。Service 代码如下:

import org.springframework.stereotype.Service;
import util.JedisClusterClient;

/**
 * Created by fengdezitai on 2016/10/13.
 */
@Service
public class RedisClusterService {

    public void save() throws Exception{
        //调用 JedisClusterClient 中的方法
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        try {
            jedisClusterClient.SaveRedisCluster();
        }catch (Exception e){
            throw e;
        }
    }
}

说到底在 Controller 中调用实现的 Service 即可

@Controller
@RequestMapping(value = "redisCluster")
public class RedisClusterController {

    @Autowired
    private RedisClusterService redisClusterService;

    @RequestMapping(value = "save",method = RequestMethod.GET)
    @ResponseBody
    public Object save(){
        try{
            redisClusterService.save();
        }catch (Exception e){
            e.printStackTrace();
            return String.format("error: %s",e.getMessage());
        }
        return "ok";
    }
}  

用 spring-data-redis 包做集成 

Spring 和 spring-data-redis maven
包援引和前面一致,之所以引用 spring-data-redis 1.7.2.RELEASE,是因为脚下唯有这些新型版本才支撑集群操作。

redis 集群服务性质配置

redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=false
redis.timeout=3000

spring-data-redis xml 集群配置文件 redis-cluster-context.xml

<!-- 连接池 配置 -->
    <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>


    <bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <property name="maxRedirects" value="3"></property>
        <property name="clusterNodes">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7000"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7001"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port" value="7002"></constructor-arg>
                </bean>
                 <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7003"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7004"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port" value="7005"></constructor-arg>
                </bean>
            </set>
        </property>
    </bean>

    <bean id="redis4CacheConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <constructor-arg name="clusterConfig" ref="redisClusterConfig" />
        <property name="timeout" value="${redis.timeout}" />
        <property name="poolConfig" ref="poolConfig"/>
    </bean>


    <bean name="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="redis4CacheConnectionFactory" />
        <property name="keySerializer" ref="stringRedisSerializer" />
        <property name="hashKeySerializer" ref="stringRedisSerializer" />
        <property name="valueSerializer" ref="stringRedisSerializer" />
        <property name="hashValueSerializer" ref="stringRedisSerializer" />
    </bean>

未来在 Spring 配置文件中援引

<import resource="redis-cluster-context.xml" />

分解以上配置

poolConfig是连接池配置,redisClusterConfig 配置了 Redis
集群的依次节点(节点 host 和 port 最棒写在品质配置文件中),集群搭建可知作者的 另一篇博客 。然后上边和单机配置一样了,一对
JedisConnectionFactory 和 RedisTemplate 。

现在在 Service 层即可注入并援引这些 RedisTemplate,代码如下:

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.io.*;

/**
 * Created by fengdezitai on 2016/9/29.
 */
@Repository
public class RedisClusterCache {

    @Autowired
    private RedisTemplate clusterRedisTemplate;


    public void put(Object key, Object value) {
        if(null == value) {
            return;
        }

        if(value instanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }

        // TODO Auto-generated method stub
        final String keyf = key + "";
        final Object valuef = value;
        final long liveTime = 86400;

        clusterRedisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    public Object get(Object key) {
        final String keyf = (String) key;
        Object object;
        object = clusterRedisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);

            }
        });

        return object;
    }

    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }

    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }
}

末了在 Controller 中调用即可

@Controller
@RequestMapping(value = "redisCluster")
public class RedisClusterController {

    @Autowired
    private RedisClusterCache redisClusterCache;

    @RequestMapping(value = "clusterSave",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public Object clusterSave(){
        //redisClusterCache.put("cluster","save cluster");
        Token token = new Token();
        token.setExpires_in(1000);
        token.setAccess_token("hello world");
        redisClusterCache.put("token",token);
        return "ok";
    }

    @RequestMapping(value = "getKey",method = RequestMethod.GET)
    @ResponseBody
    public Object getCluster(String key){
        Object val = redisClusterCache.get(key);
        return val;
    }
} 

注意事项:

  • 本子难题,尽管用 spring-data-redis 做集成操作 Reids
    集群,唯有 spring-data-redis
    方今风尚版本1.7才含有对集群的操作,而新颖的 spring-data-redis
    中的有些意义对 Spring mvc
    的本子也有个别限制,所以尽大概接纳高版本的 Spring mvc 对应。
  • 一经存款和储蓄的value值是三个实体对象,那么势须要贯彻 Serializable 接口

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图