springboot内存缓存_SpringCloud微服务项目实战 缓存详解及高效缓存接入

缓存,已经是现在系统中必不可少的内容,如何使用好缓存,对系统的性能和效率至关重要,这里我就来分析一下使用缓存的正确姿势吧。

1f759789a8967e3732eb76adc76487db.png

如今的微服务项目,都是前后端分离,上面就是简单的服务架构图。在整个服务器项目中,有哪些需要我们做缓存呢,这里大致有:客户端缓存、文件缓存及网络加速和后端数据缓存。

缓存技术简介

1,客户端缓存

客户端缓存主要包含如客户使用的PC上的浏览器、手机App、微信小程序等。客户端缓存的原则就是尽量减少或消灭请求,以达到降低服务器压力和提升用户体验的效果。静态文件,例如Js、html、css、图片等内容,它们的很多可以只请求1次,然后缓存在本地,之后就优先从本地缓存中获取,这样就减少了对Web服务器的频繁请求。

507c94590ef64d722709a97dea3a1caf.png

如常见的浏览器缓存,可以通过Http的头信息控制缓存是通过Expires(强缓存)、Cache-control(强缓存)、Last-Modified/If-Modified-Since(协商缓存)、Etag/If-None-Match(协商缓存)实现。具体使用方法和区别,这里就不赘叙了哈。

客户端缓存的优缺点:

    优点:减少网络传输,加快页面内容展示速度,提升用户体验。

    成本:占用客户端的部分内存和磁盘,影响实时性。

2,文件缓及网络加速 除了前面说的前端缓存,针对一些静态资源,我们可以一次加载,实现本地缓存。那如果同时有一万、十万甚至更多的用户初次使用呢,这就使得大量的请求同时请求web服务器,势必给服务器带来很大的压力。基于这种情况,我们又如何来解决应对呢?这就是要说的新的内容--网络加速。目前流行的网络加速解决方案主要是CDN技术,那什么又是CDN呢,我这里做简单介绍。 CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络,为了能在传统IP网上发布丰富的宽带媒体内容,在现有互联网基础上建立一个内容分发平台专门为网站提供服务。CDN网络是在用户和服务器之间增加了一层缓存层,将用户的请求引导到最优的缓存节点而不是服务器源站,从而加块访问速度。 4b2db5e124a3d24d9a191cbb463f195b.png

CDN的一般使用场景:

  1. 加速静态资源; 网站中有大量的html、js、css、图片等文件,可以将这些静态内容推送到CDN。

  2.  大文件的下载;软件下载,视频点播等存储网站。

  3. 部分与用户无关的高频接口加速,在高并发情况下提升接口响应时间。

关于CDN的接入使用,使用云服务器的可以直接通过域名去云服务厂商去买就行,这里不在多说。

3,数据缓存

这是整个整个项目中最重要的,也就是我们所说的服务端缓存。服务端缓存有服务自身的Session,也有第三方的缓存技术。在分布式微服务的环境下,几乎没人使用Session作为服务端缓存,基本都采用了第三方的Nosql缓存技术。

常用的Nosql缓存有:Memcached、Redis、mongoDB。那么我们到底选用那个呢,先来看看他们的优缺点。

1)Memcached

      优点:可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key、value的字节大小以及服务器硬件性能,日常环境中QPS高峰大约在4-6w左右)。适用于最大程度扛量。

      缺点:只支持简单的key/value数据结构,不像Redis可以支持丰富的数据类型。无法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据全部丢失。无法进行数据同步,不能将MC中的数据迁移到其他MC实例中。

2)Redis       优点:支持多种数据结构,支持持久化操作,可以进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操作,较好的防止数据丢失的手段。支持通过Replication进行数据复制,通过master-slave机制,可以实时进行数据同步复制,支持多级复制和增量复制,master-slave机制是Redis进行HA的重要手段。

      缺点:只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒。支持简单的事务需求,但业界使用场景很少,并不成熟,既是优点也是缺点。Redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用。MC和Redis都是Key-Value类型,不适合在不同数据集之间建立关系,也不适合进行查询搜索。

3)mongoDB

       mongoDB 是一种文档性的数据库。先解释一下文档的数据库,即可以存放xml、json、bson类型系那个的数据。这些数据具备自述性(self-describing),呈现分层的树状数据结构。

       mongoDB 存放json格式的数据。适合场景如:事件记录、内容管理或者博客平台,比如评论系统。

        mongodb与MC和Redis不同的是,它可以使用语句进行CRUD操作,处理和获取文档数据。操作语句如下:

  • 查询:db.col.find().pretty();

  • 添加:db.col.insert({name:'Lily',sex:'female',age:'18'});

  • 删除:db.col.remove(...);

  • 更新:db.col.update(...);

     mongodb与mysql不同,mysql的每一次更新操作都会直接写入硬盘,但是mongo不会,做为内存型数据库,数据操作会先写入内存,然后再会持久化到硬盘中去。

服务端缓存选取接入

经过上面的介绍说明,考虑到服务端接口数据类型已经持久化等,Redis似乎是我们的首选,当然你也可以选择Memcached,这个完全取决与自己的项目。这里我介绍下Redis在Springboot+SpringCloud微服务项目的接入。

