云计算模型- 断路器模式 (3)

在 web 应用中,页面是根据外部服务获得的数据计算生成的。如果系统设定较少的缓存策略,大多数页面点击都会调用一次服务。从 web 应用到服务的请求可以设定超时时间(通常是60秒),如果服务在这段时间内未响应,页面的逻辑将认为服务不可用并抛出异常。

然而,如果服务失败并且系统非常繁忙,用户可能需要等60秒才会被提示异常。最终内存,链接,线程等资源可能会用尽,阻止其他用户连接系统,即使它们并不是访问失败的那个服务。

通过添加更多的网络服务器和实现负载均衡来为系统扩容能够延缓资源耗尽的时间,但这并不会解决这个问题因为用户的请求仍会未响应并且最终所以网络服务器的资源终会耗尽。

为访问该服务查询数据的连接包裹一层断路器能够解决该问题,并且能更优雅地解决服务失败。用户的请求仍会失败,但失败将会更迅速并且不会阻塞资源。

The CircuitBreaker class maintains state information about a circuit breaker in an object that implements the ICircuitBreakerStateStore interface shown in the following code.

interface ICircuitBreakerStateStore { CircuitBreakerStateEnum State { get; } Exception LastException { get; } DateTime LastStateChangedDateUtc { get; } void Trip(Exception ex); void Reset(); void HalfOpen(); bool IsClosed { get; } }

The State property indicates the current state of the circuit breaker, and will be either Open, HalfOpen, or Closed as defined by the CircuitBreakerStateEnum enumeration. The IsClosed property should be true if the circuit breaker is closed, but false if it's open or half open. The Trip method switches the state of the circuit breaker to the open state and records the exception that caused the change in state, together with the date and time that the exception occurred. The LastException and the LastStateChangedDateUtc properties return this information. The Reset method closes the circuit breaker, and the HalfOpen method sets the circuit breaker to half open.

The InMemoryCircuitBreakerStateStore class in the example contains an implementation of the ICircuitBreakerStateStore interface. The CircuitBreaker class creates an instance of this class to hold the state of the circuit breaker.

The ExecuteAction method in the CircuitBreaker class wraps an operation, specified as an Action delegate. If the circuit breaker is closed, ExecuteAction invokes the Action delegate. If the operation fails, an exception handler calls TrackException, which sets the circuit breaker state to open. The following code example highlights this flow.

public class CircuitBreaker { private readonly ICircuitBreakerStateStore stateStore = CircuitBreakerStateStoreFactory.GetCircuitBreakerStateStore(); private readonly object halfOpenSyncObject = new object (); ... public bool IsClosed { get { return stateStore.IsClosed; } } public bool IsOpen { get { return !IsClosed; } } public void ExecuteAction(Action action) { ... if (IsOpen) { // The circuit breaker is Open. ... (see code sample below for details) } // The circuit breaker is Closed, execute the action. try { action(); } catch (Exception ex) { // If an exception still occurs here, simply // retrip the breaker immediately. this.TrackException(ex); // Throw the exception so that the caller can tell // the type of exception that was thrown. throw; } } private void TrackException(Exception ex) { // For simplicity in this example, open the circuit breaker on the first exception. // In reality this would be more complex. A certain type of exception, such as one // that indicates a service is offline, might trip the circuit breaker immediately. // Alternatively it might count exceptions locally or across multiple instances and // use this value over time, or the exception/success ratio based on the exception // types, to open the circuit breaker. this.stateStore.Trip(ex); } }

The following example shows the code (omitted from the previous example) that is executed if the circuit breaker isn't closed. It first checks if the circuit breaker has been open for a period longer than the time specified by the local OpenToHalfOpenWaitTime field in the CircuitBreaker class. If this is the case, the ExecuteAction method sets the circuit breaker to half open, then tries to perform the operation specified by the Action delegate.

If the operation is successful, the circuit breaker is reset to the closed state. If the operation fails, it is tripped back to the open state and the time the exception occurred is updated so that the circuit breaker will wait for a further period before trying to perform the operation again.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspxfx.html