Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结

2023-11-03

Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结
Nginx
对于中间件nginx常用来做流量的分发,同时nginx本身也有自己的缓存(容量有限),我们可以用来缓存热点数据,让用户的请求直接走缓存并返回,减少流向服务器的流量
一、模板引擎
通常我们可以配合使用freemaker/velocity等模板引擎来抗住大量的请求。
小型系统可能直接在服务器端渲染出所有的页面并放入缓存,之后的相同页面请求就可以直接返回,不用去查询数据源或者做数据逻辑处理。
对于页面非常之多的系统,当模板有改变,上述方法就需要重新渲染所有的页面模板,毫无疑问是不可取的。因此配合nginx+lua(OpenResty),将模板单独保存在nginx缓存中,同时对于用来渲染的数据也存在nginx缓存中,但是需要设置一个缓存过期的时间,以尽可能保证模板的实时性。

二、双层nginx来提升缓存命中率
对于部署多个nginx而言,如果不加入一些数据的路由策略,那么可能导致每个nginx的缓存命中率很低。因此可以部署双层nginx。
1. 分发层nginx负责流量分发的逻辑和策略,根据自己定义的一些规则,比如根据productId进行hash,然后对后端nginx数量取模将某一个商品的访问请求固定路由到一个nginx后端服务器上去。
2. 后端nginx用来缓存一些热点数据到自己的缓存区。
Redis
用户的请求,在nginx没有缓存相应的数据,那么会进入到redis缓存中,redis可以做到全量数据的缓存,通过水平扩展能够提升并发、高可用的能力。

一、持久化机制
持久化机制:将redis内存中的数据持久化到磁盘中,然后可以定期将磁盘文件上传至S3(AWS)或者ODPS(阿里云)等一些云存储服务上去。
如果同时使用RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整,建议将两种持久化机制都开启,用AO F来保证数据不丢失,作为数据恢复的第一选择;用RDB来作不同程度的冷备,在AOF文件都丢失或损坏不可用的时候来快速进行数据的恢复。
实战踩坑:对于想从RDB恢复数据,同时AOF开关也是打开的,一直无法正常恢复,因为每次都会优先从AOF获取数据(如果临时关闭AOF,就可以正常恢复)。此时首先停止redis,然后关闭AOF,拷贝RDB到相应目录,启动redis之后热修改配置参数redis config set appendonly yes,此时会自动生成一个当前内存数据的AOF文件,然后再次停止redis,打开AOF配置,再次启动数据就正常启动。
RDB 对redis中的数据执行周期性的持久化,每一刻持久化的都是全量数据的一个快照。对redis性能影响较小,基于RDB能够快速异常恢复
AOF 以append-only的模式写入一个日志文件中,在redis重启的时候可以通过回放AOF日志中的写入指令来重新构建整个数据集。(实际上每次写的日志数据会先到linux os cache,然后redis每隔一秒调用操作系统fsync将os cache中的数据写入磁盘)。对redis有一定的性能影响,能够尽量保证数据的完整性。redis通过rewrite机制来保障AOF文件不会太庞大,基于当前内存数据并可以做适当的指令重构。

二、redis集群
replication 一主多从架构,主节点负责写,并且将数据同步到其他salve节点(异步执行),从节点负责读,主要就是用来做读写分离的横向扩容架构。这种架构的master节点数据一定要做持久化,否则,当master宕机重启之后内存数据清空,那么就会将空数据复制到slave,导致所有数据消失。
sentinal哨兵 哨兵是redis集群架构中很重要的一个组件,负责监控redis master和slave进程是否正常工作,当某个redis实例故障时,能够发送消息报警通知给管理员,当master node宕机能够自动转移到slave node上,如果故障转移发生来,会通知client客户端新的master地址。sentinal至少需要3个实例来保证自己的健壮性,并且能够更好地进行quorum投票以达到majority来执行故障转移。 前两种架构方式最大的特点是,每个节点的数据是相同的,无法存取海量的数据。因此哨兵集群的方式使用与数据量不大的情况。
redis cluster redis cluster支撑多master node,每个master node可以挂载多个slave node,如果mastre挂掉会自动将对应的某个slave切换成master。需要注意的是redis cluster架构下slave节点主要是用来做高可用、故障主备切换的,如果一定需要slave能够提供读的能力,修改配置也可以实现(同时也需要修改jedis源码来支持该情况下的读写分离操作)。redis cluster架构下,master就是可以任意扩展的,直接横向扩展master即可提高读写吞吐量。slave节点能够自动迁移(让master节点尽量平均拥有slave节点),对整个架构过载冗余的slave就可以保障系统更高的可用性。
ehcache
tomcat jvm堆内存缓存,主要是抗redis出现大规模灾难。如果redis出现了大规模的宕机,导致nginx大量流量直接涌入数据生产服务,那么最后的tomcat堆内存缓存也可以处理部分请求,避免所有请求都直接流向DB。

