威尼斯人线上娱乐

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

31 3月 , 2019  

一、简介

  近期因为做事亟待,使用了部分单机版Redis的界面化管理工科具,使用进度中那忧伤的体验真正唯有用过的人才能体味;为此笔者和同伙准备入手三个Redis可视化学工业具,不过因为小伙伴近期工作相比较忙,搞了半数以上没有时间继续(会有继续,界面不敢说,使用体验方面肯定要比现有的好);自身对wpf不是很熟,再想到很久在此之前的web迅雷,就想初叶达成多个web版的Redis的界面化管理工科具;近来那个工具已开始成型,所以放出去分享一下。

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

 本文原创,转发请评释:

有关 Redis 集群搭建能够参照笔者的另一篇小说 Redis集群搭建与简便利用

Redis 是怎么,能做怎么着

Redis
是3个开源(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 代码拿过来引用即可,只需兑现2个造访 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。

随后在 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值是贰个实体对象,那么一定要完结 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

  一些好端端的增加和删除改查的成效都有,近来还有部分询问功用、集群众管理理等没有做到,今后查询项私下认可都是肆18个,后续再稳步加上吧。  

至于 Redis
集群搭建可以参考小编的另一篇文章 Redis集群搭建与简便利用

零、开发条件

1.使用的node版本为v6.11.3
LTS(Redis的nodejs开发案例,Redis可视化学工业具Web。明知故犯声明:以身作则代码应用了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 是什么,能做什么

一 、创造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
是3个开源(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两种数据类型(库克ie和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);

能够看到引用了2个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 的
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。

现在在 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 代码拿过来引用即可,只需兑现1个拜访 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值是一个实体对象,那么必然要促成 塞里alizable 接口

 


相关文章

发表评论

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

网站地图xml地图