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

一、简介

  近年来因为做事索要,使用了有个别单机版Redis的界面化管理工科具,使用进程中那痛楚的心得真正唯有用过的人才能体会;为此笔者和同伴准备出手3个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 对应三个 JedisConnectionFactory
,那样能够安顿依据气象布局差别的 Redis
连接,比如超时时间须求不一致等、database 0-15
可以储存分化的数量等。这里就安插了database 1 和 2
,调用 commonRedisTemplate 会存到 database1 ,调用 cacheRedisTemplate
会存到 database2。

Redis的nodejs开发案例,Redis可视化学工业具Web。从此在 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 中调用达成的 瑟维斯 即可

@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 接口

 

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

 本文原创,转发请注解:

作为一名曾今的pythoner,在既往的web开发工作时,接触过Django、Flask、Tornado等框架;而近年来投入nodejs的胸怀,任天由命接触到了Express和Restify框架,上边就依照自身的入门经验,写一个restify+mongoose+redis进行web开发的简练示例。

二 、基本使用手续

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

  澳门葡京备用网址 1

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

  澳门葡京备用网址 2

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

  澳门葡京备用网址 3

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

  澳门葡京备用网址 4

  添加事业有成后会自动显示在左边:

  澳门葡京备用网址 5

  澳门葡京备用网址 6

  澳门葡京备用网址 7

  一些健康的增加和删除改查的功效都有,近年来还有一些查询功能、集群众管理理等尚未马到成功,以后查询项私下认可都是四十几个,后续再稳步加上吧。  

至于 Redis
集群搭建能够参见笔者的另一篇小说 Redis集群搭建与简便利用

零、开发环境

1.使用的node版本为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 安装在本项目
贰个名为package.json的文件是它的好基友,不信自身慢慢看

叁 、开发简介

  上边根本是根据SAEA.Socket通讯框架中的SAEA.RedisSocket、SAEA.WebApi八个零件来促成redis通讯、webserver以及仿asp.net
mvc的敏捷风格的后端程序,web端使用的是layui+ajax。项目源码结构:

  澳门葡京备用网址 8

 

Redis 是何等,能做咋样

① 、创设一个行使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对于3个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本子,如下:

5、接口测试

在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 代码拿过来引用即可,只需兑现1个访问 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 代码拿过来引用即可,只需兑现一个访问 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 接口

 

相关文章

发表评论

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

*
*
Website