给webflux增加缓存

栏目: ASP.NET · 发布时间: 4年前

内容简介:上一篇中已经给用户管理增加了页面,看上去比较low,但是不犯该大家学习。今天增加redis来作为缓存。当用户访问量增大的时候,并发量也会增大,同一时间数据库查询的压力也会增大。尽管mongodb的查询速度已经很快了,但是也会出现性能瓶颈,一般会通过集群来解决。另一方面就是增加缓存,使得不用每次查询都要经过数据库。提高响应速度。关于redis的安装,我之前的文章中已经讲过了,可关注我的公众号

上一篇中已经给用户管理增加了页面,看上去比较low,但是不犯该大家学习。今天增加 redis 来作为缓存。

1 为什么要做缓存

当用户访问量增大的时候,并发量也会增大,同一时间数据库查询的压力也会增大。尽管 mongodb 的查询速度已经很快了,但是也会出现性能瓶颈,一般会通过集群来解决。另一方面就是增加缓存,使得不用每次查询都要经过数据库。提高响应速度。

2 缓存策略

  • 在查询方法中先从缓存中取,如果没有则查询数据库
  • 在删除方法中,同时删除缓存中的值
  • 在更新操作中,同步修改缓存中的值

3 添加依赖

关于redis的安装,我之前的文章中已经讲过了,可关注我的公众号 mike啥都想搞 在教程中查看。补充:

之前我们讲了如和设置redis的密码,可是都不生效。是因为启动方式不对,需要指定备至文件

redis-server.exe redis.windows.conf
<!-- Spring Boot 响应式 Redis 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

设置redis连接:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=mike123
spring.redis.timeout=5000

4 改造service中的方法

package com.mike.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.mike.dao.UserDao;
import com.mike.po.User;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * The class UserService.java
 */
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    public Mono<User> saveOrUpdateUser(User user){
        //删除缓存
        if (redisTemplate.hasKey("user_"+user.getId())) {
            redisTemplate.delete("user_"+user.getId());
        }
        return userDao.save(user);
    }
    
    public Mono<User> findById(String id){
        redisTemplate.opsForValue().set("test","test");
        //先查找缓存
        boolean hashKey = redisTemplate.hasKey("user_"+id);
        if (hashKey) {
            User u = (User) redisTemplate.opsForValue().get("user_"+id);
            return Mono.create(rs -> rs.success(u));
        }
        Mono<User> m = userDao.findById(id);
        if (m!=null) { //更新缓存
            m.subscribe(u -> {
                redisTemplate.opsForValue().set("user_"+u.getId(), u);
            });
        }
        return m;
    }
    
    public Flux<User> findAll(){
        return userDao.findAll().cache();
    }
    
    public  void deleteById(String id){
        // 使用mongoTemplate来做删除   直接使用提供的删除方法不行
        Query query = Query.query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, User.class);
        //userDao.deleteById(id);  这样无法删除,不知道为什么
        
        //同时删除缓存
        if (redisTemplate.hasKey("user_"+id)) {
            redisTemplate.delete("user_"+id);
        }
    }
}

总结

一般我们会和 @cacheable 注解配合使用,但是在webflux中,我们需要手动编程来实现redis的数据存储。原因是Mono / Flux 对象没有实现 Serializable。上面用的是同步操作redis,还有一个异步操作 ReactiveRedisTemplate ,但是因为我们操作缓存的时候要先进行 key 的判断后在执行后续操作,这是同步过程。使用 ReactiveRedisTemplate 的话感觉操作比较麻烦,谁如果有好的写法可以一起交流下。

填坑: User 对象需要实现Serializable,否则redis存储会失败。


以上所述就是小编给大家介绍的《给webflux增加缓存》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

UNIX系统编程: 通信、并发与线程

UNIX系统编程: 通信、并发与线程

【美】Kay Robbins、Steve Robbins / 师蓉 / 电子工业出版社 / 2018-5 / 198

《UNIX系统编程: 通信、并发与线程》是一本基于最新UNIX标准的完备的参考书,对UNIX编程的要点进行了清晰易懂的介绍,从一些用于说明如何使用系统调用的短小代码段开始,逐渐过渡到能帮助读者扩展自己技能水平的实际项目中。《UNIX系统编程: 通信、并发与线程》中对通信、并发和线程问题进行了深入探讨,对复杂的概念(如信号和并发)进行了全面且清晰的解释,还覆盖了与文件、信号、信号量、POSIX线程和......一起来看看 《UNIX系统编程: 通信、并发与线程》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具