resty_v2 -> resty_v3

This commit is contained in:
2025-05-07 21:42:48 +08:00
parent 6dcd072570
commit ba47891d3c
11 changed files with 46 additions and 79 deletions

View File

@ -0,0 +1,13 @@
// Package abstract ...
//
// Description : abstract ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-05-07 21:13
package abstract
// RateLimiter v2 流控口约束, v3移除了, 人工补齐
type RateLimiter interface {
Allow() bool
}

View File

@ -20,7 +20,7 @@ import (
"git.zhangdeman.cn/zhangdeman/network/httpclient/log"
"git.zhangdeman.cn/zhangdeman/network/httpclient/validate"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/go-resty/resty/v2"
"resty.dev/v3"
)
// NewHttpClient 获取http client
@ -175,28 +175,6 @@ func (hc *HttpClient) OnRequestFinish(handlerList ...define.RequestFinishHandler
hc.requestFinishHandler = append(hc.requestFinishHandler, handlerList...)
}
// getRequestValidateMiddleware 请求验证的Middleware
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:40 2024/5/31
func (hc *HttpClient) getRequestValidateMiddleware() resty.RequestMiddleware {
return func(client *resty.Client, request *resty.Request) error {
return nil
}
}
// getResponseValidateMiddleware 获取响应数据验证的middleware
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:42 2024/5/31
func (hc *HttpClient) getResponseValidateMiddleware() resty.ResponseMiddleware {
return func(client *resty.Client, response *resty.Response) error {
return nil
}
}
// SetRestyClient 设置client
//
// Author : go_developer@163.com<白茶清欢>
@ -341,8 +319,6 @@ func (hc *HttpClient) Request() *define.Response {
//
// Date : 18:47 2024/10/9
func (hc *HttpClient) requestBackendApi() *define.Response {
hc.Client.OnBeforeRequest(hc.getRequestValidateMiddleware()) // 请求参数验证中间件必注册
hc.Client.OnAfterResponse(hc.getResponseValidateMiddleware()) // 响应验证中间件必注册
var (
err error
)
@ -363,12 +339,20 @@ func (hc *HttpClient) requestBackendApi() *define.Response {
response = hc.newResponse()
response.Seq = i
response.RequestCount = i + 1
if nil != hc.reqOption.RateLimiter {
if !hc.reqOption.RateLimiter.Allow() {
response.FailInfo = &define.ResponseFailInfo{
Type: define.RequestFailTypeRateLimit,
Message: "rate limit exceeded",
}
// 命中限流, 忽略重试
log.RecordDebug("请求命中限流, 忽略重试策略, 不进行重试", nil, hc.reqCfg)
break
}
}
if response.RestyResponse, err = hc.request.Send(); nil != err {
errType := define.RequestFailTypeSend
if err.Error() == resty.ErrRateLimitExceeded.Error() {
// 命中限流
errType = define.RequestFailTypeRateLimit
} else if netErr, ok := err.(net.Error); ok {
if netErr, ok := err.(net.Error); ok {
if netErr.Timeout() {
// 请求超时
errType = define.RequestFailTypeTimeoutError
@ -385,11 +369,6 @@ func (hc *HttpClient) requestBackendApi() *define.Response {
"err_type": errType,
"err_msg": err.Error(),
}, hc.reqCfg)
if errType == define.RequestFailTypeRateLimit {
// 命中限流就不重试了
log.RecordDebug("请求命中限流, 忽略重试策略, 不进行重试", nil, hc.reqCfg)
break
}
if errType == define.RequestFailTypeTimeoutError && !hc.reqOption.ResponseParser.NeedRetry(hc.reqCfg, response) {
// 未配置超时重试

View File

@ -9,7 +9,6 @@ package define
import (
"context"
"github.com/go-resty/resty/v2"
"go.uber.org/zap"
)
@ -39,7 +38,6 @@ type Request struct {
ReadTimeout int64 `json:"read_timeout"` // 读取超时时间
RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则
Logger *zap.Logger `json:"-"` // 日志记录器
RateLimiter resty.RateLimiter `json:"-"` // 流控实例
}
// RequestRetryRule 重试规则

View File

@ -8,7 +8,7 @@
package define
import (
"github.com/go-resty/resty/v2"
"resty.dev/v3"
)
// Response 响应的数据结构定义

View File

@ -87,7 +87,7 @@ func (r *Response) fillResponseBody(reqCfg *define.Request, response *define.Res
jsonByte []byte
)
if err = parser.Unmarshal(response.RestyResponse.Body(), &res); nil != err {
if err = parser.Unmarshal(response.RestyResponse.Bytes(), &res); nil != err {
return errors.New("response parse body error :" + err.Error())
}
if jsonByte, err = parser.MarshalForByte(res); nil != err {

View File

@ -39,6 +39,7 @@ type RequestConfigGroupItem struct {
FailBehavior *RequestConfigGroupItemFailBehavior `json:"fail_behavior"` // 失败的行为, 不配置, 默认失败break
FinalFailureAllow bool `json:"final_failure_allow"` // 已经确定当前请求是最终失败了,当前请求是否允许执行
CacheInstance abstract.ICache `json:"-"` // 数据缓存实例
RateLimiter abstract.RateLimiter `json:"-"` // 流控实例
ResponseParser abstract.IResponse `json:"-"` // 响应数据解析
Condition any `json:"condition"` // TODO: 请求条件, 特定条件下不执行当前请求
}

View File

@ -149,6 +149,7 @@ func (c *client) doRequest(apiList []*RequestConfigGroupItem) bool {
apiCfg.RequestCfg.Query = param[strings.ToLower(consts.RequestDataLocationQuery.String())] // query
if httpClient, err = httpclient.NewHttpClient(apiCfg.RequestCfg, &httpclient.RequestOption{
CacheInstance: apiCfg.CacheInstance,
RateLimiter: apiCfg.RateLimiter,
ResponseParser: apiCfg.ResponseParser,
}); nil != err {
// 此处获取客户端实例即发生异常, 忽略一切配置, 直接作为全局失败, 后续也不请求了

View File

@ -13,6 +13,7 @@ import (
// RequestOption 请求一些选项
type RequestOption struct {
CacheInstance abstract.ICache `json:"-"` // 数据结果缓存实例
ResponseParser abstract.IResponse `json:"-"` // 返回结果解析, 不配置使用内置实现
CacheInstance abstract.ICache `json:"-"` // 数据结果缓存实例
RateLimiter abstract.RateLimiter `json:"-"` // 流控实例
ResponseParser abstract.IResponse `json:"-"` // 返回结果解析, 不配置使用内置实现
}

View File

@ -8,15 +8,14 @@
package httpclient
import (
"encoding/json"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/network/httpclient/define"
"git.zhangdeman.cn/zhangdeman/serialize"
"git.zhangdeman.cn/zhangdeman/wrapper"
"github.com/go-resty/resty/v2"
"github.com/tidwall/gjson"
"net/http"
"net/textproto"
"resty.dev/v3"
"strings"
)
@ -31,15 +30,16 @@ func NewRestyClient(reqConfig *define.Request) (*resty.Client, *resty.Request) {
if nil == reqConfig {
return client, request
}
if nil != reqConfig.RateLimiter {
/*if nil != reqConfig.RateLimiter {
// 设置流控实例
client.SetRateLimiter(reqConfig.RateLimiter)
}
}*/
formatHeader(reqConfig)
client.SetAllowGetMethodPayload(true) // 配置 GET 请求允许带 Body
client.SetJSONMarshaler(json.Marshal) // 序列化方法
client.SetJSONEscapeHTML(true) // 处理html实体字符
client.SetJSONUnmarshaler(serialize.JSON.UnmarshalWithNumber) // 序列化方法
client.SetAllowMethodGetPayload(true) // 配置 GET 请求允许带 Body
client.SetAllowMethodDeletePayload(true) // 配置 DELETE 请求允许带 Body
client.SetJSONEscapeHTML(true) // 处理html实体字符
/*client.SetJSONMarshaler(json.Marshal) // 序列化方法
client.SetJSONUnmarshaler(serialize.JSON.UnmarshalWithNumber) // 反序列化方法*/
request.SetPathParams(reqConfig.PathParam) // 设置path中的参数
query := map[string]string{}