首页 文章 精选 留言 我的

精选列表

搜索[Agent团队],共10001篇文章
优秀的个人博客,低调大师

浅谈LocalCache | 京东云技术团队

1、什么是LocalCache? 本地缓存是一种将数据存储在应用程序内存中的机制,用于提高数据访问的性能和响应速度。它通过在内存中维护一个键值对的存储结构,允许应用程序快速检索和访问数据,而无需每次都从慢速的数据源(如数据库或网络)获取数据。 2、LocalCache优缺点 1)优点 •快速访问:LocalCache将数据存储在内存中,因此可以快速访问缓存数据,提高应用程序的性能。 •减轻后端负载:通过将经常访问的数据存储在本地缓存中,可以减少对后端数据源的访问次数,降低后端负载,提高系统的整体性能。 •灵活性:LocalCache提供了一些配置选项,如最大容量、过期时间等,可以根据需求进行调整。这使得开发人员能够灵活地控制缓存的行为,以适应不同的业务场景。 2)缺点 •有限的容量:由于LocalCache是基于内存的,因此容量是有限的。如果缓存数据量过大,可能会导致内存消耗过高,影响系统的稳定性。 •单点故障:LocalCache存储在单个应用程序中,如果应用程序崩溃或重启,缓存数据将丢失。这可能会导致缓存冷启动和性能下降。 3、LocalCache应用场景 LocalCache适用于许多不同的使用场景,特别是以下几种情况: 1.**频繁访问的数据:**如果应用程序中有一些频繁被访问的数据,将这些数据存储在LocalCache中可以大大提高访问速度。由于数据存储在内存中,相比于从磁盘或网络中读取数据,从本地缓存中获取数据的速度更快。 2.**减轻后端负载:**通过将经常访问的数据存储在本地缓存中,可以减少对后端数据源(如数据库或API)的访问次数。这样可以降低后端的负载,提高系统的整体性能。 3.**降低网络延迟:**在分布式系统或微服务架构中,不同的服务可能位于不同的节点上,通过网络进行通信。使用本地缓存可以减少对远程服务的调用次数,从而减少网络延迟,提高系统的响应速度。 4.灵活性和可配置性:LocalCache提供了一些配置选项,如最大容量、过期时间等,可以根据需求进行调整。这使得开发人员能够灵活地控制缓存的行为,以适应不同的业务场景。 4、LocalCache实际使用场景 1.**数据库中间件:**数据库中间件是位于应用程序和后端数据库之间的软件层,常见的数据库中间件包括MySQL Proxy、Cobar、MyCat等。这些中间件可以使用LocalCache来缓存查询结果,以减轻后端数据库的负载并提高查询性能。当应用程序发出相同的查询请求时,中间件可以先检查LocalCache中是否有相应的缓存结果,如果有则直接返回缓存结果,否则再向后端数据库发起查询请求。 2.**消息队列:**消息队列是一种用于异步通信的中间件,常见的消息队列系统包括Apache Kafka、RabbitMQ等。在消息队列系统中,LocalCache可以用来缓存消息,以提高消息的处理速度和响应能力。当消费者需要处理消息时,它可以先在LocalCache中查找是否有相应的消息缓存,如果有则直接消费缓存消息,否则再从消息队列中获取消息。 3.**前端应用:**前端应用包括各种Web应用、移动应用和桌面应用,常见的前端框架如React、Angular、Vue.js等。在前端应用中,LocalCache可以用于缓存静态资源(如JavaScript、CSS、图像等)或动态数据,以提高应用的加载速度和用户体验。例如,前端应用可以先检查LocalCache中是否有相应的资源缓存,如果有则直接使用缓存资源,否则再从服务器获取资源并将其缓存到LocalCache中。 4.**服务端应用:**服务端应用包括各种后端服务、微服务和RESTful API等,常见的服务端框架如Spring、Node.js、Ruby on Rails等。LocalCache可以在服务端应用中使用,用于缓存计算结果、数据库查询结果等,以提高性能和减少对外部资源的依赖。例如,当服务端应用需要进行频繁的计算或查询时,它可以先检查LocalCache中是否有相应的缓存结果,如果有则直接返回缓存结果,否则再进行计算或查询,并将结果缓存到LocalCache中。 5.**开源框架:**许多开源框架提供了自己的LocalCache实现,以方便开发人员在应用中使用。这些框架通常提供了丰富的配置选项和高性能的缓存实现,可以根据应用需求进行定制。例如,Guava、Caffeine和Ehcache等是常见的Java开源框架,它们提供了LocalCache的实现,可以用于缓存计算结果、数据库查询结果等。 5、LocalCache在Guava实践 Guava cache 继承了 ConcurrentHashMap 的思路,使用多个 segments 方式的细粒度锁,在保证线程安全的同时,支持高并发场景需求。 1、CacheBuilder 缓存构建器。构建缓存的入口,指定缓存配置参数并初始化本地缓存。采用 Builder 设计模式提供了设置好各种参数的缓存对象。 CacheBuilder<Object,Object> cacheBuilder =CacheBuilder.newBuilder(); 2、LocalCache 数据结构。缓存核心类 LocalCache 数据结构与 ConcurrentHashMap 很相似,由多个 segment 组成,且各 segment 相对独立,互不影响,所以能支持并行操作,每个 segment 由一个 table 和若干队列组成。缓存数据存储在 table 中,其类型为AtomicReferenceArray,具体结构图及代码解释如下。 #Guava中LocalCache声明segments变量 final LocalCache.Segment<K, V>[] segments; #Guava中初始化segments this.segments = this.newSegmentArray(segmentCount); final LocalCache.Segment<K, V>[] newSegmentArray(int ssize) { return new LocalCache.Segment[ssize]; } #获取Segment Segment<K, V> segmentFor(int hash) { return segments[(hash >>> segmentShift) & segmentMask]; } #Guava中Segment声明table变量用于存储数据 volatile AtomicReferenceArray<LocalCache.ReferenceEntry<K, V>> table; V put(K key, int hash, V value, boolean onlyIfAbsent) { #保证线程安全 lock(); #获取数据 AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; int index = hash & (table.length() - 1); ReferenceEntry<K, V> first = table.get(index); for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) { if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { } } } 3、在Guava中,CacheBuilder提供了一系列方法,用于指定缓存的大小、过期策略、并发级别等属性。 1.配置缓存属性:通过一系列方法来配置缓存的属性,例如: •maximumSize(long size):指定缓存的最大容量,当缓存达到最大容量时,根据缓存策略淘汰部分缓存项。 •expireAfterWrite(Duration duration):指定缓存项的写入后过期时间,过期后的缓存项将被自动移除。 •expireAfterAccess(Duration duration):指定缓存项的最后一次访问后过期时间,过期后的缓存项将被自动移除。 •concurrencyLevel(int level):指定并发级别,即同时可以进行缓存操作的线程数。 Cache<Object,Object> cache = cacheBuilder.maximumSize(1000) .expireAfterWrite(Duration.ofMinutes(10)) .concurrencyLevel(4) .build(); 2. 使用缓存:通过Cache对象的方法来进行缓存的读取、写入和移除操作。例如: •get(Object key):根据键获取缓存项的值。 •put(Object key, Object value):向缓存中添加或更新一个缓存项。 •invalidate(Object key):移除指定键的缓存项。 3. 其他功能:Guava的LocalCache还提供了其他功能,如统计信息、监听器、加载器等,用于监控缓存的状态、处理缓存未命中的情况等。 CacheStats stats = cache.stats(); cache.asMap().forEach((key, value)->System.out.println(key +": "+ value)); cache.cleanUp(); 总结来说,Guava的LocalCache使用CacheBuilder构建和配置缓存,通过Cache对象进行缓存的读取、写入和移除操作。开发人员可以根据自己的需求使用相应的方法和功能来定制和管理缓存。 6、后记 设计一个可用的 Cache 绝对不是一个普通的 Map 这么简单,这里小结一下关于 Guava Cache 的知识。 回归LocalCache 的源头,我是希望可以了解 设计一个缓存要考虑什么?,局部性原理 是一个系统性能提升的最直接的方式(编程上,硬件上当然也可以),缓存的出现就是根据 局部性原理 所设计的。 缓存作为存储金字塔的一部分,一定需要考虑以下几个问题: 1.何时加载 在设计何时加载的问题上,Guava Cache 提供了一个 Loader 接口,让用户可以自定义加载过程,在由 Cache 在找不到对象的时候主动调用 Loader 去加载,还通过一个巧妙的方法,既保证了 Loader 的只运行一次,还能保证锁粒度极小,保证并发加载时,安全且高性能。 2. 何时失效 失效处理上,Guava Cache 提供了基于容量、有限时间(读有限时、写有限时)等失效策略,在官方文档上也写明,在基于限时的情况下,并不是使用一个线程去单独清理过期 K-V,而是把这个清理工作,均摊到每次访问中。假如需要定时清理,也可以调用 CleanUp 方法,定时调用就可以了。 3. 如何保持热点数据有效性 在 Cache 容量有限时, LRU 算法是一个通用的解决方案,在源码中,Guava Cache 并不是严格地保证全局 LRU 的,只是针对一个 Segment 实现 LRU 算法。这个前提是 Segment 对用户来说是随机的,所以全局的 LRU 算法和单个 Segment 的算法是基本一致的。 4. 写回策略 在 Guava Cache 里,并没有实现任何的写回策略。原因在于,Guava Cache 是一个本地缓存,直接修改对象的数据,Cache 的数据就已经是最新的了,所以在数据能够写入 DB 后,数据就已经完成一致了。 参考文献:Google Guava Cache 全解析 作者:京东科技 游斌平 来源:京东云开发者社区 转载请注明来源

