完成前台门户页面系统功能(十四)使用redis构建缓存以及缓存同步

为什么要使用redis?有什么意义?

使用redis可以加快页面加载的速度。

在页面一打开的时候,首先去redis中找是否有对应的缓存的内容,要是有的话就直接加载缓存,然后再加载在页面上面,这样就可以加快页面加载的速度,而不用每次加载页面的时候都去数据库进行查询,当数据比较大的时候,那么加载的速度就会很慢。

1 使用redis做缓存。

1.1 在vm中安装redis服务

安装的前提条件:

   需要安装 gcc:yum install gcc-c++

  1. 安装第三方库:  yum install epel-release
  2. 再安装 redis 即可:  yum install redis
  3. 使用 service redis start 命令启动 redis 服务端
  4. iptables -I INPUT 1 -p tcp --dport 6379 -j ACCEPT
  5. 使用 ps -ef | grep redis 查看 redis 进程 

 

      6. vi /etc/redis.conf 。直接/bind 回车,然后修改为你虚拟机的 ip 地址,不然无法访问。

使用 redis manager 连接: 

 

1.2 通过使用jedis来对redis进行操作。

需要把 jedis 的 jar 包添加到工程中,如果是 maven 需要添加 jar 包的坐标,配置如下:

 

2.开发过程

2.1 jedis整合spring

<!-- 连接池配置 --> 
     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> 
          <!-- 最大连接数 --> 
          <property name="maxTotal" value="30" /> 
          <!-- 最大空闲连接数 --> 
          <property name="maxIdle" value="10" /> 
          <!-- 每次释放连接的最大数目 --> 
          <property name="numTestsPerEvictionRun" value="1024" /> 
          <!-- 释放连接的扫描间隔(毫秒) --> 
          <property name="timeBetweenEvictionRunsMillis" value="30000" /> 
          <!-- 连接最小空闲时间 --> 
          <property name="minEvictableIdleTimeMillis" value="1800000" /> 
          <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 --> 
          <property name="softMinEvictableIdleTimeMillis" value="10000" /> 
          <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 --> 
          <property name="maxWaitMillis" value="1500" /> 
          <!-- 在获取连接的时候检查有效性, 默认false --> 
          <property name="testOnBorrow" value="true" /> 
          <!-- 在空闲时检查有效性, 默认false --> 
          <property name="testWhileIdle" value="true" /> 
          <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --> 
          <property name="blockWhenExhausted" value="false" /> 
     </bean>  
     <!-- jedis客户端单机版 --> 
     <bean id="redisClient" class="redis.clients.jedis.JedisPool"> 
          <constructor-arg name="host" value="192.168.48.129"></constructor-arg> 
          <constructor-arg name="port" value="6379"></constructor-arg> 
          <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg> 
     </bean> 

 

测试:

/** 
*    <p>Title: testSpringJedisSingle</p> 
*    <p>Description: </p> 
      */      
   @Test
public void testSpringJedisSingle() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml"); JedisPool pool = (JedisPool) applicationContext.getBean("redisClient"); Jedis jedis = pool.getResource(); String string = jedis.get("key1"); System.out.println(string); jedis.close(); pool.close();

 

 2.2 添加redis dao

package com.jingxi.rest.dao;

public interface JedisClient {

    String get(String key);
    String set(String key,String value);
    String hget(String hkey,String key);
    long hset(String hkey,String key,String value);
    long incr(String key);
    long expire(String key,int second);
    long ttl(String key);
    long del(String key);
    long hdel(String hkey,String key);
}
package com.jingxi.rest.dao;

import org.springframework.beans.factory.annotation.Autowired;

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

public class JedisClientSingle implements JedisClient {

    

    @Autowired
    private JedisPool jedisPool;
    @Override
    public String get(String key) {
        Jedis jedis= jedisPool.getResource();
        String string= jedis.get(key);
        jedis.close();
        return string;
    }

    @Override
    public String set(String key, String value) {
        Jedis jedis= jedisPool.getResource();
        String string= jedis.set(key, value);
        jedis.close();
        return string;
    }

    @Override
    public String hget(String hkey, String key) {
        Jedis jedis= jedisPool.getResource();
        String string= jedis.hget(hkey, key);
        jedis.close();
        return string;
    }

    @Override
    public long hset(String hkey, String key, String value) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.hset(hkey, key, value);
        jedis.close();
        return result;
    }

    @Override
    public long incr(String key) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.incr(key);
        jedis.close();
        return result;
    }

    @Override
    public long expire(String key, int second) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.expire(key, second);
        jedis.close();
        return result;
    }

    @Override
    public long ttl(String key) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.ttl(key);
        jedis.close();
        return result;
    }

    @Override
    public long del(String key) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.del(key);
        jedis.close();
        return result;
    }

    @Override
    public long hdel(String hkey, String key) {
        Jedis jedis= jedisPool.getResource();
        Long result= jedis.hdel(hkey,key);
        jedis.close();
        return result;
    }

}

 

 

2.3 在jingxi-rest中的获取内容列表的方法中加入缓存

注意:缓存的添加不能影响正常的业务逻辑。

正常的逻辑应该变成:调用这个方法的时候,首先去缓存中找是否存在缓存内容,如果有的话则直接return 内容。要是没有内容的话,那么就去数据库中进行查找,查找到内容后,先将查找到的内容保存在缓存中,然后再返回查找到的内容。

@Service
public class ContentServiceImpl implements ContentService {

    @Autowired
    private TbContentMapper tbContentMapper;
    
    @Autowired
    private JedisClient jedisClient;
    
    private static final String INDEX_CONTENT_REDIS_KEY="INDEX_CONTENT_REDIS_KEY";
    @Override
    public List<TbContent> getContentList(long contentCid) {
        //首先是取緩存中取内容
        try{
            String result=jedisClient.hget(INDEX_CONTENT_REDIS_KEY, contentCid+"");
            if(result!=null){
                List<TbContent> resultList=JsonUtils.jsonToList(result, TbContent.class);
                return resultList;
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        //根據内容分類的id查詢内容列表
        TbContentExample example =new TbContentExample();
        Criteria critria =example.createCriteria();
        critria.andCategoryIdEqualTo(contentCid);
        List<TbContent> list=tbContentMapper.selectByExample(example);
        //向緩存中添加内容數據
        try{
            //把list轉換成字符串
            String cacheString =JsonUtils.objectToJson(list);
            jedisClient.hset(INDEX_CONTENT_REDIS_KEY, contentCid+"", cacheString);
        }catch(Exception e){
            e.printStackTrace();
        }
        return list;
    }

}

 

2.4 运行效果

测试结果:运行之前:

运行之后,缓存成功插入:

首页显示正常:

 

3.有关缓存同步的内容

3.1 需求分析

当在cms系统中对内容进行增加,修改,删除的时候,那么我们应该删除原本保存在缓存中的内容,这样在页面显示的内容才是最实时的内容,而不会出现说我改后的内容没有在首页展示出来,而是展示修改前的内容。

3.2 添加缓存后的架构

 

3.3 解决方案

在 jingxi-rest 工程中发布一个服务。当后台管理系统修改内容后,调用此服务,同步缓存。

 

3.3.1 dao层

3.3.2 service层

 

3.3.3 controller层

 

4 在jingxi-backend中调用jingxi-rest的服务

只要在对应的service层中调用这个服务即可

例如添加的方法中:

 

posted @ 2017-10-21 11:07  梦想在深圳立足  阅读(555)  评论(0编辑  收藏  举报