Redis中央缓存

Redis

分布式缓存(中央缓存)

1.发起请求
2.检查redis中是否有缓存,有就返回,没有就查询
3.没有就查询数据库数据
4.同步一份数据到redis
5.返回结果
优点:
1.作为独立服务,不会和其他服务抢占资源;
2.中央缓存不存在数据不同步的问题

搭建缓存服务

1.导包

  <!--注册中心客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--springboot的web支持包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--配置中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
<!--集成jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.2.0</version>
        </dependency>
    </dependencies>

2.application.yml注册到注册中心

eureka:
  client:
    service-url:
     defaultZone: http://localhost:1010/eureka/
  instance:
    prefer-ip-address: true  #使用IP进行注册
    instance-id: redis-server:2030 #服务中心显示的名字
#端口号
server:
  port: 2030

spring:
  application:
    name: redis-server  #服务名称

3.配置类

@SpringBootApplication
public class RedisServerApplication {
     
    public static void main(String[] args) {
     
        SpringApplication.run(RedisServerApplication.class);
    }
}

4.RedisUtil

package cn.itsource.util;

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

import java.io.IOException;
import java.util.Properties;

/**
 * 获取连接池对象
 */
public enum RedisUtils {
     
    INSTANCE;
    static JedisPool jedisPool = null;

    static {
     
        //1 创建连接池配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //2 进行配置-四个配置
        config.setMaxIdle(1);//最小连接数
        config.setMaxTotal(11);//最大连接数
        config.setMaxWaitMillis(10 * 1000L);//最长等待时间
        config.setTestOnBorrow(true);//测试连接时是否畅通
        //3 通过配置对象创建连接池对象
        Properties properties = null;
        try {
     
            properties = new Properties();
            properties.load(RedisUtils.class.getClassLoader().getResourceAsStream("redis.properties"));
        } catch (IOException e) {
     
            e.printStackTrace();
        }
        String host = properties.getProperty("redis.host");
        String port = properties.getProperty("redis.port");
        String password = properties.getProperty("redis.password");
        String timeout = properties.getProperty("redis.timeout");

        jedisPool = new JedisPool(config, host, Integer.valueOf(port),Integer.valueOf(timeout), password);
    }

    //获取连接
    public Jedis getSource() {
     
        return jedisPool.getResource();
    }

    //关闭资源
    public void closeSource(Jedis jedis) {
     
        if (jedis != null) {
     
            jedis.close();
        }

    }

    /**
     * 设置字符值
     *
     * @param key
     * @param value
     */
    public void set(String key, String value) {
     
        Jedis jedis = getSource();
        jedis.set(key, value);
        closeSource(jedis);
    }

    /**
     * 设置
     * @param key
     * @param value
     */
    public void set(byte[] key, byte[] value) {
     
        Jedis jedis = getSource();
        jedis.set(key, value);
        closeSource(jedis);
    }

    /**
     *
     * @param key
     * @return
     */
    public byte[]  get(byte[] key) {
     
        Jedis jedis = getSource();
        try {
     
            return jedis.get(key);
        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
     
            closeSource(jedis);
        }
        return null;

    }

    /**
     * 设置字符值
     *
     * @param key
     */
    public String get(String key) {
     
        Jedis jedis = getSource();
        try {
     
            return jedis.get(key);
        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
     
            closeSource(jedis);
        }

        return null;

    }
}

5.准备redis.properties文件

redis.host=127.0.0.1
redis.port=6379
redis.password=redis密码
redis.timeout=3000

6.controller层

@RestController
@RequestMapping("redis")
public class RedisController {
     

    //设置值
    @PostMapping("/set")
    public AjaxResult set(@RequestParam("key")String key,@RequestParam("value")String value) {
     
        RedisUtils.INSTANCE.set(key,value );
        return AjaxResult.me();
    }
    //获取值
    @GetMapping("/get/{key}")//获取请求中的key
    public AjaxResult get(@PathVariable("key")String key) {
     
        String result = RedisUtils.INSTANCE.get(key);
        return AjaxResult.me().setResultObj(result);
    }
}

AjaxResult工具

//Ajax请求响应对象的类
public class AjaxResult {
     
    private boolean success = true;
    private String message = "操作成功!";


    //返回到前台对象
    private Object resultObj;

    public boolean isSuccess() {
     
        return success;
    }

    public AjaxResult setSuccess(boolean success) {
     
        this.success = success;
        return this;
    }

    public String getMessage() {
     
        return message;
    }

