<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Retry | Liao Lile</title>
    <link>https://liaolile.com/tag/retry/</link>
      <atom:link href="https://liaolile.com/tag/retry/index.xml" rel="self" type="application/rss+xml" />
    <description>Retry</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>zh-Hans</language><lastBuildDate>Sat, 24 Apr 2021 12:23:10 +0000</lastBuildDate>
    <image>
      <url>https://liaolile.com/media/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_3.png</url>
      <title>Retry</title>
      <link>https://liaolile.com/tag/retry/</link>
    </image>
    
    <item>
      <title>easy-try一种存储介质可扩展的持久化重试方案</title>
      <link>https://liaolile.com/post/tech/sourcecode/easy-retry-%E4%B8%80%E7%A7%8D%E5%AD%98%E5%82%A8%E4%BB%8B%E8%B4%A8%E5%8F%AF%E6%89%A9%E5%B1%95%E7%9A%84%E6%8C%81%E4%B9%85%E5%8C%96%E9%87%8D%E8%AF%95%E6%96%B9%E6%A1%88/</link>
      <pubDate>Sat, 24 Apr 2021 12:23:10 +0000</pubDate>
      <guid>https://liaolile.com/post/tech/sourcecode/easy-retry-%E4%B8%80%E7%A7%8D%E5%AD%98%E5%82%A8%E4%BB%8B%E8%B4%A8%E5%8F%AF%E6%89%A9%E5%B1%95%E7%9A%84%E6%8C%81%E4%B9%85%E5%8C%96%E9%87%8D%E8%AF%95%E6%96%B9%E6%A1%88/</guid>
      <description>&lt;p&gt;&lt;strong&gt;源码地址&lt;/strong&gt;：&lt;a href=&#34;https://github.com/alibaba/easy-retry&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;alibaba/easy-retry: easy-retry (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;源码语言&lt;/strong&gt;：Java&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;源码出品&lt;/strong&gt;：Alibaba&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;源码关联分析&lt;/strong&gt;： &lt;a href=&#34;https://github.com/houbb/sisyphus&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;houbb/sisyphus: The java retry framework.(支持注解的 java 重试框架) (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;源码分析&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;其目录树结构为：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---easy-retry-common
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---easy-retry-core
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---easy-retry-extensions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   ---easy-retry-mybatis-extension
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   ---easy-retry-spring-extension
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---easy-retry-starters
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   ---easy-retry-memory-starter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   ---easy-retry-mybatis-starter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   ---easy-retry-starter-common
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;目前支持两种模式的重试，包括持久化到mysql依赖mybatis和内存数据版本，分别需要以来easy-retry-mybatis-starter和easy-retry-memoery-starter模块。&lt;/p&gt;
&lt;p&gt;重试的最基本的interface以及model定义在easy-retry-common中，retry逻辑的具体默认实现在easy-retry-core模块中；&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;该重试的模块中定义的核心概念有：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;Retryable&lt;/code&gt;支持重试的注解，支持定义是否重新抛出异常，以及SpelExpression来驱动重试判定&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryInfo&lt;/code&gt; 通过@Retryable注解绑定获取执行的executor和executorMethod信息绑定到RetryInfo上；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryTask&lt;/code&gt; 对于重试任务的定义，重要的领域模型。其在框架中的convert关系：retryInfo-&amp;gt;retryTask-&amp;gt;retryTaskPo&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryConfiguration&lt;/code&gt; 重试的配置，如果没有自定义的则框架默认的重试机制。支持灵活的自定义内容，包含有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取重试任务&lt;/li&gt;
&lt;li&gt;重试信息序列化器获取，默认是 Hessian&lt;/li&gt;
&lt;li&gt;重试机制的定义&lt;/li&gt;
&lt;li&gt;重试执行器，执行驱动业务&lt;/li&gt;
&lt;li&gt;重试最大次数&lt;/li&gt;
&lt;li&gt;重试事件监听&lt;/li&gt;
&lt;li&gt;任务结果序列化器，配合SPEL表达式决策是否需要重试，默认是 Hessian&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Retryer&lt;/code&gt; 重试的基本Call定义，@FunctionalInterface 函数式接口声明&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryContext&lt;/code&gt;，重试的上下文内容，上下文内容来自于RetryConfiguration，目前只有一种实现，即MaxAttemptsPersistenceRetryContext；绑定具体的task和task executor method&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryContainer&lt;/code&gt; 重试的容器承载，目前一种实现，即SimpleRetryContainer。其通过一个生产-消费者设计模式，实现了retryTask的生产和消费，用于对retryTask的管理；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryContext&lt;/code&gt;和&lt;code&gt;RetryContainer&lt;/code&gt;目前都托管在RetryLifeCycle中管理，在启动和关闭时候做相关资源的处理；RetryContainer中是一个优先队列装的是RetryContext，RetryContex中承载了RetryTask，而RetryTask的优先级最终反应到RetryContext上。而任务的优先级通过任务重试的背压机制设置，避免失败的任务频繁的重试；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryFilter&lt;/code&gt;，重试的过滤器，在过滤器中可以针对RetryContext进行相关的拦截统一处理；其中有一个确保线程安全的过滤器；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryInterceptor&lt;/code&gt; 切面的切入，该切入点做了BeforeRetryProcess和OnRetryProcess切入动作，两个process针对正常场景和异常场景定义了相关处理方法，来决策是否需要进行重试；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryProcessor&lt;/code&gt;，拦截面切入的动作定义&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryStrategy&lt;/code&gt;，具体的重试策略，包括等待策略以及结束策略&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryEvent&lt;/code&gt;，重试的事件，包括重试前的重试对象获取前后事件，以及重试中的失败、成功、等待事件等；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryListener&lt;/code&gt;，事件的监听者；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RetryExecutor&lt;/code&gt;，重试的执行器，在上下文中依赖于RetryConfiguration和RetryTask关联，确定task的执行器；当前的executor实现了PersistencRetryExecutor。其处理逻辑是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;RetryContainer从当前优先队列中获取最优先的任务对应的RetryContext上下文信息，送入executor中执行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;executor判断当前任务是否需要立即执行还是继续等待，决定于背压模式下的时间设定。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果可以执行，则更新当前的retryTask状态为handling&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;执行器执行对应的filter逻辑，filter逻辑返回对应的信息，filter链中最后一个处理逻辑为冲RetryContext取出Invocation信息并且invoke对应的method。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依据filter chain的返回结果后者会抛出异常，针对这两个结果进行判定，决策当前的执行是否需要重试，如果需要重试再决策是否已经达到最大重试次数或者进入背压逻辑，返回该次的结果；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依据上述的状态结果，进行事件广播，相关的Retrylisterner即会被调用；&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/22/tZPD2LrR5ezgySf.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;源码借鉴&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;概念定义清楚，从领域建模的角度，区分开来各种概念的含义，面向对象，对象定义清楚，准确定义。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于各个Bean的AutoConfiguration，集中进行管理，且当用户无自定义时候，需要提供默认的注入实现；—这是开发框架和非框架的本质区别；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按模块做成各个模块之间的独立，模块的边界定义清晰；&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    
  </channel>
</rss>