缓存数据更新策略

对时效性要求高的缓存数据,当发生变更的时候,直接采取数据库和redis缓存双写的方案,让缓存时效性最高。
对时效性不高的数据,当发生变更之后,采取MQ异步通知的方式,通过数据生产服务来监听MQ消息,然后异步去拉取服务的数据更新tomcat jvm缓存和redis缓存,对于nginx本地缓存过期之后就可以从redis中拉取新的数据并更新到nginx本地。
经典的缓存+数据库读写的模式,cache aside pattern
读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应
更新的时候,先删除缓存,然后再更新数据库 之所以更新的时候只是删除缓存,因为对于一些复杂有逻辑的缓存数据,每次数据变更都更新一次缓存会造成额外的负担,只是删除缓存,让该数据下一次被使用的时候再去执行读的操作来重新缓存,这里采用的是懒加载的策略。举个例子,一个缓存涉及的表的字段,在1分钟内就修改了20次,或者是100次,那么缓存跟新20次,100次;但是这个缓存在1分钟内就被读取了1次,因此每次更新缓存就会有大量的冷数据,对于缓存符合28黄金法则,20%的数据,占用了80%的访问量。
数据库和redis缓存双写不一致的问题

最初级的缓存不一致问题以及解决方案 问题:如果先修改数据库再删除缓存,那么当缓存删除失败来,那么会导致数据库中是最新数据,缓存中依旧是旧数据,造成数据不一致。 解决方案:可以先删除缓存,再修改数据库,如果删除缓存成功但是数据库修改失败,那么数据库中是旧数据,缓存是空不会出现不一致。
比较复杂的数据不一致问题分析 问题:对于数据发生来变更,先删除缓存,然后去修改数据库,此时数据库中的数据还没有修改成功,并发的读请求到来去读缓存发现是空,进而去数据库查询到此时的旧数据放到缓存中,然后之前对数据库数据的修改成功来,就会造成数据不一致 解决方案:将数据库与缓存更新与读取操作进行异步串行化。当更新数据的时候,根据数据的唯一标识,将更新数据操作路由到一个jvm内部的队列中,一个队列对应一个工作线程,线程串行拿到队列中的操作一条一条地执行。当执行队列中的更新数据操作,删除缓存,然后去更新数据库,此时还没有完成更新的时候过来一个读请求,读到了空的缓存那么可以先将缓存更新的请求发送至路由之后的队列中,此时会在队列积压,然后同步等待缓存更新完成,一个队列中多个相同数据缓存更新请求串在一起是没有意义的,因此可以做过滤处理。等待前面的更新数据操作完成数据库操作之后,才会去执行下一个缓存更新的操作,此时会从数据库中读取最新的数据,然后写入缓存中,如果请求还在等待时间范围内,不断轮询发现可以取到缓存中值就可以直接返回(此时可能会有对这个缓存数据的多个请求正在这样处理);如果请求等待事件超过一定时长,那么这一次的请求直接读取数据库中的旧值 对于这种处理方式需要注意一些问题:
读请求长时阻塞:由于读请求进行来非常轻度的异步化,所以对超时的问题需要格外注意,超过超时时间会直接查询DB,处理不好会对DB造成压力,因此需要测试系统高峰期QPS来调整机器数以及对应机器上的队列数最终决定合理的请求等待超时时间
多实例部署的请求路由:可能这个服务会部署多个实例,那么必须保证对应的请求都通过nginx服务器路由到相同的服务实例上
热点数据的路由导师请求的倾斜:因为只有在商品数据更新的时候才会清空缓存,然后才会导致读写并发,所以更新频率不是太高的话,这个问题的影响并不是特别大,但是的确可能某些机器的负载会高一些。

