At present our system database pressure is very large, to solve the bottleneck problem of the database is imperative, in order to solve the pressure of the database and other requirements, we commonly used is a variety of cache, such as REDis, this article will simply explain how to integrate redis cache storage, attached to github source code.


Environment to prepare

· Redis · IDEA development tools · JDK 1.8 and above · Maven 4.0 and aboveCopy the code

There are many examples of how to build Redis on the web, but I won’t go into details here. You can browse the web to install a wave of redis, and we will directly talk about how to integrate Redis in Spring.

The allocation of resources

1. Spring integrates redis

The first step is to set maven’s pom.xml reference as follows:

<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> < version > 1.6.0. RELEASE < / version > < / dependency > < the dependency > < groupId > redis. Clients < / groupId > < artifactId > jedis < / artifactId > < version > 2.7.3 < / version > < / dependency >Copy the code

Once you’ve set the reference, you’re ready to write the Redis configuration file in Spring, directly to the applicationContext.xml file:

<! -- redis --> <import resource="spring-redis.xml" />
Copy the code

Spring – redis. XML file:

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <! -- loading redis parameters --> <context:property-placeholder location="classpath:redis.properties"/ > <! -- Automatic annotation --> <! --<context:component-scan base-package="service.impl"/ > -- > <! -- jedis connection pool configuration parameter: --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <! -- Set the maximum number of connections --> <property name="maxTotal" value="${redis.maxActive}"></property> <! -- Set the maximum number of free times --> <property name="maxIdle" value="${redis.maxIdle}"></property> <! -- Set the timeout time --> <property name="maxWaitMillis" value="${redis.maxWait}"></property>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"></property>
        <property name="testOnReturn" value="${redis.testOnReturn}"></property> </bean> <! Jedis connection pool connects to local Redis service constructor injection --> <bean id="pool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="poolConfig"/>
        <constructor-arg index="1" value="${redis.host}"/>
        <constructor-arg index="2" value="${redis.port}"/>
        <constructor-arg index="3" value="${redis.maxWait}"/>
        <constructor-arg index="4" value="${redis.pass}"/> </bean> <! -- redis cache config --> <bean id="redisCache" class="client.RedisCache">
        <property name="pool" ref="pool"/>
    </bean>

</beans>
Copy the code

This file mainly describes the connection pool and configuration parameters of Jedis. It should be noted that the specific parameters may be different depending on the version of Jedis, for example, 2.5.1. If you reference other versions of Jedis, please refer to the source code for the attribute parameters.

The following is the redis.properties configuration file, which sets the specific parameter values:

# Redis settings
redis.host=localhost
redis.port=6379
redis.pass=123456

redis.maxIdle=25
redis.maxActive=100
redis.maxWait=1000
redis.testOnBorrow=false
redis.testOnReturn=false
Copy the code

2. Redis client writing

The environment and resources have been configured. Next time, we can start to write our Redis client program. The code is as follows:

