错误处理

表格存储Go SDK目前采用“异常”的方式处理错误。本文介绍了表格存储错误处理方式、异常处理信息和出错时的重试策略。

方式

表格存储Go SDK目前采用“异常”的方式处理错误,如果调用接口没有抛出异常,则说明操作成功,否则失败。

说明

批量相关接口,例如BatchGetRowBatchWriteRow不仅需要判断是否有异常,还需要检查每行的状态是否成功,只有全部成功后才能保证整个接口调用是成功的。

异常

在使用表格存储Go SDK时,异常通常作为方法返回值的第二个参数返回。因此,在获取返回数据前,您需要检查err参数是否有值。

如果是表格存储服务端报错,err中会包含requestId,它是一个用于唯一标识该次请求的UUID。如果您无法解决问题,请记录此requestId提交工单或者加入钉钉群36165029092(表格存储技术交流群-3)进行咨询

异常处理的代码示例如下:

client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
listTables, err := client.ListTable()
if err != nil {
    // 异常处理。
    fmt.Println(err.Error())
} else {
    // 无异常。
    for _, table := range listTables.TableNames {
        fmt.Println("TableName: ", table)
    }
}

重试

Go SDK提供了默认重试策略,您也可以根据需要自定义重试逻辑。

默认重试策略

当发生流控类错误或者是读操作相关的服务端内部错误时,Go SDK会进行退避重试,默认的重试最大次数为10次,默认的重试总时长为5秒。您可以通过修改tablestore.TableStoreConfig来设置默认重试的参数。具体参数说明请参见下表。

参数

说明

默认值

RetryTimes

最大的重试次数。

10

MaxRetryTime

重试最大总时长。

5s

DefaultRetryInterval

指数退避重试策略的抖动值,以避免多个故障客户端在同一时间点发起重试请求。

10 ms

MaxRetryInterval

两次重试之间的最大时间间隔。

320 ms

Transport

管理HTTP客户端的底层传输属性,默认为nil。

如果设置了该参数,则HTTPTimeout.ConnectionTimeout、MaxIdleConnections、IdleConnTimeout参数不生效。

nil

HTTPTimeout.ConnectionTimeout

HTTP建立新的网络连接时的超时时长。

15s

HTTPTimeout.RequestTimeout

HTTP客户端发起请求并等待服务器响应的最长时间。

30s

MaxIdleConnections

HTTP host的最大空闲连接数。

2000

IdleConnTimeout

HTTP host空闲连接在连接池中保持打开状态但未被复用的最大时长。

25s

用户自定义重试逻辑

如果您希望在默认重试逻辑的基础上进行一些改造或者是完全自定义重试逻辑,您可以通过设置TableStoreClient的以下参数实现。

参数

说明

默认值

CustomizedRetryFunc

如果设置了CustomizedRetryFunc,则会优先判断CustomizedRetryFunc的方法是否进行重试。

  • 如果未设置CustomizedRetryFunc,即CustomizedRetryFuncnil,则SDK会执行默认重试逻辑。

  • 如果CustomizedRetryFunc的取值不为nil,且判定值为重试,则SDK会根据设置的自定义重试逻辑进行重试。

  • 如果CustomizedRetryFunc的取值不为nil,且判定值为不重试,则需要根据KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc的值做进一步判断。

    • 如果KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc的取值为false,则不进行重试。

    • 如果KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc的取值为true,则继续校验默认重试逻辑判断是否进行重试。

nil

KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc

true

自定义重试逻辑的示例如下:

针对所有错误都进行重试

以下示例用于对所有错误都进行重试。

func alwaysRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
	return true
}
func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
  	client.CustomizedRetryFunc = alwaysRetry
    // do something
}

针对所有错误都不进行重试

以下示例用于对所有错误都不进行重试。

func alwaysNotRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
	return false
}
func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
  	client.CustomizedRetryFunc = alwaysNotRetry
    client.KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc = false
    // do something
}

重试时进行回调

如果需要在SDK进行重试时进行一些预定义的操作,您可以通过设置TableStoreClient的以下参数实现。

参数

说明

默认值

RetryNotify

SDK重试时会触发的回调方法。

nil

以下示例展示了如何针对每一次请求设置一个业务侧的traceID,在发生重试时打印此traceID。

func userRetryNotify(traceId, requestId string, err error, action string, backoffDuration time.Duration) {
    // 用户自定义逻辑,在重试时会触发调用。
    fmt.Println("Retry for traceId: " + traceId + ", timestamp: " + strconv.FormatInt(time.Now().UnixNano(), 10))
}

func alwaysRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
    return true
}

func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
    client.CustomizedRetryFunc = alwaysRetry
    client.RetryNotify = userRetryNotify

    request := &tablestore.DescribeTableRequest{TableName: "tableNotExist"}
    // 设置请求的业务侧traceID。
    request.ExtraRequestInfo.SetTraceID("test_TraceId_" + strconv.FormatInt(time.Now().UnixNano(), 10))
    // do something
    res, err := client.DescribeTable(request)

    if err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Println(res.ResponseInfo.RequestId)
    }
}

返回结果示例如下:

Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752655394000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752683437000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752708603000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752760519000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752814590000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752916539000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753110943000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753454311000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753798531000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097754165411000
OTSObjectNotExist Requested table does not exist. 0006143b-fdd6-5050-10ef-700b045590fc