分布式缓存重建并发冲突解决方案
对于缓存生产服务,可能部署在多台机器,当redis和ehcache对应的缓存数据都过期不存在时,此时可能nginx过来的请求和kafka监听的请求同时到达,导致两者最终都去拉取数据并且存入redis中,因此可能产生并发冲突的问题,可以采用redis或者zookeeper类似的分布式锁来解决,让请求的被动缓存重建与监听主动的缓存重建操作避免并发的冲突,当存入缓存的时候通过对比时间字段废弃掉旧的数据,保存最新的数据到缓存。

缓存冷启动以及缓存预热解决方案

当系统第一次启动,大量请求涌入,此时的缓存为空,可能会导致DB崩溃,进而让系统不可用,同样当redis所有缓存数据异常丢失,也会导致该问题。因此,可以提前放入数据到redis避免上述冷启动的问题,当然也不可能是全量数据,可以根据类似于当天的具体访问情况,实时统计出访问频率较高的热数据,这里热数据也比较多,需要多个服务并行的分布式去读写到redis中(所以要基于zk分布式锁)。

通过nginx+lua将访问流量上报至kafka中,storm从kafka中消费数据,实时统计处每个商品的访问次数,访问次数基于LRU(apache commons collections LRUMap)内存数据结构的存储方案,使用LRUMap去存放是因为内存中的性能高,没有外部依赖,每个storm task启动的时候基于zk分布式锁将自己的id写入zk同一个节点中,每个storm task负责完成自己这里的热数据的统计,每隔一段时间就遍历一下这个map,然后维护一个前1000的数据list,然后去更新这个list,最后开启一个后台线程,每隔一段时间比如一分钟都将排名的前1000的热数据list同步到zk中去,存储到这个storm task对应的一个znode中去

部署多个实例的服务,每次启动的时候就会去拿到上述维护的storm task id列表的节点数据,然后根据taskid,一个一个去尝试获取taskid对应的znode的zk分布式锁,如果能够获取到分布式锁,再去获取taskid status的锁进而查询预热状态,如果没有被预热过,那么就将这个taskid对应的热数据list取出来,从而从DB中查询出来写入缓存中,如果taskid分布式锁获取失败,快速抛错进行下一次循环获取下一个taskid的分布式锁即可,此时就是多个服务实例基于zk分布式锁做协调并行的进行缓存的预热。

缓存热点导致系统不可用解决方案

对于瞬间大量的相同数据的请求涌入,可能导致该数据经过hash策略之后对应的应用层nginx被压垮,如果请求继续就会影响至其他的nginx,最终导致所有nginx出现异常整个系统变得不可用。

基于nginx+lua+storm的热点缓存的流量分发策略自动降级来解决上述问题的出现,可以设定访问次数大于后95%平均值n倍的数据为热点,在storm中直接发送http请求到流量分发的nginx上去,使其存入本地缓存,然后storm还会将热点对应的完整缓存数据没发送到所有的应用nginx服务器上去,并直接存放到本地缓存。

对于流量分发nginx,访问对应的数据,如果发现是热点标识就立即做流量分发策略的降级,对同一个数据的访问从hash到一台应用层nginx降级成为分发至所有的应用层nginx。storm需要保存上一次识别出来的热点List,并同当前计算出来的热点list做对比,如果已经不是热点数据,则发送对应的http请求至流量分发nginx中来取消对应数据的热点标识

缓存雪崩解决方案

redis集群彻底崩溃,缓存服务大量对redis的请求等待,占用资源,随后缓存服务大量的请求进入源头服务去查询DB,使DB压力过大崩溃,此时对源头服务的请求也大量等待占用资源,缓存服务大量的资源全部耗费在访问redis和源服务无果,最后使自身无法提供服务,最终会导致整个网站崩溃。

事前的解决方案,搭建一套高可用架构的redis cluster集群,主从架构、一主多从,一旦主节点宕机,从节点自动跟上,并且最好使用双机房部署集群。

事中的解决方案,部署一层ehcache缓存,在redis全部实现情况下能够抗住部分压力;对redis cluster的访问做资源隔离,避免所有资源都等待,对redis cluster的访问失败时的情况去部署对应的熔断策略,部署redis cluster的降级策略;对源服务访问的限流以及资源隔离。

