1.浅析本地缓存技术 - Guava Cache | 京东物流技术团队
2.重试机制!程源java retry,源码spring retry,程源 guava retrying 详解
3.SpringCloud之网关服务(gateway)
浅析本地缓存技术 - Guava Cache | 京东物流技术团队
本地缓存技术,源码特别是程源 Guava Cache,作为 Java 开发中的源码刻录源码重要工具,其在实际项目中的程源应用广受好评。Guava Cache 提供了高效的源码缓存管理机制,大大提升了应用性能。程源本文从应用场景、源码使用方式、程源源码分析以及总结四个方面,源码深入解析 Guava Cache 的程源特性及其在开发过程中的应用。应用场景
本地缓存的源码优势在于数据读写都在同一个进程中进行,避免了网络传输的程源延迟,访问速度得到显著提升。然而,这也意味着它受到 JVM 内存的限制,不适用于数据量特别庞大的场景。因此,Guava Cache 主要适用于以下场景: 参数配置存储:在应用程序中,参数配置通常频繁访问,但改动较少,此时缓存配置可以显著提升性能。使用方式
Guava Cache 的核心类包括 CacheBuilder 和 Cache。CacheBuilder 用于构建缓存,而 Cache 则用于存放缓存数据。引入 Maven 依赖后,你可以按照以下步骤创建和使用缓存:实例化缓存
设置缓存初始化参数,如初始容量、最大缓存数、源码超市图片动漫绘画并发等级、写入后刷新时间等。
使用 get 方法获取数据,若不存在则通过指定的 Callable 方法构造缓存。
实现数据的被动删除与主动删除。
存储原理
Guava Cache 的数据结构基于 ConcurrentHashMap,但其设计更为灵活,能够通过设置自动回收机制限制内存占用。核心类 LocalCache 实现了 ConcurrentMap 接口,其数据结构主要由 Segment 数组、ReferenceEntry 链表和 AtomicReferenceArray 组成。通过 Segment 数组实现并发操作,每个 Segment 拥有独立的锁,确保了高并发下的数据安全。总结
本文对 Guava Cache 的应用场景、使用方式、存储原理进行了深入探讨,帮助开发者理解其在实际开发中的应用。通过阅读本文,你将对常见的 Guava Cache 有一个清晰的认识,并能够在项目中高效地应用它,提升系统性能。重试机制!java retry,spring retry, guava retrying 详解
小明同学与产品经理的斗智斗勇过程,当接口有时候异常想重试,你会怎么办?随着需求的不断提出,怎么去迭代升级,看看这篇文章,源码下载电影爱情校园写得很好!!
一定要看完,哈哈!然后点个赞。
作者:叶止水 juejin.im/post/5b6ac0a0...
java retry 的一步步实现机制。
简单的需求:产品经理:实现一个按条件,查询用户信息的服务。
小明:好的。没问题。
代码谈话:项目经理:这个服务有时候会失败,你看下。
小明:OutService 在是一个 RPC 的外部服务,但是有时候不稳定。
项目经理:如果调用失败了,你可以调用的时候重试几次。你去看下重试相关的东西
重试:重试作用 - 对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法、写操作等(要考虑写是否幂等)都不适合重试。
远程调用超时、网络突然中断可以重试。在微服务治理框架中,通常都有自己的重试与超时配置,比如dubbo可以设置retries=1,timeout=调用失败只重试1次,超过ms调用仍未返回则调用失败。
比如外部 RPC 调用,或者数据入库等操作,如果一次操作失败,emacs插件源码安装方法可以进行多次重试,提高调用成功的可能性。
V1.0 支持重试版本思考 - 小明:我手头还有其他任务,这个也挺简单的。5 分钟时间搞定他。
V1.1 代理模式版本易于维护 - 项目经理:你的代码我看了,功能虽然实现了,但是尽量写的易于维护一点。
小明:好的。(心想,是说要写点注释什么的?)
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
其特征是代理与委托类有同样的接口。
V1.2 动态代理模式方便拓展 - 项目经理:小明啊,这里还有个方法也是同样的问题。你也给加上重试吧。
小明:好的。
小明心想,我在写一个代理,但是转念冷静了下来,如果还有个服务也要重试怎么办呢?
V1.3 动态代理模式增强对话 - 小明看了下,就选择使用 CGLIB。
V2.0 AOP 实现对话 - 项目经理:小明啊,最近我在想一个问题。不同的服务,重试的时候次数应该是不同的。因为服务对稳定性的要求各不相同啊。
小明:好的源码基地杭州西湖旅游。(心想,重试都搞了一周了,今天都周五了。)
下班之前,小明一直在想这个问题。刚好周末,花点时间写个重试小工具吧。
设计思路 - spring
java 注解
注解可在方法上使用,定义需要重试的次数
拦截指定需要重试的方法,解析对应的重试次数,然后进行对应次数的重试。
V3.0 spring-retry 版本对话 - 周一来到公司,项目经理又和小明谈了起来。
项目经理:重试次数是满足了,但是重试其实应该讲究策略。比如调用外部,第一次失败,可以等待 5S 再次调用,如果又失败了,可以等待 S 再调用。。。
小明:了解。
可是今天周一,还有其他很多事情要做。
小明在想,没时间写这个呀。看看网上有没有现成的。
spring-retry - Spring Retry 为 Spring 应用程序提供了声明性重试支持。 它用于Spring批处理、Spring集成、Apache Hadoop(等等)的Spring。
在分布式系统中,为了保证数据分布式事务的强一致性,大家在调用RPC接口或者发送MQ时,针对可能会出现网络抖动请求超时情况采取一下重试操作。 大家用的最多的重试方式就是MQ了,但是如果你的项目中没有引入MQ,那就不方便了。
还有一种方式,是开发者自己编写重试机制,但是大多不够优雅。
注解式使用 - 重试条件:遇到RuntimeException
重试次数:3
重试策略:重试的时候等待 5S, 后面时间依次变为原来的 2 倍数。
熔断机制:全部重试失败,则调用recover() 方法。
三次调用的时间点:
缺陷 - spring-retry 工具虽能优雅实现重试,但是存在两个不友好设计:
一个是重试实体限定为Throwable 子类,说明重试针对的是可捕捉的功能异常为设计前提的,但是我们希望依赖某个数据对象实体作为重试实体, 但 sping-retry框架必须强制转换为Throwable子类。
另一个就是重试根源的断言对象使用的是 doWithRetry 的 Exception 异常实例,不符合正常内部断言的返回设计。
Spring Retry 提倡以注解的方式对方法进行重试,重试逻辑是同步执行的,重试的"失败"针对的是Throwable, 如果你要以返回值的某个状态来判定是否需要重试,可能只能通过自己判断返回值然后显式抛出异常了。
@Recover 注解在使用时无法指定方法,如果一个类中多个重试方法,就会很麻烦。
@Recover 注解介绍 - @Recover 注解用于恢复处理程序的方法调用的注释。一个合适的复苏handler有一个类型为可投掷(或可投掷的子类型)的第一个参数[br/>和返回与@Retryable方法相同的类型的值。
方法式使用 - 注解式只是让我们使用更加便捷,但是如果要更高的灵活性。可以使用各种提供的方法。
spring-retry 结构概览 - 重试策略重试回退策略 - 重试回退策略,指的是每次重试是立即重试还是等待一段时间后重试。
默认情况下是立即重试,如果需要配置等待一段时间后重试则需要指定回退策略BackoffRetryPolicy。
guava-retrying谈话 - 小华:我们系统也要用到重试
项目经理:小明前段时间用了 spring-retry,分享下应该还不错
小明:spring-retry 基本功能都有,但是必须是基于异常来进行控制。如果你要以返回值的某个状态来判定是否需要重试,可能只能通过自己判断返回值然后显式抛出异常了。
小华:我们项目中想根据对象的属性来进行重试。你可以看下 guava-retry,我很久以前用过,感觉还不错。
小明:好的。
guava-retrying - guava retryer工具与spring-retry类似,都是通过定义重试者角色来包装正常逻辑重试,但是Guava retryer有更优的策略定义,在支持重试次数和重试频度控制基础上,能够兼容支持多个异常或者自定义实体对象的重试源定义,让重试功能有更多的灵活性。
Guava Retryer也是线程安全的,入口调用逻辑采用的是java.util.concurrent.Callable 的 call() 方法
代码例子入门案例 - 遇到异常之后,重试 3 次停止
重试策略 - 重试次数:3
重试策略:固定等待 3S
guava-retrying 简介 - RetryerBuilder 是一个 factory 创建者,可以定制设置重试源且可以支持多个重试源,可以配置重试次数或重试超时时间,以及可以配置等待时间间隔,创建重试者 Retryer 实例。
RetryerBuilder 的重试源支持 Exception 异常对象和自定义断言对象,通过retryIfException 和 retryIfResult 设置,同时支持多个且能兼容。
主要接口 - 序号接口描述备注1Attempt一次执行任务2AttemptTimeLimiter单次任务执行时间限制如果单次任务执行超时,则终止执行当前任务3BlockStrategies任务阻塞策略通俗的讲就是当前任务执行完,下次任务还没开始这段时间做什么),默认策略为:BlockStrategies.THREAD_SLEEP_STRATEGY4RetryException重试异常5RetryListener自定义重试监听器可以用于异步记录错误日志6StopStrategy停止重试策略7WaitStrategy等待时长策略(控制时间间隔),返回结果为下次执行时长8Attempt一次执行任务9Attempt一次执行任务
StopStrategy - 提供三种:
设定一个最长允许的执行时间;比如设定最长执行s,无论任务执行次数,只要重试的时候超出了最长时间,则任务终止,并返回重试异常RetryException;
不停止,用于需要一直轮训知道返回期望结果的情况;
设定最大重试次数,如果超出最大重试次数则停止重试,并返回重试异常;
WaitStrategy - 固定等待时长策略;
随机等待时长策略(可以提供一个最小和最大时长,等待时长为其区间随机值)
递增等待时长策略(提供一个初始值和步长,等待时间随重试次数增加而增加)
指数等待时长策略;
Fibonacci 等待时长策略;
异常时长等待策略;
复合时长等待策略;
总结优雅重试共性和原理 - 正常和重试优雅解耦,重试断言条件实例或逻辑异常实例是两者沟通的媒介。
约定重试间隔,差异性重试策略,设置重试超时时间,进一步保证重试有效性以及重试流程稳定性。
都使用了命令设计模式,通过委托重试对象完成相应的逻辑操作,同时内部封装实现重试逻辑。
spring-retry 和 guava-retry 工具都是线程安全的重试,能够支持并发业务场景的重试逻辑正确性。
优雅重试适用场景 - 功能逻辑中存在不稳定依赖场景,需要使用重试获取预期结果或者尝试重新执行逻辑不立即结束。比如远程接口访问,数据加载访问,数据上传校验等等。
对于异常场景存在需要重试场景,同时希望把正常逻辑和重试逻辑解耦。
对于需要基于数据媒介交互,希望通过重试轮询检测执行逻辑场景也可以考虑重试方案。
谈话 - 项目经理:我觉得 guava-retry 挺好的,就是不够方便。小明啊,你给封装个基于注解的吧。
小明:......
更好的实现 - java 重试框架------sisyphus: github.com/houbb/sisyph...
推荐阅读:
太赞了,SpringBoot+Vue前后端分离完整入门教程!
分享一套SpringBoot开发博客系统源码,以及完整开发文档!速度保存!
Github上最值得学习的个Java开源项目,涵盖各种技术栈!
年最新的常问企业面试题大全以及答案
SpringCloud之网关服务(gateway)
SpringCloud的网关服务在整体架构中扮演着关键角色。首先,它作为服务与外部网络之间的屏障,有助于保护内部服务不受恶意攻击,同时提升内部服务之间的通信效率。网关还具备功能强大的权限控制和流量管理能力,如验证用户登录权限和实施限流策略,确保服务资源的高效利用。
搭建网关项目时,必不可少的组件是Eureka Discovery和Zuul路由。首先,你需要在项目入口处添加@EnableZuulProxy注解,这会启用Zuul的代理功能。配置文件的设置也很重要,启动EurekaServer和相关的服务后,通过统一的路径如apigateway/product/和apigateway/order/访问接口,从而对外界隐藏实际服务的API路径。
在网关层面实现权限校验,通常会借助ZuulFilter进行拦截。这里,我们以简单的字符串校验为例,但实际生产环境可能需要与Redis和ACL结合以提高安全性,供有兴趣的读者自行扩展。
流量控制是网关服务的另一个实用功能。通过guava生成令牌,每秒为请求分配访问许可,这样可以有效防止服务过载。你可以使用压力测试工具如JMeter,针对/apigateway/order/api/v1/order/saveforribbon接口进行测试,以验证网关限流的效果。
总的来说,SpringCloud的网关服务提供了强大的服务管理和控制能力,是构建可扩展和高可用系统的重要组成部分。如果你对视频教程和源码感兴趣,可以在评论区留言交流。