断路器设计模式用于提高应用程序的稳定性,改善响应时间,并防止应用程序不断发出失败的请求。 此库提供了将断路器逻辑引入您的 Swift 应用程序所需的工具。
最新版本的 CircuitBreaker 适用于 5.1
及更高版本的 Swift 二进制文件。 您可以通过以下链接下载此版本的 Swift 二进制文件。
将 CircuitBreaker
添加到应用程序的 Package.swift
文件中的依赖项。 用最新的 CircuitBreaker
release 替换 "x.x.x"
。
.package(url: "https://github.com/Kitura/CircuitBreaker.git", from: "x.x.x")
将 CircuitBreaker
添加到您的目标的依赖项中
.target(name: "example", dependencies: ["CircuitBreaker"]),
在您的应用程序中导入该包
import CircuitBreaker
断路器状态基于超时和用户定义的故障(当您要断路的函数进行异步调用时非常有用)。 要在您的应用程序代码中使用断路器,您需要执行以下操作
(BreakerError, (fallbackArg1, fallbackArg2, ...)) -> Void
的回退函数func myFallback(err: BreakerError, msg: String) {
// The fallback will be called if one of the below occurs:
// 1. The request does not return before the specified timeout
// 2. CircuitBreaker is currently in Open state and set to fail fast.
// 3. There was an error in the user's called context function (networking error, etc.)
Log.verbose("Error: \(err)")
Log.verbose("Message: \(msg)")
}
extension BreakerError {
public static let encodingURLError = BreakerError(reason: "URL could not be created")
public static let networkingError = BreakerError(reason: "There was an error, while sending the request")
public static let jsonDecodingError = BreakerError(reason: "Could not decode result into JSON")
}
Invocation
对象作为其参数。 Invocation
类的一个实例说明func myContextFunction(invocation: Invocation<(String), String>) {
let requestParam = invocation.commandArgs
// Create HTTP request
guard let url = URL(string: "http://myserver.net/path/\(requestParam)") else {
// Something went wrong
invocation.notifyFailure(error: .encodingURLError)
return
}
var req = URLRequest(url: url)
req.httpMethod = "GET"
let session = URLSession.shared
// Perform the request
session.dataTask(with: req) { result, res, err in
guard let result = result else {
// Failed getting a result from the server
invocation.notifyFailure(error: .networkingError)
return
}
// Convert results to a JSON object
guard let json = (try? JSONSerialization.jsonObject(with: result, options: [])) as? [String: Any] else {
invocation.notifyFailure(error: .jsonDecodingError)
return
}
// Process JSON data
invocation.notifySuccess()
}.resume()
}
let breaker = CircuitBreaker(name: "Circuit1", command: myContextFunction, fallback: myFallback)
run()
方法来调用对端点的调用。 您应该传递上下文命令和回退闭包的相应参数。 在此示例中,myContextFunction
采用字符串作为其参数,而 myFallback
采用字符串作为其第二个参数let requestParam: String = "myRequestParams"
breaker.run(commandArgs: requestParam, fallbackArgs: "Something went wrong.")
extension BreakerError {
public static let encodingURLError = BreakerError(reason: "URL could not be created")
public static let networkingError = BreakerError(reason: "There was an error, while sending the request")
public static let jsonDecodingError = BreakerError(reason: "Could not decode result into JSON")
}
func myFallback(err: BreakerError, msg: String) {
// The fallback will be called if one of the below occurs:
// 1. The request does not return before the specified timeout
// 2. CircuitBreaker is currently in Open state and set to fail fast.
// 3. There was an error in the user's called context function (networking error, etc.)
Log.verbose("Error: \(err)")
Log.verbose("Message: \(msg)")
}
func myContextFunction(invocation: Invocation<(String), String>) {
let requestParam = invocation.commandArgs
// Create HTTP request
guard let url = URL(string: "http://mysever.net/path/\(requestParam)") else {
// Something went wrong...
invocation.notifyFailure(error: .encodingURLError)
}
var req = URLRequest(url: url)
req.httpMethod = "GET"
let session = URLSession.shared
// Perform Request
session.dataTask(with: req) { result, res, err in
guard let result = result else {
// Failed getting a result from the server
invocation.notifyFailure(error: .networkingError)
return
}
// Convert results to a JSON object
guard let json = (try? JSONSerialization.jsonObject(with: result, options: [])) as? [String: Any] else {
invocation.notifyFailure(error: .jsonDecodingError)
return
}
// Process JSON data
invocation.notifySuccess()
}.resume()
}
let breaker = CircuitBreaker(name: "Circuit1", command: myContextFunction, fallback: myFallback)
let requestParam: String = "myRequestParams"
breaker.run(commandArgs: requestParam, fallbackArgs: "Something went wrong.")
将为 CircuitBreaker 实例跟踪以下统计信息
下面的示例代码展示了如何记录统计信息的快照以及如何创建符合 Hystrix 的快照。
// Create CircuitBreaker
let breaker = CircuitBreaker(name: "Circuit1", command: myFunction, fallback: myFallback)
// Invoke breaker call
breaker.run(commandArgs: (a: 10, b: 20), fallbackArgs: "Something went wrong.")
// Log statistics snapshot
breaker.logSnapshot()
// Hystrix compliant snapshot
let snapshot = breaker.snapshot
CircuitBreaker 库提供了一个接口,用于观察新的 CircuitBreaker 实例,以便注册和跟踪统计信息更改。 在 CircuitBreaker 实例的初始化过程中,会通知链接的监视器其实例化,从而允许它们开始跟踪实例的统计信息。 CircuitBreaker 实例向监视器公开符合 Hystrix 的统计信息快照,然后可以相应地处理该快照。 有关更多信息,请参见 API 文档。
有关更多信息,请访问我们的 API 参考。
我们喜欢讨论服务器端 Swift 和 Kitura。 加入我们的 Slack 与团队会面!
此 Swift 包已获得 Apache 2.0 许可。 完整的许可证文本可在 LICENSE 中找到。