事后的解决方案:redis数据做了备份可以直接恢复,重启redis即可;redis数据彻底失败来或者数据过旧,可以快速缓存预热,然后让redis重新启动。然后由于资源隔离的half-open策略发现redis已经能够正常访问,那么所有的请求将自动恢复

缓存穿透解决方案

对于在多级缓存中都没有对应的数据,并且DB也没有查询到数据,此时大量的请求都会直接到达DB,导致DB承载高并发的问题。解决缓存穿透的问题可以对DB也没有的数据返回一个空标识的数据,进而保存到各级缓存中,因为有对数据修改的异步监听,所以当数据有更新,新的数据会被更新到缓存汇中。

Nginx缓存失效导致redis压力倍增

可以在nginx本地,设置缓存数据的时候随机缓存的有效期,避免同一时刻缓存都失效而大量请求直接进入redis。
转载链接:http://www.sohu.com/a/221395129_827544

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结 的相关文章

  • 分布式系统SDK端重试策略

    分布式系统SDK端重试策略 1 API 的属性 成功率优先 强调成功率 所以重试的时候 sleep 时间较长 按照指数退避的方式sleep latency优先 强调latency 所以重试的时候 sleep的时间较短 2 重试次数 retr
  • 高效实现延迟消息功能

    高效实现延迟消息功能 高效延时消息 包含两个重要的数据结构 1 环形队列 例如可以创建一个包含3600个slot的环形队列 本质是个数组 2 任务集合 环上每一个slot是一个Set 同时 启动一个timer 这个timer每隔1s 在上述
  • Serverless架构模式简介

    Serverless架构模式简介 一 简介 Serverless是一种无服务的架构 类似aws lambda Serverless与跟传统架构不同 由开发者实现的服务端逻辑运行在无状态的计算容器中 它是由事件触发 短暂的 可能只存在于一次请
  • 构建高并发高可用的电商平台架构大纲

    构建高并发高可用的电商平台架构大纲 参考 http blog csdn net yangbutao article details 12242441
  • 飞天平台安全相关

    飞天平台安全相关 1 capability机制 用户的身份认证 authentication 是基于密钥机制的 用户对资源的访问控制是基于权能 capability 机制进行授权 authorization 的 capability是用于访
  • 阿里云飞天系统

    阿里云飞天系统 有幸在阿里云飞天部门工作几年 下面给出基础架构一览
  • Quorum Journal Manager原理

    Quorum Journal Manager原理 在一个典型的HA集群 两个独立的物理节点配置为NameNodes 在任何时间点 其中之一NameNodes是处于Active状态 另一种是在Standby状态 Active NameNode
  • 分布式系统的自主服务

    分布式系统的自主服务 分布式系统作为server运行在机器上 需要很好的自动化运维来操作集群上的复杂的分布式系统 自动化运维要做到基础数据的完整收集 关键信息的准确推送 运维流程的正确 简便执行和确认 进程内部数据按需获取 对象运行状况的长
  • 分布式配置管理系统QConf

    分布式配置管理系统QConf 分布式配置管理系统QConf是360公司开源的系统 详见 https github com Qihoo360 QConf 整体架构图如下 资料 1 https github com Qihoo360 QConf
  • 分布式系统的正确性验证方法

    分布式系统的正确性验证方法 1 Jepsen框架 Jepsen是一个开源的分布式一致性验证框架 可用于验证分布式数据库 分布式消息队列 分布式协调系统 Jepsen探索特定故障模式下分布式系统是否满足一致性 Jepsen框架是一个
  • 一种多级缓存的系统架构

    一种多级缓存的系统架构 下面这个也是比较常用的多级缓存的系统架构图 整体流程如上图所示 1 首先接入Nginx将请求负载均衡到应用Nginx 此处常用的负载均衡算法是轮询或者一致性哈希 轮询可以使服务器的请求更加均衡 而一致性哈希可以提升应
  • Tachyon内存文件系统

    Tachyon内存文件系统 Tachyon是以内存为中心的分布式文件系统 拥有高性能和容错能力 能够为集群框架 如Spark MapReduce 提供可靠的内存级速度的文件共享服务 从软件栈的层次来看 Tachyon是位于现有大数据计算框架
  • Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结

    Nginx Redis Ehcache 大型高并发与高可用的三层缓存架构总结 Nginx 对于中间件nginx常用来做流量的分发 同时nginx本身也有自己的缓存 容量有限 我们可以用来缓存热点数据 让用户的请求直接走缓存并返回 减少流向服
  • 架构师需要了解的Paxos原理、历程及实战

    架构师需要了解的Paxos原理 历程及实战 数据库高可用性难题 数据库的数据一致和持续可用对电子商务和互联网金融的意义不言而喻 而这些业务在使用数据库时 无论 MySQL 还是 Oracle 都会面临一个艰难的取舍 就是如何处理主备库之间的
  • API网关

    API网关 api gateway 即 api 网关 所有的请求首先会经过这个网关 这有点类似于前端控制器模式 也有点类似于 Facade模式 如下图所示 由于所有的请求会先经过这个 api 网关 所以 可以在 这里做 权限控制 安全 负载
  • zookeeper session实现机制

    zookeeper session实现机制 TO DO
  • condition update在分布式系统中设计

    condition update在分布式系统中设计 1 定义 condition update称为条件更新 用于分布式系统中数据一致性 能够保证在并发操作数据时的正确性 2 方式 1 可以通过version来保证condition upda
  • 分布式系统全链路监控方案设计

    分布式系统全链路监控方案设计 在分布式系统中 全链路监控系统 跟踪requestid经过了哪些server 方便定位log的位置 能在一定程度上缓解维护压力 下面给出我们团队的架构设计图
  • DNS在架构设计中的巧用

    DNS在架构设计中的巧用 一 缘起 一个http请求从客户端到服务端 整个执行流程是怎么样的呢 一个典型流程如上 1 客户端通过域名daojia com请求dns server 2 dns server返回域名对应的外网ip 1 2 3 4
  • 聊聊java高并发系统之异步非阻塞

    聊聊java高并发系统之异步非阻塞 几种调用方式 同步阻塞调用 即串行调用 响应时间为所有服务的响应时间总和 半异步 异步Future 线程池 异步Future 使用场景 并发请求多服务 总耗时为最长响应时间 提升总响应时间 但是阻塞主请求