1,首先在pom.xml里引入Redis依赖
    org.springframework.boot    spring-boot-starter-data-redis    ${springboot-redis.version}
2,配置Redis连接属性(application.yml)
spring:  redis:    # Redis库索引(默认为0)    database: 0    # Redis服务器地址    host: 192.168.1.1    # Redis服务端口    port: 6379    # Redis连接密码(默认为空)    password:     lettuce:      pool:        # 连接池最大连接数(默认为8)        max-active: 8        # 连接池最大空闲连接(默认为8)        max-idle: 8        # 连接池最小空闲连接(默认为0)        min-idle: 0        # 连接池最大阻塞等待时间        max-wait: -1ms
3,创建RedisConfig
@Configurationpublic class RedisConfig implements RedisSerializer {  private Converter serializer = new SerializingConverter();  private Converter deserializer = new DeserializingConverter();  static final byte[] EMPTY_ARRAY = new byte[0];  @Autowired  RedisConnectionFactory redisConnectionFactory;  @Bean  public RedisTemplate functionDomainRedisTemplate() {    RedisTemplate redisTemplate = new RedisTemplate<>();    initDomainRedisTemplate(redisTemplate, redisConnectionFactory);    return redisTemplate;  }  /**   * 设置数据存入 redis 的序列化方式   * @param redisTemplate   * @param factory   */  private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {    redisTemplate.setKeySerializer(new StringRedisSerializer());    redisTemplate.setHashKeySerializer(new StringRedisSerializer());    redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());    redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());    redisTemplate.setConnectionFactory(factory);  }  @Bean  public HashOperations hashOperations(RedisTemplate redisTemplate) {    return redisTemplate.opsForHash();  }  @Bean  public ValueOperations valueOperations(RedisTemplate redisTemplate) {    return redisTemplate.opsForValue();  }  @Bean  public ListOperations listOperations(RedisTemplate redisTemplate) {    return redisTemplate.opsForList();  }  @Bean  public SetOperations setOperations(RedisTemplate redisTemplate) {    return redisTemplate.opsForSet();  }  @Bean  public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {    return redisTemplate.opsForZSet();  }  @Override  public Object deserialize(byte[] bytes) {    if (bytes == null || bytes.length == 0) {      return null;    }    try {      return deserializer.convert(bytes);    } catch (Exception ex) {      throw new SerializationException("Cannot deserialize", ex);    }  }  @Override  public byte[] serialize(Object object) {    if (object == null) {      return EMPTY_ARRAY;    }    try {      return serializer.convert(object);    } catch (Exception ex) {      return EMPTY_ARRAY;    }  }}
4,缓存操作接口及实现
public interface CacheService {  boolean hasKey(String key);  boolean delete(String key);  Object get(String key);  void set(String key, Object value);  void set(String key, Object value, long timeout);}
@Componentpublic class CacheServiceImpl implements CacheService {  @Autowired  private ValueOperations valueOperation;  @Autowired  private RedisTemplate redisTemplate;  @Override  public boolean hasKey(String key) {    return redisTemplate.hasKey(key);  }  @Override  public boolean delete(String keys) {    return redisTemplate.delete(keys);  }  @Override  public void set(String key, Object value) {    valueOperation.set(key, value);  }  @Override  public Object get(String key) {    return valueOperation.get(key);  }  @Override  public void set(String key, Object value, long timeout) {    valueOperation.set(key,value,timeout,TimeUnit.SECONDS);  }}

5,编写测试实战

@RestController@RequestMapping(value = "/customer/")public class CustomerController {    @Autowired    private CustomerService customerService;    @Autowired    private CacheService cacheService;    @GetMapping("/id")    public Object findCustomerById(Integer customerId) {        Object obj = null;        if ((obj = cacheService.getCacheByKey(CustomerConstant.CUSTOMER_CACHE_PREFIX+customerId)) != null) {            return  ResultData.ok((CustomerInfo) obj);        } else {            // 从数据库获取            CustomerInfo customerInfo = customerService.findById(customerId);            if(customerInfo != null) {               cacheService.setCacheToRedis(CustomerConstant.CUSTOMER_CACHE_PREFIX+customerId,customerInfo,3600);            }            return ResultData.ok(customerInfo);        }    }}

今天就说到这里,下一篇继续说说缓存使用中的注意事项,以及面试时经常问到的缓存使用的相关问题。fc95ab4708dff9bcf18cfe63455c1119.png

推荐阅读: SpringCloud微服务项目实战 - 限流、熔断、降级处理 SpringCloud微服务项目实战 -  API网关Gateway详解实现 SpringCloud微服务项目实战 - 网关zuul详解及搭建

SpringCloud微服务项目实战 - 微服务调用详解(附面试题)

SpringCloud微服务项目实战,服务注册与发现(附面试题)

114f492a938a15b9974f7c864ed1a31c.gif114f492a938a15b9974f7c864ed1a31c.gif114f492a938a15b9974f7c864ed1a31c.gif114f492a938a15b9974f7c864ed1a31c.gif114f492a938a15b9974f7c864ed1a31c.gif

扫码关注公众号,发送关键词获取相关资料:

发“Springboot”领取电商项目实战源码;

发“SpringCloud”领取学习实战资料;

04ab45bb480d21d93a15f17d39b5a595.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值