什么是程序设计里的 backoff pattern
Posted JerryWangSAP
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是程序设计里的 backoff pattern相关的知识,希望对你有一定的参考价值。
Backoff pattern 是一种程序设计模式,通常用于处理因高负载或故障而导致的请求失败或错误。该模式基于一种简单的策略,即当请求失败时,等待一段时间后重试,等待时间逐渐增加,直到成功或达到最大重试次数为止。
在实际应用中,Backoff pattern 通常会包含以下几个要素:
初始等待时间:在第一次重试之前等待的时间,通常是一个较短的固定时间。
等待时间递增因子:每次重试时等待时间的增加因子,通常是一个固定的倍数或增量。
最大等待时间:达到该等待时间后不再进行重试,防止过度等待或死循环。
最大重试次数:达到该重试次数后停止重试,防止无限重试或死循环。
Backoff pattern 的优点是能够在高负载或故障情况下有效地处理请求失败,并减轻服务器负载。然而,该模式也存在一些缺点,例如可能会导致响应时间变慢,因为每次失败都需要等待一段时间后才会重试,并且需要在客户端上实现复杂的逻辑来处理重试。
一个简单的实现 Backoff pattern 的例子可以是以下的伪代码:
def make_request():
retries = 0
while retries < MAX_RETRIES:
try:
response = send_request()
return response
except Exception as e:
if retries == MAX_RETRIES - 1:
raise e
retries += 1
wait_time = INITIAL_WAIT_TIME * (BACKOFF_FACTOR ** retries)
wait_time = min(wait_time, MAX_WAIT_TIME)
time.sleep(wait_time)
Spartacus 里的 backoff 机制的一个例子:
下面是一个使用 Angular HttpClient 实现 backoff pattern 的 TypeScript 代码示例:
import Injectable from \'@angular/core\';
import HttpClient from \'@angular/common/http\';
import Observable, throwError from \'rxjs\';
import retryWhen, delay, take, mergeMap from \'rxjs/operators\';
@Injectable(
providedIn: \'root\'
)
export class DataService
constructor(private http: HttpClient)
getData(url: string): Observable<any>
return this.http.get(url).pipe(
retryWhen(errors => errors.pipe(
// 每秒重试一次,最多重试 3 次
delay(1000),
take(3),
// 如果是 500 错误,则进行重试
mergeMap(response =>
if (response.status === 500)
return throwError(response);
return response;
)
))
);
在这个示例中,我们定义了一个名为 DataService 的服务,该服务使用 Angular HttpClient 来获取数据。我们使用 retryWhen 操作符来实现 backoff pattern,它将在发生错误时重试 HTTP 请求。
在 retryWhen 中,我们使用 delay 操作符来指定每次重试之间的延迟时间,这里设置为 1000 毫秒。我们还使用 take 操作符来指定最大重试次数,这里设置为 3 次。
在 mergeMap 操作符中,我们检查响应的状态码是否为 500。如果是,我们使用 throwError 操作符将错误抛出,触发 retryWhen 中的重试逻辑。如果响应状态码不是 500,则直接返回响应。
因此,这个示例中的 backoff pattern 实现了在 HTTP 请求失败时进行重试,最多重试 3 次,每次重试之间延迟 1 秒。
菜鸟理解的工厂模式(Factory Pattern)是什么样子的?
直接开始说了,不浪费园友宝贵的时间!
什么是工厂模式?
在学习前,先问一下:“它是什么?”。
工厂模式,它是项目里面常用的设计模式之一。
它是属于创建型模式,简单的理解创建型模式就是将实例化工作交给另外一个对象来完成。
工厂模式(又称静态工厂模式 Static Factory Method),它算是软件设计模式中最简单的模式了。
为了解决什么问题?
工厂模式使代码清晰,降低耦合度,调用者通过 接口/抽象类来获得想要的实例化,而无需关心细节上是如何实现的。
工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。
(说的比较简单,看了多个网站与博客,我个人认为这句话是工厂模式要解决的最根本的问题,如果有兴趣,可以去看一下其它文章。)
什么时候使用?
工厂模式属于创建类模式,在同的条件下创建不同的对象实例时,可以使用工厂方法模式。
简单的对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。(就是复杂的时候才用工厂,简单不需要用,反而增加程序的复杂度。)
实践加深理解:
我请大家去饭店吃饭,有东北菜(我是东北yin),浙江菜,北京菜等等等等,我把你们带进饭店,然后点了东北菜。这个过程,其实就是工厂模式的一种实现。
首先,不管它是什么菜系的饭店,首先它必须是个“饭店”,必须会做菜(简单描述一下),以下是代码实践过程。
一、我们创建一个饭店的接口类,里面只有一个动作,用来规定所有饭店都必须会做菜!!!

/// <summary> /// 饭店接口类 /// </summary> public interface IRestaurants { /// <summary> /// 每个饭店必须会做饭 /// </summary> /// <returns></returns> string Cook(); }
二、接下来创建几个菜系的具体饭店。

/// <summary> /// 北京饭店 /// </summary> class Beijing : IRestaurants { public string Cook() { return "给你北京菜"; } }

/// <summary> /// 东北饭店 /// </summary> class Dongbei : IRestaurants { public string Cook() { return "给你东北菜"; } }

/// <summary> /// 浙江饭店 /// </summary> class Zhejiang : IRestaurants { public string Cook() { return "给你浙江菜"; } }
三、菜馆有了,接下来这个就是简单工厂模式里的重点了。如何让这些饭店能够正确的给我上菜呢?(如果读者说去东北饭店肯定不能给上北京菜,那请您出门右拐,跪哭!!!)
这时就需要有个“工厂”来协助我要告诉什么饭店做菜了(创建哪个饭店的实例)。

/// <summary> /// 饭店工厂类,根据名字创建饭店的实例。 /// </summary> public class RestaurantSimpleFactory { public IRestaurants GiveMe(string name) { switch (name) { case "Dongbei": return new Dongbei(); case "Beijing": return new Beijing(); case "Zhejiang": return new Zhejiang(); default: return new Dongbei(); } } }
四、准备工作完毕,可以上菜了。

public class Program { static void Main(string[] args) { //创建饭店工厂实例 var restaurantSimpleFactory = new RestaurantSimpleFactory(); //使用饭店接口招收实现它的饭店实例 IRestaurants restaurant = restaurantSimpleFactory.GiveMe("Dongbei"); string cookWhat = restaurant.Cook(); Console.WriteLine("饭店:" + cookWhat); Console.ReadLine(); } }
图解:这是根据我个人的理解画的导图,可能与网络上大牛们的不太一样。
Tag:简单工厂中还包含了另一种实现,“工厂方法”,接下来深入学习一下。
如果我的理解有误,想喷就喷没关系,别骂我就好!可能在您的愤怒中会学习到我没有理解的。谢谢观看!
以上是关于什么是程序设计里的 backoff pattern的主要内容,如果未能解决你的问题,请参考以下文章