表格存储Go SDK目前采用“异常”的方式处理错误。本文介绍了表格存储错误处理方式、异常处理信息和出错时的重试策略。
方式
表格存储Go SDK目前采用“异常”的方式处理错误,如果调用接口没有抛出异常,则说明操作成功,否则失败。
批量相关接口,例如BatchGetRow和BatchWriteRow不仅需要判断是否有异常,还需要检查每行的状态是否成功,只有全部成功后才能保证整个接口调用是成功的。
异常
在使用表格存储Go SDK时,异常通常作为方法返回值的第二个参数返回。因此,在获取返回数据前,您需要检查err
参数是否有值。
如果是表格存储服务端报错,err
中会包含requestId
,它是一个用于唯一标识该次请求的UUID。如果您无法解决问题,请记录此requestId
并提交工单。
异常处理的代码示例如下:
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 | 如果设置了
| 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