首页 > 编程知识 正文

JAVA aop,java序列化

时间:2023-05-05 16:44:57 阅读:174801 作者:4593

重试作用:重试有场景限制,不是任何场景都适合重试。 例如,参数检查错误,不适合写入操作等(需要考虑写入是否为幂等)重试。

远程调用超时、网络突然中断可以重试。 微服务治理框架通常有自己的重试和超时配置。 例如,如果retries=1,timeout=500调用失败,dubbo将只重试一次,如果超过500ms调用但未返回,则调用将失败。

例如,外部RPC调用或数据签入等操作、如果一次操作失败,可以进行多次重试,提高调用成功的可能性

优雅的重试机制要具备几点:无入侵:这很容易理解,在不更改当前业务逻辑的情况下,对需要重试的地方可以很容易地配置。 包括重试次数、重试间隔、是否使用异步方式等通用性。 最理想的是,无改动(或小改动)的支持在大多数场景下,可以拿来直接利用的优雅的重试共性和原理。 约定正常和重试优雅的解耦重试间隔,区分重试策略,设置重试超时时间,进一步保证重试的有效性和重试过程的稳定性。 它们都使用命令设计模式,通过委托重试对象完成相应的逻辑操作,同时进行内部封装实现重试逻辑。 Spring-tryer和guava-tryer工具都是线程安全重试,支持并发业务场景重试的逻辑正确性。 优雅的重试应用场景:功能逻辑具有不稳定的依赖场景,需要使用重试来获得预期的结果,或者尝试重新运行逻辑不会立即退出。 例如,远程接口访问、数据加载访问、数据上传验证等。 如果存在异常场景,则需要重试。 我们还希望将常规逻辑与重试逻辑解除耦合。 如果需要基于数据媒体的交互,通过重试轮询检测来执行逻辑场景也可以考虑重试方案。 优雅的重试解决思路:切片方式这个思路比较清晰。 向需要添加重试的方法添加重试的自定义注释,并在片上实现重试逻辑。 主要配置参数根据注释中的选项进行初始化

优点:

真的没有入侵的缺点:

也有无法覆盖无法用切面遮挡的场景的方法。 例如,spring-aop无法割舍私人的方法,而是最终的方法。 直接使用aspecj有点复杂。 使用spring-aop只能关闭由spring容器管理的bean消息总线方法。 这也很容易理解,通过需要重试的方法发送消息,并将业务逻辑作为回调方法传递。 订阅重试消息的用户执行重试的业务逻辑

优点:

重试机制没有限制。 这意味着您可以在任何地方使用EventBus框架,并可以方便地组合框架。

要入侵业务,在重试的业务中,需要积极开始调试重试消息以进行复杂的理解。 (消息总线方案的最大优点和缺点可能是太灵活了,不知道在哪里处理这个消息。 特别是在使用新童鞋来维护此代码时) )无法很好地处理返回结果,并且上下文参数无法处理模板方法的优点。

简单(依赖简单)引入一个类就可以了:实现抽象类,讲商务逻辑的填充就可以了(灵活),这真的灵活了。 想怎么做取决于你。 完全由你控制) )缺点:

强入侵代码肥大化将其单独取出,主要是在某个时候,我会对一两个地方进行重试。 简单地实现就好了,也没有必要使用上述沉重的方式。 另外,我想早点进行代码重试

这个设计还非常简单,基本上可以直接贴上代码,一目了然:

publicabstractclassretrytemplate { privatestaticfinalintdefault _ retry _ time=1; privateintretrytime=default _ retry _ time; private int sleep时间=0; //重试睡眠时间public int getSleepTime () { return sleepTime; ) publicretrytemplatesetsleeptime (int sleep time ) if ) sleeptime0) thrownewillegalargumentexception ) sleeptimeshouldeder } return this; }公共获取时间() { return retryTime; } publicretrytemplatesetretrytime (intretrytime ) if ) retrytime=0) thrownewillegalargumentexception ' retrytimeshout } return this; (} /** *重试的业务执行代码

* 失败时请抛出一个异常 * * todo 确定返回的封装类,根据返回结果的状态来判定是否需要重试 * * @return */ protected abstract Object doBiz() throws Exception; //预留一个doBiz方法由业务方来实现,在其中书写需要重试的业务代码,然后执行即可 public Object execute() throws InterruptedException { for (int i = 0; i < retryTime; i++) { try { return doBiz(); } catch (Exception e) { log.error("业务执行出现异常,e: {}", e); Thread.sleep(sleepTime); } } return null; } public Object submit(ExecutorService executorService) { if (executorService == null) { throw new IllegalArgumentException("please choose executorService!"); } return executorService.submit((Callable) () -> execute()); }}

使用示例:

public void retryDemo() throws InterruptedException { Object ans = new RetryTemplate() { @Override protected Object doBiz() throws Exception { int temp = (int) (Math.random() * 10); System.out.println(temp); if (temp > 3) { throw new Exception("generate value bigger then 3! need retry"); } return temp; } }.setRetryTime(10).setSleepTime(10).execute(); System.out.println(ans);}

转载于:https://www.cnblogs.com/panchanggui/p/11232915.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。