如何使用断路器? [英] How do I use a circuit breaker?

查看:237
本文介绍了如何使用断路器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找方法,使远程调用服务无法控制,直到连接成功。我也不想简单地设置一个定时器,其中每个 n 秒/分钟执行一个动作,直到成功。经过一系列的研究,看来断路器模式是非常适合的。

I'm looking for ways to make remote calls to services out of my control until a connect is successful. I also don't want to simply set a timer where an action gets executed every n seconds/minutes until successful. After a bunch of research it appears that the circuit breaker pattern is a great fit.

我发现一个实现,它使用了一个看起来很棒的Castle Windsor拦截器。唯一的问题是我不知道如何使用它。从关于该主题的几篇文章中,我能够找到的唯一使用示例是简单地使用断路器来调用一次 ,这似乎不是很有用。从那看来,我需要使用断路器($ code)while(true)循环运行我的动作。

I found an implementation that uses an Castle Windsor interceptor, which looks awesome. The only problem is I don't know how to use it. From the few articles I found regarding the topic the only usage example I was able to find was to simply use the circuit breaker to call an action only once, which doesn't seem very useful. From that it seems I need to simply run my action using the circuit breaker in a while(true) loop.

如何使用Windsor拦截器执行一个调用外部服务的操作,直到成功,而不会砰击我们的服务器?

How do I use the Windsor interceptor to execute an action making a call to an external service until it is successful without slamming our servers?

有人可以填写缺失的作品吗?

Could someone please fill in the missing pieces?

while(true)
{
    try
    {
        service.Subscribe();
        break;
    }
    catch (Exception e)
    {
        Console.WriteLine("Gotcha!");

        Thread.Sleep(TimeSpan.FromSeconds(10));
    }
}

Console.WriteLine("Success!");

public interface IService
{
    void Subscribe();
}

public class Service : IService
{
    private readonly Random _random = new Random();

    public void Subscribe()
    {
        var a = _random.Next(0, 10) % 2421;
        if(_random.Next(0, 10) % 2 != 0)
            throw new AbandonedMutexException();
    }
}

根据这一点,我想我现在明白这个概念如何应用它。

Based on that I think I now understand this concept as well as how to apply it.

推荐答案

如果你有很多线程击中同一个资源,这是一个有趣的想法。这个工作方式是通过汇总来自所有线程的尝试的计数。在实际发生故障之前,不用担心写一个循环来尝试打5次数据,而是让断路器跟踪所有尝试触发资源的尝试。

This is an interesting idea if you have lots of threads hitting the same resource. The way this works is by pooling the count for attempts from all threads. Rather than worrying about writing a loop to try and hit the database 5 times before actually failing, you have the circuit breaker keep track of all attempts to hit the resource.

一个例子,你说5个线程运行这样的循环(伪代码):

In one example, you have say 5 threads running a loop like this (pseudo-code):

int errorCount = 0;
while(errorCount < 10) // 10 tries
{
    if(tryConnect() = false)
      errorCount++;
    else
      break;
}

假设你的错误处理是正确的,所有的,这个循环可以运行5次,共资源共计50次。

Assuming your error handling is correct and all, this loop could be run 5 times, and ping the resource a total of 50 times.

断路器尝试减少尝试到达资源的总次数。每个线程或请求尝试将增加一个错误计数器。一旦达到错误限制,断电器将不会尝试连接到它的资源,以便任何线程上的任何更多的调用,直到超时。在资源准备就绪之前,轮询资源仍然具有相同的效果,但是您可以减少总负载。

The circuit breaker tries to reduce the total number of times it attempts to reach the resource. Each thread, or request attempt, will increment a single error counter. Once the error limit is reached, the circuit breaker will not try to connect to it's resource for any more calls on any threads until the timeout has elapsed. It's still the same effect of polling the resource until it's ready, but you reduce the total load.

static volatile int errorCount = 0;

while(errorCount < 10)
{
   if(tryConnect() = false)
      errorCount++;
   else
       break;
}

使用此拦截器实现,拦截器正在注册为单例。因此,您的资源类的所有实例将首先通过断路器重定向代码,以便对任何方法进行任何调用。 拦截器只是您课程的代理。它基本上覆盖了您的方法,并在调用方法之前先调用拦截器方法。

With this interceptor implementation, the interceptor is being registered as a singleton. So, all instances of your resource class will have code redirected through the circuit breaker first for any call made to any method. The interceptor is just a proxy to your class. It basically overrides your methods and calls the interceptor method first before calling your method.

如果您没有任何电路理论知识,则打开/关闭位可能会令人困惑。
维基:

The Open/Closed bit might be confusing if you don't have any circuit theory knowledge. wiki:


如果电源在其电源正极和负极之间缺少完整路径
,则电路是开路。

An electric circuit is an "open circuit" if it lacks a complete path between the positive and negative terminals of its power source

理论上,当连接断开时,该电路是断开的,当连接可用时,该电路闭合。您的示例的重要部分是:

In theory, this circuit is Open when the connection is down and Closed when the connection is available. The important part of your example is this:

public void Intercept(IInvocation invocation)
    {
        using (TimedLock.Lock(monitor))
        {
            state.ProtectedCodeIsAboutToBeCalled(); /* only throws an exception when state is Open, otherwise, it doesn't do anything. */
        }

        try
        {
            invocation.Proceed(); /* tells the interceptor to call the 'actual' method for the class that's being proxied.*/
        }
        catch (Exception e)
        {
            using (TimedLock.Lock(monitor))
            {
                failures++; /* increments the shared error count */
                state.ActUponException(e); /* only implemented in the ClosedState class, so it changes the state to Open if the error count is at it's threshold. */ 
            }
            throw;
        }

        using (TimedLock.Lock(monitor))
        {
            state.ProtectedCodeHasBeenCalled(); /* only implemented in HalfOpen, if it succeeds the "switch" is thrown in the closed position */
        }
    }

这篇关于如何使用断路器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