package client; import com.alibaba.fastjson.JSON; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.util.ResourceBundle; /** ** <p> ** Created by yclimb on 2017/6/8. */ public class RedisClient {/** * pooled jedis link pool */ public static JedisPool jedisPool; Static {// read the related configuration ResourceBundle ResourceBundle = resourcebundle.getBundle ("redis");
        int maxActive = Integer.parseInt(resourceBundle.getString("redis.pool.maxActive"));
        int maxIdle = Integer.parseInt(resourceBundle.getString("redis.pool.maxIdle"));
        int maxWait = Integer.parseInt(resourceBundle.getString("redis.pool.maxWait"));

        String ip = resourceBundle.getString("redis.ip");
        int port = Integer.parseInt(resourceBundle.getString("redis.port")); JedisPoolConfig config = new JedisPoolConfig(); // Set the maximum number of connections config.setMaxTotal(maxActive); // Set the maximum number of idle config.setMaxIdle(maxIdle); // Set the timeout interval config.setMaxWaitmillis (maxWait); // Initialize connection pool jedisPool = new jedisPool (config, IP, port); } /** * set the string contents to the cache * @param key key * @param value value * @return
     * @throws Exception
     */
    public static boolean  set(String key,String value) throws Exception{
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }finally{ jedisPool.returnResource(jedis); }} /** * Set the object to the cache * @param key * @param value * @return
     */
    public static boolean  set(String key,Object value){
        Jedis jedis = null;
        try {
            String objectJson = JSON.toJSONString(value);
            jedis = jedisPool.getResource();
            jedis.set(key, objectJson);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }finally{ jedisPool.returnResource(jedis); }} /** * delete the cached object according to key * @param key * @return
     */
    public static boolean del(String key){
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }finally{ jedisPool.returnResource(jedis); }} /** * get content by key * @param key * @return
     */
    public static Object get(String key){
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Object value = jedis.get(key);
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }finally{ jedisPool.returnResource(jedis); }} /** * get the object by key * @param key * @return
     */
    public static <T> T get(String key,Class<T> clazz){
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String value = jedis.get(key);
            return JSON.parseObject(value, clazz);
        } catch (Exception e) {
            e.printStackTrace();
            returnnull; }finally{ jedisPool.returnResource(jedis); }}}Copy the code

This file is a simple Redis client that can be used directly to manipulate jedis access methods. The Test class is as follows:

package test; import client.RedisClient; import entity.City; import org.junit.Test; /** ** <p> ** Created by yclimb on 2017/6/8. */ public class SimpleClient {@test public voiduserCache(){// Save the object to the cache City City = new City(); city.setCity("city");
        city.setCity("1");
        city.setLastUpdate("2222"); Boolean reusltCache = redisclient.set ("city1", city);
        if (reusltCache) {
            System.out.println("Saving object to cache succeeded.");
        }else{
            System.out.println("Failed to save object to cache.");
        }
    }


    @Test
    public void getUserInfo(){

        City city = RedisClient.get("city1", City.class);
        if(city ! = null) { System.out.println("Objects retrieved from the cache," + city.getCity() + "@"+ city.getLastUpdate()); }}}Copy the code

At this point, our first simple Redis client is successful; However, we usually use RPC distributed architecture, so we also need a Service interface redis memory, convenient dubbo service call, below we write dubbo redis service memory.

Dubbo servitized Redis storage

First, we need to define a redis cache configuration class, the main user obtains and closes the Redis connection, needs to use the jedis pool when the resource configuration, the code is as follows:

package client; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.io.Serializable; @author yclimb */ public class RedisCache implements Serializable {/** * private static */ final Log LOG = LogFactory.getLog(RedisCache.class); /** * redis pool */ private JedisPool pool; public voidsetPool(JedisPool pool) {
        this.pool = pool;
    }

    /*static {
        if(pool == null) {ResourceBundle ResourceBundle = resourcebundle.getBundle (pool == null) {ResourceBundle ResourceBundle = resourcebundle.getBundle ("redis");
            int maxActive = Integer.parseInt(resourceBundle.getString("redis.maxActive"));
            int maxIdle = Integer.parseInt(resourceBundle.getString("redis.maxIdle"));
            int maxWait = Integer.parseInt(resourceBundle.getString("redis.maxWait"));

            String host = resourceBundle.getString("redis.host");
            int port = Integer.parseInt(resourceBundle.getString("redis.port"));
            String pass = resourceBundle.getString("redis.pass"); JedisPoolConfig config = new JedisPoolConfig(); // Set the maximum number of connections config.setMaxTotal(maxActive); // Set the maximum number of idle config.setMaxIdle(maxIdle); // Set the timeout interval config.setMaxWaitmillis (maxWait); Pool = new JedisPool(config, host, port, 2000, pass); }}*/ /** * get jedis ** @return jedis
     */
    public Jedis getResource() {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
        } catch (Exception e) {
            LOG.info("can't get the redis resource");
        }
        returnjedis; } @param jedis j */ public void disconnect(jedis jedis) {jedis.disconnect(); } /** * return jedis to the connection pool ** @param jedis j */ public voidreturnResource(Jedis jedis) {
        if(null ! = jedis) { try { pool.returnResource(jedis); } catch (Exception e) { LOG.info("can't return jedis to jedisPool"); }} public void brokenResource(jedis jedis) {}} public void brokenResource(jedis jedis) {if(jedis ! = null) { try { pool.returnBrokenResource(jedis); } catch (Exception e) { LOG.info("can't release jedis Object"); }}}}Copy the code

