Skip to content

Commit

Permalink
docs:更新polaris-go中的熔断降级文档 (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
chuntaojun authored Nov 19, 2023
1 parent 15068b0 commit b1cd7c1
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 62 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
197 changes: 197 additions & 0 deletions content/zh-cn/docs/使用指南/go应用开发/sdk/熔断降级.md
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)
62 changes: 0 additions & 62 deletions content/zh-cn/docs/使用指南/go应用开发/sdk/节点熔断.md

This file was deleted.

0 comments on commit b1cd7c1

Please sign in to comment.