随机推荐

  • STM32—Flash读写详解

    目录 前言 介绍 STM32 FLASH 闪存的编程和擦除 Flash读写的标准库函数 软件设计 FLASH的读取 直接读取某一地址的内容 读取选定位置的选定大小的内容 FLASH的写入 直接使用标准库写入 写入选定位置的选定大小的内容 如
  • mega328p-ADC,PWM,UART驱动

    ADC驱动 函 数 名 Ai Init 函数功能 Ai端口初始化 输入参数 void 输出参数 void 返 回 值 void 参考文档 void 创 件 人 程强刚 创建日期 2016 02 09 修改历史 void Ai Init vo
  • 身份认证之多因素身份认证(MFA)

    我们大多数人都同意密码是不安全的身份验证形式这一观点 更糟糕的是 它完全不智能 但这引发了一个问题 如果密码不是解决安全问题的答案 那什么是 目前 答案可能是多因素身份验证 MFA 多因素身份验证增加了一层关键的防御 MFA使用两个或多个因
  • Filter过滤器完成验证代码的封装

    Filter过滤器完成验证代码的封装 filter是什么 1 使用filter 2 filter配置到项目中 验证用户权限是需要反复使用的代码块 把他封装到filter中 减少代码冗余 filter是什么 init 方法 初始化方法 在创建
  • 主板上还剩啥?CPU整合GPU/北桥/南桥

    泡泡网主板频道2月6日 众所周知 主板上最重要 成本最高的两颗芯片 被称为北桥和南桥 其中北桥负责与处理器对接 主要功能包括 内存控制器 PCI E控制器 集成显卡 前 后端总线等 都是速度较快的模块 而南桥则负责外围周边功能 速度较慢 主
  • c++ 读写excel_每天10分钟,轻松入门python,json、csv等读写

    JSON的全称是 JavaScript Object Notation 意思是JavaScript对象表示法 它是一种基于文本 独立于语言的轻量级数据交换格式 这种数据在弄爬虫的时候 经常会见到这类型的数据 下面展示一个简单的json数据
  • 利用计数器实现任意分频,占空比为60%(任意占空比)电路 [VHDL]

    本次实验为利用计数器实现分频常数为24000 占空比为60 的电路 也可以设置为任意分频 任意占空比的电路 一 设计思路 设计分析 要将原来的占空比为50 大频率的信号重新设为60 占空比 频率较小的周期信号 其中频率的思想就是分频器 利用
  • Northstar软件下载 以及搭建机器人时遇到的坑

    上个学期学机器人的时候 老师让我们用 innostar 创意之星 做出一个机器人来 但我翻遍全网也没找到创意之星的配套软件 我找了三天也没找到 公司官网也没有 给博创的人发邮件也不回 给我整的心态爆炸 为了方便后来的学弟学妹们 现在把我找到
  • Java 优先队列(PriorityQueue)总结

    PriorityQueue 实现的是 Queue 接口 可以使用 Queue 提供的方法 以及自带的方法 1 PriorityQueue概述 Java PriorityQueue 实现了 Queue 接口 不允许放入 null 元素 其通过
  • LVGL学习笔记

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 硬件要求 二 移植 1 准备工作 2 文件准备 3 加入工程 前言 LVGL 轻巧而多功能的图形库 是一个免费的开放源代码图形库 它提供创建具有易于使用的
  • Shopify Liquid 日期

    Shopify Liquid 日期变量 assign start date now date s assign start date year now date Y assign yoy start start date year minu
  • 基于卷积神经网络的车道线检测

    在本博客中 我们将探讨如何使用卷积神经网络 CNN 在Udacity自动驾驶数据集上进行车道线检测 我们将首先简要介绍自动驾驶的相关知识 然后介绍车道线检测的重要性 接下来 我们将构建一个CNN模型 并在Udacity数据集上对其进行训练和
  • 【Mo 人工智能技术博客】K-means:无监督聚类的经典算法

    K means 无监督聚类的经典算法 作者 郑培 无监督学习是一类用于在数据中寻找模式的机器学习技术 无监督学习算法使用的输入数据都是没有标注过的 这意味着数据只给出了输入变量 自变量 X 而没有给出相应的输出变量 因变量 在无监督学习中
  • 常见的并发模型

    介绍 常见解决并发的策略一般有两种 共享数据和消息传递 基于消息传递的实现有 CSP模型 典型的有Go语言中基于Channel的通讯 Actor模型 典型的有Akka中的Actor模型 CSP模型和Actor模型的简单理解 Don t co
  • linux centos中查看应用进程和杀死进程

    1 ps 表示 查看正在运行中的进程 2 ps ef 表示 查看所有进程的详细信息 3 输入 ps ef grep nmon 表示 搜索nmon相关的进程 4 杀死进程 kill 9 进程号
  • 【常用的反监控(winrdlv3)方法winrdlv3】

    常用的反监控 winrdlv3 方法winrdlv3 方案一 使用silent terminal 禁用 sdhelper2 exe和winrdlv3 exe两个程序进程 加密进程终止或者可以只中止sdhelper2则不会加密也不会被管理员发
  • Python手册(Standard Library)--re

    文章目录 re模块 匹配 返回re对象 MatchObject 查找 检索 替换和分割 flags标志 re 模块使 Python 语言拥有全部的正则表达式功能 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象
  • 笔记:JavaScript编译与执行

    1 js的编译与执行 事件循环 单线程语言 JavaScript是单线程语言 即在浏览器中一个页面只有一个线程在执行js代码 进程和线程 假设我们有一家工厂 进程 那么 工厂所拥有的独立资源就相当于系统给我们分配的内存 这是独立的 如果我们
  • Flutter 学习笔记 (二) —— Flutter布局及常用widget总结

    前言 在Flutter里 UI控件就是Widget Widget根据不同的功能可以分为结构元素 如按钮或菜单 文本样式 字体或者颜色方案 布局属性 如填充 对齐 居中 可以这么理解 一个flutter的页面是有一棵树型的Widget组成 包
  • Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结

    Nginx Redis Ehcache 大型高并发与高可用的三层缓存架构总结 Nginx 对于中间件nginx常用来做流量的分发 同时nginx本身也有自己的缓存 容量有限 我们可以用来缓存热点数据 让用户的请求直接走缓存并返回 减少流向服