By default, configuration files given in Spring are used for automatic injection, or static code blocks annotated in the code can be used, depending on your needs.

With the cache configuration and the Jedis pool in place, we are now ready to write the add, delete, change and check service storage as follows:

Interface: RedisCacheStorageService. Java:

package service; import java.util.Map; @author yclimb @param <K> key @param <V> value */ public interface RedisCacheStorageService<K, V> {/** ** insert key and value ** @param key * @param value * @ into redis databasereturn
     */
    boolean set(K key, V value); /** * Insert key and value into redis database and set expiration time ** @param key * @param value * @param exp expiration time s * @return
     */
    boolean set(K key, V value, int exp); /** * get value ** @param key * @ from redisreturn*/ V get(K key); /** * delete data from redis library ** @param key * @return*/ boolean remove(K key); /** * set hash type data to redis database ** @param cacheKey can be seen as a table * @param key table field * @param value * @return*/ boolean hset(String cacheKey, K key, V value); /** * Get the value of the hash table data type ** @param cacheKey * @param key * @return*/ V hget(String cacheKey, K key); /** * get hash type data ** @param cacheKey * @return
     */
    Map<K, V> hget(String cacheKey);
}

Copy the code

Implementation class: RedisCacheStorageServiceImpl. Java:

package service.impl; import client.RedisCache; import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; import service.RedisCacheStorageService; import java.util.HashMap; import java.util.Map; / redis cache memory to realize * * * * @ author yclimb * * @ param > < V * / @ Service public class RedisCacheStorageServiceImpl < V > implements RedisCacheStorageService<String, V > {/ * * * logging * / public static final Log Log = LogFactory. GetLog (RedisCacheStorageServiceImpl. Class); Private static final int EXPIRE_TIME = 86400; private static final int EXPIRE_TIME = 86400; @Autowired private RedisCache redisCache; /** * insert key and value into redis database ** @param key k * @param value v * @return boolean
     */
    @Override
    public boolean set(String key, V value) {// Set the default stale timereturn set(key, value, EXPIRE_TIME); } /** * Insert key and value into redis database and set expiration time ** @param key k * @param value v * @param exp expiration time s * @return boolean
     */
    @Override
    public boolean set(String key, V value, int exp) { Jedis jedis = null; JKey = json.tojsonString (key); // Convert key and value toJSON objects. String jValue = JSON.toJSONString(value); Boolean isSucess = if the operation succeedstrue;
        if (StringUtils.isEmpty(jKey)) {
            LOG.info("key is empty");
            return false; } try {// get the client object jedis = rediscache.getResource (); // insert jedis.setex(jKey, exp, jValue); } catch (Exception e) { LOG.info("client can't connect server");
            isSucess = false;
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }return false;
        } finally {
            if(isSucess) {/ / return the connection pool redisCache returnResource (jedis); }}return true; } /** * get value ** @param key k * @returnobj */ @Override public V get(String key) { Jedis jedis = null; JKey = json.tojsonString (key); // Convert key and value toJSON objects. V jValue = null; // Key cannot be emptyif (StringUtils.isEmpty(jKey)) {
            LOG.info("key is empty");
            returnnull; } try {// get the client object jedis = rediscache.getResource (); String value = jedis.get(jKey); // Check whether the value is non-nullif (StringUtils.isEmpty(value)) {
                return null;
            } else{ jValue = (V) JSON.parse(value); } / / return the connection pool redisCache returnResource (jedis); } catch (Exception e) { LOG.info("client can't connect server");
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }}returnjValue; } /** * delete data from redis library ** @param key k * @returnboolean */ @Override public boolean remove(String key) { Jedis jedis = null; JKey = json.tojsonString (key); // Convert key and value toJSON objects. Boolean isSucess = if the operation succeedstrue;
        if (StringUtils.isEmpty(jKey)) {
            LOG.info("key is empty");
            return false; } try { jedis = redisCache.getResource(); // Delete jedis.del(jKey); } catch (Exception e) { LOG.info("client can't connect server");
            isSucess = false;
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }return false;
        } finally {
            if(isSucess) {/ / return the connection pool redisCache returnResource (jedis); }}return true; } /** * set hash type data to redis database ** @param cacheKey can be seen as a table * @param key table field * @param value v * @returnboolean */ @Override public boolean hset(String cacheKey, String key, V value) { Jedis jedis = null; JKey = json.tojsonString (key); // Convert key and value toJSON objects. String jCacheKey = JSON.toJSONString(cacheKey); String jValue = JSON.toJSONString(value); Boolean isSucess = if the operation succeedstrue;
        if (StringUtils.isEmpty(jCacheKey)) {
            LOG.info("cacheKey is empty");
            return false; } try { jedis = redisCache.getResource(); // Execute insert hash jedis.hset(jCacheKey, jKey, jValue); } catch (Exception e) { LOG.info("client can't connect server");
            isSucess = false;
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }return false;
        } finally {
            if(isSucess) {/ / return the connection pool redisCache returnResource (jedis); }}return true; CacheKey cacheK * @param key k * @returnobj */ @Override public V hget(String cacheKey, String key) { Jedis jedis = null; JKey = json.tojsonString (key); // Convert key and value toJSON objects. String jCacheKey = JSON.toJSONString(cacheKey); V jValue = null;if (StringUtils.isEmpty(jCacheKey)) {
            LOG.info("cacheKey is empty");
            returnnull; } try {// get the client object jedis = rediscache.getResource (); String value = jedis.hget(jCacheKey, jKey); // Check whether the value is non-nullif (StringUtils.isEmpty(value)) {
                return null;
            } else{ jValue = (V) JSON.parse(value); } / / return the connection pool redisCache returnResource (jedis); } catch (Exception e) { LOG.info("client can't connect server");
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }}returnjValue; } /** * get hash type data ** @param cacheKey cacheK * @returnmap */ @Override public Map<String, V> hget(String cacheKey) { String jCacheKey = JSON.toJSONString(cacheKey); // Non-null checkif (StringUtils.isEmpty(jCacheKey)) {
            LOG.info("cacheKey is empty!");
            returnnull; } Jedis jedis = null; Map<String, V> result = null; try { jedis = redisCache.getResource(); Map<String, String> Map = jedis.hgetall (jCacheKey);if(null ! = map) {for (Map.Entry<String, String> entry : map.entrySet()) {
                    if (result == null) {
                        result = new HashMap<String, V>();
                    }
                    result.put((String) JSON.parse(entry.getKey()), (V) JSON.parse(entry.getValue()));
                }
            }
        } catch (Exception e) {
            LOG.info("client can't connect server");
            if(null ! = jedis) {/ / release jedis object redisCache brokenResource (jedis); }}returnresult; }}Copy the code

Now that we have written our memory, it is time to see how to inject the Dubbo service. Here is the sample code for the injection:

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <! -- redis --> <dubbo:service timeout="${dubbo-timeout}" retries="${dubbo-retries}" interface="com.yc.redis.RedisCacheStorageService" ref="redisCacheStorageServiceImpl" group="${service.group}" />

</beans>
Copy the code

OK, the code is finished, here dubbo service call code I will not paste, you can try it yourself, here is a set of jedis based on a simple example is completed.

conclusion

Source code address: github.com/YClimb/redi…

To this article is over, pay attention to the public account to view more push!!