优秀的个人博客,低调大师

初探webAssembly | 京东物流技术团队

1 WebAssembly是什么? 一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果 W3C WebAssembly Community Group开发的一项网络标准,对于浏览器而言,WebAssembly 提供了一条途径,让各种语言编写的代码以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件等都将可以运行在 Web 中。 WebAssembly 设计之初就决定和 JavaScript 一起协同运行——通过JavaScript 中的 WebAssembly API,可以把 WebAssembly 模块加载到一个 JavaScript 应用中并且在两者之间互相调用。这样可以在同一个应用中使用 WebAssembly 的高性能及 JavaScript 的高灵活性。 2 为什么需要WebAssembly? 众所周知JavaScript是解释型语言,相比于编译型语言需要在运行时转换,所以解释型语言的执行速度要慢于编译型语言。 编译型语言和解释型语言代码执行的具体流程如下: 因为解释型语言每次执行都需要把源码转换一次才能执行,而转换过程非常耗费时间和性能,也就导致在JavaScript背景下,web无法执行一些高性能应用,如图片剪辑、视频剪辑、3D游戏等。 根据MDN的定义,WebAssembly是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C / C ++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两者一起工作。 3 WebAssembly的工作原理 WebAssembly不被解释,而是由开发者提前编译为WebAssembly二进制格式,如下图所示。由于变量类型都是预知的,因此浏览器加载WebAssembly文件时,JavaScript引擎无须监测代码。它可以简单地将这段代码的二进制格式编译为机器码。 如果将每种编程语言都直接编译为机器码的各个版本,那么效率会很低。编译器中称为前端的部分会将所编写的代码编译为一种中间表示(intermediate representation,IR)。创建好IR代码后,编译器的后端部分会接收IR代码,对其进行优化,然后将其转换为所需要的机器码。 如果将每种编程语言都直接编译为机器码的各个版本,那么效率会很低。编译器中称为前端的部分会将所编写的代码编译为一种中间表示(intermediate representation,IR)。创建好IR代码后,编译器的后端部分会接收IR代码,对其进行优化,然后将其转换为所需要的机器码。 由于浏览器可以在若干不同的处理器(比如桌面计算机、智能手机和平板设备)上运行,因此为每个可能的处理器发布一个WebAssembly代码的编译后版本会非常繁复。替代方法即取得IR代码,并通过一个专门的编译器来运行,这个编译器将IR代码转换为一种专用字节码并放入后缀为.wasm的文件中。此时wasm文件中的字节码还不是机器码,它只是支持WebAssembly的浏览器能够理解的一组虚拟指令。当加载到支持WebAssembly的浏览器中时,浏览器会验证这个文件的合法性,然后这些字节码会继续编译为浏览器所运行的设备上的机器码。如下图 WebAssembly被设计为JavaScript的一个组件,不是它的替代品。虽然有些开发者试图只用WebAssembly来创建整个网站,但这不是普遍情况。一般情况JavaScript仍然是更好的选择。 4 WebAssembly模块内部 模块中不同段的含义说明: 编译器负责生成WebAssembly模块的段,并将它们按照适当顺序放置。 所有的段都是可选的,因此可能存在空模块。 如果指定了已知段,那么它们只能出现一次并且要按照特定顺序出现。 自定义段可以放置在已知段之前、之间或之后,用于指定不适用已知段的数据。 5 哪些语言可用来创建WebAssembly模块? 现在WebAssembly的最小可行性版本(Minimum Viable Product,MVP)还没有垃圾回收(garbage collection,GC),他限制了一些语言的使用。GC作为一种后MVP功能正在开发中,实现之前,有几种语言正在试验WebAssembly支持,方式是将自己的VM编译到WebAssembly,或者在某些情况下将自己的垃圾回收器包含进去。 以下语言正在试验或已经完成WebAssembly支持: C和C++ Rust正致力于成为WebAssembly的首选编程语言。 AssemblyScript是一种新编译器,它用来将TypeScript转换为WebAssembly。 TeaVM是一个将Java转译到JavaScript的工具,现在也可以生成WebAssembly了。 Go 1.11为WebAssembly增加了一个试验性项目,其编译后的WebAssembly模块包含一个垃圾回收器。 Pyodide是Python的一个项目,其中包含了Python科学栈的核心包:Numpy、Pandas和matplotlib。 Blazor是微软的实验性项目,用于将C#引入WebAssembly。 更多列表关注github: WebAssembly支持列表 相关案例: TeaVM:它可以将 JVM 字节码翻译成 JavaScript 和 WebAssembly 我们有一段时间后端开始做一些前端开发,但是结果有时并不尽如人意,关键就在于我们的后端开发人员对前端无论是框架还是语法还是规范,都不是非常了解。这是在所难免的,但是因为业务需要又不得不做。 TeaVM就为我们这种情况提供了一种解决方案,我们的后端开发人员依然使用自己熟悉的语言(java)进行开发。功能开发完成后再将_.class或_.jar文件通过TeaVM编译成wasm或JavaScript供浏览器加载调用。 git:https://github.com/konsoletyper/teavm 官网:https://teavm.org/ 6 WebAssembly可以用在哪? 目前大多数浏览器厂商都已经支持WebAssembly,包括Chrome、Edge、Firefox和Safari。移动端Web浏览器也同样支持。Node.js也从版本8开始支持。 WebAssembly不是JavaScript的替代品,而是它的一个补充,有些情况下WebAssembly是更好的选择,有些情况下使用JavaScript会是一个更优的方案。与JavaScript在同一个VM运行可让两种技术相辅相成。 WebAssembly为非JavaScript的开发者提供了一个新的道路,帮助他们在web中使用自己编写的代码。也让不了解C或C++等语言的web开发者可与访问更新、更快的库。个人理解WebAssembly也可用来优化某些库的执行速度。 6.1 一些使用webAssembly的案例 Figma — 基于浏览器的多人实时协作 UI 设计工具:https://www.figma.com/ Google Earth https://earth.google.com/ - 17年开始支持在FireFox打开,主要依赖webAssembly。之前使用Native Client导致只能在chrome中运行 Magnum — 跨平台的 OpenGL 图形引擎https://github.com/mosra/magnum Egret Engine - 一款HTML5游戏引擎https://github.com/egret-labs/egret-core/ Web-DSP — 使用浏览器就能即时制作多媒体影音特效https://github.com/shamadee/web-dsp 7 WebAssembly怎么用? 7.1 得到wasm文件手动引入 var importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; // 输出 42 fetch('simple.wasm') .then(res => res.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(results => { results.instance.exports.exported_func(); }); 7.2 得到编译好的npm包引入执行 // alert(`Hello, ${name}`) const js = import("./node_modules/@jdl/hello-wasm/hello_wasm.js"); js.then(js => { js.greet("WebAssembly"); }); 以下为hello_wasm.js文件编译前源码 // rust extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] extern { pub fn alert(s: &str); } #[wasm_bindgen] pub fn greet(name: &str) { alert(&format!("Hello, {}!", name)); } 本文从为什么需要WebAssembly、WebAssembly的工作原理、哪些语言可用来创建WebAssembly模块、WebAssembly可以用在哪里 以及 怎么使用 几方面简要介绍了webAssembly。如果之前没有了解过webAssembly,可以做一些简要的了解。 参考文献 《WebAssembly 实战》 —- C. 杰勒德·加伦特 编译 Rust 为 WebAssembly - WebAssembly | MDN 作者:京东物流 潘维高 来源:京东云开发者社区 自猿其说Tech

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册