熔断降级

引入依赖

go get github.com/polarismesh/polaris-go@latest

初始化 polaris.yaml

你需要在项目的根路径下创建一个 polaris.yaml 文件用于初始化 polaris-go SDK。polaris.yaml配置详细

SDK实例构建

当初始化好 polaris.yaml 文件之后,你可以直接使用在 package github.com/polarismesh/polaris-go 下的 NewCircuitBreakerAPI 方法进行构造一个 CircuitBreakerAPI SDK 实例

import (
    ...
	"github.com/polarismesh/polaris-go"
)

func main() {
    circuitbreakerAPI, err := polaris.NewCircuitBreakerAPI()
}

熔断整个服务

配置熔断规则

配置服务熔断规则,针对 default 命名空间下所有的服务,对于时延大于 500 毫秒,或者返回码为 500 的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对服务进行熔断。

使用SDK进行熔断判断

方法说明

北极星 Go SDK 提供以下熔断相关的方法,所有的方法都在CircuitBreakAPI接口中提供。

  • Check: 检查资源是否可被调用,并对资源获取调用申请。对于半开的资源,如果半开的调用配额申请成功,返回true,否则返回false。
  • Report: 该方法供用户在资源调用完成后,上报调用的结果,包括返回码、时延等信息,供熔断逻辑判断。
  • MakeFunctionDecorator: 创建一个函数调用装饰器model.DecoratorFunction,装饰器可以对 Go 的函数接口进行装饰。具体的定义如下
// @param ctx: 当前调用上下文信息
// @param args: 方法入参
// @return interface{}: 用户方法实际执行的返回结果
// @return *CallAborted: 如果方法调用、服务调用被熔断, 则会返回 CallAborted 结构题指针
// @return error: 返回用户方法调用的 error 或者内部熔断执行逻辑的内部错误
type DecoratorFunction func(ctx context.Context, args interface{}) (interface{}, *CallAborted, error)

使用示例

// 创建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地址

熔断单个接口

配置熔断规则

配置接口熔断规则,针对 default 命名空间所有服务的 /echo 接口,对于时延大于500毫秒,或者返回码为 500 的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对接口进行熔断。

使用SDK进行熔断判断

熔断所使用的SDK接口及方法与服务级熔断相同,这里不再重复介绍。

使用示例

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地址

熔断单个实例

配置熔断规则

配置实例熔断规则,针对default命名空间下所有的服务实例,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,每个实例的错误率是单独统计的,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对被调实例(IP:PORT)进行熔断。

使用SDK进行熔断判断

当实例被熔断时,该实例会暂时不接收请求,原本路由到该实例的请求会路由到其他实例。这个过程在服务路由过程中自动完成,用户无需进行额外的熔断状态判断等操作。

执行服务路由

// 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地址