-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
15068b0
commit b1cd7c1
Showing
3 changed files
with
197 additions
and
62 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
--- | ||
title: "熔断降级" | ||
linkTitle: "熔断降级" | ||
weight: 5 | ||
--- | ||
|
||
{{< note >}} | ||
从 polaris-go 1.6.0-beta 版本开始支持 | ||
{{</ note >}} | ||
|
||
## 引入依赖 | ||
|
||
``` | ||
go get github.com/polarismesh/polaris-go@latest | ||
``` | ||
|
||
## 初始化 polaris.yaml | ||
|
||
你需要在项目的根路径下创建一个 polaris.yaml 文件用于初始化 polaris-go SDK。[polaris.yaml配置详细](https://github.com/polarismesh/polaris-go/blob/main/polaris.yaml) | ||
|
||
## SDK实例构建 | ||
|
||
当初始化好 polaris.yaml 文件之后,你可以直接使用在 package **github.com/polarismesh/polaris-go** 下的 **NewCircuitBreakerAPI** 方法进行构造一个 CircuitBreakerAPI SDK 实例 | ||
|
||
```go | ||
import ( | ||
... | ||
"github.com/polarismesh/polaris-go" | ||
) | ||
|
||
func main() { | ||
circuitbreakerAPI, err := polaris.NewCircuitBreakerAPI() | ||
} | ||
``` | ||
|
||
## 熔断整个服务 | ||
|
||
### 配置熔断规则 | ||
|
||
配置服务熔断规则,针对 default 命名空间下所有的服务,对于时延大于 500 毫秒,或者返回码为 500 的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对服务进行熔断。 | ||
|
||
![](../image/circuitbreaker/服务熔断规则.png) | ||
|
||
### 使用SDK进行熔断判断 | ||
|
||
***方法说明*** | ||
|
||
北极星 Go SDK 提供以下熔断相关的方法,所有的方法都在```CircuitBreakAPI```接口中提供。 | ||
|
||
- Check: 检查资源是否可被调用,并对资源获取调用申请。对于半开的资源,如果半开的调用配额申请成功,返回true,否则返回false。 | ||
- Report: 该方法供用户在资源调用完成后,上报调用的结果,包括返回码、时延等信息,供熔断逻辑判断。 | ||
- MakeFunctionDecorator: 创建一个函数调用装饰器```model.DecoratorFunction```,装饰器可以对 Go 的函数接口进行装饰。具体的定义如下 | ||
```go | ||
// @param ctx: 当前调用上下文信息 | ||
// @param args: 方法入参 | ||
// @return interface{}: 用户方法实际执行的返回结果 | ||
// @return *CallAborted: 如果方法调用、服务调用被熔断, 则会返回 CallAborted 结构题指针 | ||
// @return error: 返回用户方法调用的 error 或者内部熔断执行逻辑的内部错误 | ||
type DecoratorFunction func(ctx context.Context, args interface{}) (interface{}, *CallAborted, error) | ||
``` | ||
|
||
***使用示例*** | ||
|
||
```go | ||
// 创建CircuitBreakAPI实例 | ||
circuitbreakerAPI, err := polaris.NewCircuitBreakerAPI() | ||
|
||
dealF := circuitbreakerAPI.MakeFunctionDecorator(func(ctx context.Context, args interface{}) (interface{}, error) { | ||
// 用户业务逻辑函数 | ||
}, &api.RequestContext{ | ||
RequestContext: model.RequestContext{ | ||
Callee: &model.ServiceKey{ | ||
Namespace: "被调服务所在命名空间", | ||
Service: "被调服务名称", | ||
}, | ||
Caller: &model.ServiceKey{ | ||
Namespace: "主调服务所在命名空间", | ||
Service: "主调服务名称", | ||
}, | ||
}, | ||
}) | ||
|
||
ret, abort, err := dealF(context.Background(), endpoint) | ||
``` | ||
|
||
***样例地址*** | ||
|
||
[Github地址](https://github.com/polarismesh/polaris-go/tree/main/examples/circuitbreaker/interface) | ||
|
||
## 熔断单个接口 | ||
|
||
### 配置熔断规则 | ||
|
||
配置接口熔断规则,针对 default 命名空间所有服务的 /echo 接口,对于时延大于500毫秒,或者返回码为 500 的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对接口进行熔断。 | ||
|
||
![](../图片/熔断降级/接口熔断规则.png) | ||
|
||
### 使用SDK进行熔断判断 | ||
|
||
熔断所使用的SDK接口及方法与服务级熔断相同,这里不再重复介绍。 | ||
|
||
***使用示例*** | ||
|
||
```java | ||
circuitbreakerAPI, err := polaris.NewCircuitBreakerAPI() | ||
|
||
dealF := circuitbreakerAPI.MakeFunctionDecorator(func(ctx context.Context, args interface{}) (interface{}, error) { | ||
resp, err := http.Get(fmt.Sprintf("http://%+v/echo", args)) | ||
if resp != nil { | ||
defer resp.Body.Close() | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
data, _ := ioutil.ReadAll(resp.Body) | ||
return string(data), nil | ||
}, &api.RequestContext{ | ||
RequestContext: model.RequestContext{ | ||
Callee: &model.ServiceKey{ | ||
Namespace: "被调服务所在命名空间", | ||
Service: "被调服务名称", | ||
}, | ||
Caller: &model.ServiceKey{ | ||
Namespace: "主调服务所在命名空间", | ||
Service: "主调服务名称", | ||
}, | ||
Method: "接口名称", | ||
}, | ||
}) | ||
|
||
ret, abort, err := dealF(context.Background(), endpoint) | ||
``` | ||
|
||
***样例地址*** | ||
|
||
[Github地址](https://github.com/polarismesh/polaris-go/tree/main/examples/circuitbreaker/interface) | ||
|
||
## 熔断单个实例 | ||
|
||
### 配置熔断规则 | ||
|
||
配置实例熔断规则,针对default命名空间下所有的服务实例,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,每个实例的错误率是单独统计的,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对被调实例(IP:PORT)进行熔断。 | ||
|
||
![](../图片/熔断降级/实例熔断规则.png) | ||
|
||
### 使用SDK进行熔断判断 | ||
|
||
当实例被熔断时,该实例会暂时不接收请求,原本路由到该实例的请求会路由到其他实例。这个过程在服务路由过程中自动完成,用户无需进行额外的熔断状态判断等操作。 | ||
|
||
***执行服务路由*** | ||
|
||
|
||
```go | ||
// model.ResourceStat 中 RetStatus 字段的取值 | ||
// RetSuccess 调用成功 | ||
RetSuccess RetStatus = "success" | ||
// RetFail 调用失败 | ||
RetFail RetStatus = "fail" | ||
// RetTimeout 调用超时 | ||
RetTimeout RetStatus = "timeout" | ||
// RetFlowControl 限流 | ||
RetFlowControl RetStatus = "flow_control" | ||
// RetReject 被熔断 | ||
RetReject RetStatus = "reject" | ||
// RetUnknown | ||
RetUnknown RetStatus = "unknown" | ||
|
||
circuitbreakerAPI, err := polaris.NewCircuitBreakerAPI() | ||
|
||
// 构造 model.InstanceResource 对象 | ||
insRes, _ := model.NewInstanceResource(&model.ServiceKey{ | ||
Namespace: "被调服务所在命名空间", | ||
Service: "被调服务名称", | ||
}, &model.ServiceKey{ | ||
Namespace: "主调服务所在命名空间", | ||
Service: "主调服务名称", | ||
}, "协议信息, 比如 http/grpc/dubbo/tcp 等等", "被调实例的 IP", {被调实例端口信息}) | ||
|
||
// 上报每次的调用结果 | ||
circuitbreakerAPI.Report(&model.ResourceStat{ | ||
Delay: time.Since(start), | ||
RetStatus: model.RetFail, // | ||
RetCode: "响应码, string 类型", | ||
Resource: insRes, | ||
}) | ||
|
||
// 获取一个服务实例进行调用 | ||
getOneRequest := &polaris.GetOneInstanceRequest{} | ||
getOneRequest.Namespace = namespace | ||
getOneRequest.Service = service | ||
getOneRequest.IncludeCircuitBreakInstances = true | ||
oneInstResp, err := svr.consumer.GetOneInstance(getOneRequest) | ||
``` | ||
|
||
***样例地址*** | ||
|
||
[Github地址](https://github.com/polarismesh/polaris-go/tree/main/examples/circuitbreaker/instance) |
This file was deleted.
Oops, something went wrong.