    public AjaxResult setMessage(String message) {
     
        this.message = message;
        return this;
    }

    public Object getResultObj() {
     
        return resultObj;
    }

    public AjaxResult setResultObj(Object resultObj) {
     
        this.resultObj = resultObj;
        return this;
    }

    //AjaxResult.me()成功
    //AjaxResult.me().setMessage()成功
    //AjaxResult.me().setSuccess(false),setMessage("失败");
    public  static AjaxResult me(){
     
        return new AjaxResult();
    }



    /*
    //成功
    public AjaxResult() {
    }

    //失败并且有提示
    public AjaxResult(String message) {
        this.success = false;
        this.message = message;
    }*/
}

使用postman测试http://localhost:端口号/资源路径

其他服务和中央缓存对接

服务集成Feign

因为通过feign去访问缓存服务,所以先要集成feign

1.导包
 <!--依赖feign-->
        <dependency>
            <groupId>cn.itsource</groupId>
            <artifactId>hrm-feign-server</artifactId>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
2.需要做缓存的服务集成feign

服务之间访问要通过feign去访问redis,所以需要集成feign

  • 配置类加上@EnableFeignClients开启feign
    Redis中央缓存_第1张图片
  • 在服务的实现类中,在需要做缓存的数据对应的方法里做缓存,同时也需要在添加修改删除时做缓存更新,避免访问到脏数据
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
     

    //注入feign的接口
    @Autowired
    private IRedisFeignClient redisFeignClient;


    @Override
    public boolean insert(CourseType entity) {
     

        boolean insertResult = super.insert(entity);
        //添加完成之后查询数据库,缓存到redis中
        resetRedis();
        return insertResult;
    }

    @Override
    public boolean deleteById(Serializable id) {
     
        boolean deleteResult=super.deleteById(id);
        //删除完成之后查询数据库,缓存到redis中
        resetRedis();
        return deleteResult;
    }

    @Override
    public boolean updateById(CourseType entity) {
     
        boolean updateResule=super.updateById(entity);
        //修改完成之后查询数据库,缓存到redis中
        resetRedis();
        return updateResule;
    }

    //查询数据缓存到redis中
    private List<CourseType> resetRedis() {
     
        //没有数据就取数据库查询
        //先查询出所有的分类
        List<CourseType> courseTypeList = baseMapper.selectList(null);
        //放一份数据到redis中
        redisFeignClient.set(RedisConstant.COURSE_TYPE, JSON.toJSONString(courseTypeList));
        return courseTypeList;
    }
	//查询树形菜单
    @Override
    public List<CourseType> selectTreeType() {
     

        List<CourseType> courseTypeList=null;

        //先查询redis里面有不有数据 根据key查询 常量
        AjaxResult result = redisFeignClient.get(RedisConstant.COURSE_TYPE);
        if (result.getResultObj() != null && result.isSuccess()){
     
            //如果redis里面有数据,就直接返回
            String resultObj = result.getResultObj().toString();
            //将字符串转化为list
            courseTypeList = JSON.parseArray(resultObj, CourseType.class);

        }else {
     
            //没有数据就取数据库查询
            //先查询出所有的分类
            courseTypeList = baseMapper.selectList(null);
            //放一份数据到redis中
            redisFeignClient.set(RedisConstant.COURSE_TYPE, JSON.toJSONString(courseTypeList));
        }


        //先查询出所有的分类
       // List courseTypeList = baseMapper.selectList(null);
        //用一个List来装父分类
        List<CourseType> parentList = new ArrayList<>();

        //遍历所有分类,将父分类和子分类分别查询出来
        for (CourseType parentListItem : courseTypeList) {
     
            //如果pid为0 就说明是父
            if (parentListItem.getPid().longValue() == 0) {
     
                //将父分类放进List中
                parentList.add(parentListItem);
            }else {
     
                CourseType currentCourseType = null;
                //其余的都是子分类,遍历子分类
                for (CourseType childrenListItem : courseTypeList) {
     
                    //如果子分类的pid 等于
                    if (parentListItem.getPid().longValue() == childrenListItem.getId().longValue()) {
     
                        //就把对应的子分类放进对应的父分类中
                        currentCourseType=childrenListItem;
                        break;
                    }
                }

                if (currentCourseType != null) {
     
                    //如果子分类找到父分类,就放进父分类中
                    currentCourseType.getChildren().add(parentListItem);
                }

            }
        }
        return parentList;
    }
}

你可能感兴趣的:(redis)