From 4d38cc11c3e3371111b5ff7fd2df7c97e795b281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 1 Jun 2024 18:41:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A9=E5=B1=95=E4=BA=8B=E4=BB=B6=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client.go | 86 +++++++++++++++++++++++++++++++------- define/event.go | 34 +++++++-------- define/response.go | 25 +++++++++-- go.mod | 20 +++------ go.sum | 33 ++++----------- validate/request_config.go | 2 +- 6 files changed, 125 insertions(+), 75 deletions(-) diff --git a/client.go b/client.go index 4088b38..9115d85 100644 --- a/client.go +++ b/client.go @@ -11,6 +11,7 @@ import ( "git.zhangdeman.cn/gateway/httpclient/define" "git.zhangdeman.cn/gateway/httpclient/validate" "github.com/go-resty/resty/v2" + "time" ) // NewHttpClient 获取http client @@ -25,9 +26,13 @@ func NewHttpClient(reqConfig *define.Request) (*HttpClient, error) { } restyClient, restyRequest := NewRestyClient(reqConfig) hc := &HttpClient{ - Client: restyClient, - request: restyRequest, - reqConfig: reqConfig, + Client: restyClient, + request: restyRequest, + reqConfig: reqConfig, + http4xxHandler: make([]define.Http4xxHandler, 0), + http5xxHandler: make([]define.Http5xxHandler, 0), + httpBusinessErrorHandler: make([]define.HttpBusinessErrorHandler, 0), + requestFinishHandler: make([]define.RequestFinishHandler, 0), } return hc, nil } @@ -39,8 +44,49 @@ func NewHttpClient(reqConfig *define.Request) (*HttpClient, error) { // Date : 15:27 2024/5/31 type HttpClient struct { *resty.Client - request *resty.Request - reqConfig *define.Request + request *resty.Request + reqConfig *define.Request + http4xxHandler []define.Http4xxHandler + http5xxHandler []define.Http5xxHandler + httpBusinessErrorHandler []define.HttpBusinessErrorHandler + requestSendErrorHandler []define.RequestSendErrorHandler + requestFinishHandler []define.RequestFinishHandler +} + +// OnResponse4xx 4xx处理逻辑 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:20 2024/6/1 +func (hc *HttpClient) OnResponse4xx(handlerList ...define.Http4xxHandler) { + hc.http4xxHandler = append(hc.http4xxHandler, handlerList...) +} + +// OnResponse5xx 5xx处理逻辑 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:21 2024/6/1 +func (hc *HttpClient) OnResponse5xx(handlerList ...define.Http5xxHandler) { + hc.http5xxHandler = append(hc.http5xxHandler, handlerList...) +} + +// OnResponseBusinessError 业务错误出路逻辑 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:22 2024/6/1 +func (hc *HttpClient) OnResponseBusinessError(handlerList ...define.HttpBusinessErrorHandler) { + hc.httpBusinessErrorHandler = append(hc.httpBusinessErrorHandler, handlerList...) +} + +// OnRequestFinish 请求完成时间 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:36 2024/6/1 +func (hc *HttpClient) OnRequestFinish(handlerList ...define.RequestFinishHandler) { + hc.requestFinishHandler = append(hc.requestFinishHandler, handlerList...) } // getRequestValidateMiddleware 请求验证的Middleware @@ -95,7 +141,23 @@ func (hc *HttpClient) Request() *define.Response { err error ) - response := &define.Response{ + for i := 0; i < hc.reqConfig.RetryRule.RetryCount+1; i++ { + response := hc.newResponse(i+1, hc.reqConfig.RetryRule.RetryCount+1) + if response.RestyResponse, err = hc.request.Send(); nil != err { + time.Sleep(time.Duration(hc.reqConfig.RetryRule.RetryTimeInterval) * time.Millisecond) + } + } + + return nil +} + +// newResponse 默认返回数据 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:44 2024/6/1 +func (hc *HttpClient) newResponse(seq int, requestCount int) *define.Response { + return &define.Response{ Header: map[string]string{}, Cookie: map[string]string{}, Body: map[string]any{}, @@ -105,19 +167,13 @@ func (hc *HttpClient) Request() *define.Response { HttpCode: 0, HttpCodeStatus: "", ResponseDataRule: nil, - Seq: 0, + Seq: seq, RequestStartTime: 0, FinishRequestTime: 0, UsedTime: 0, RestyResponse: nil, IsSuccess: false, - RequestCount: 0, - FailInfoList: make([]any, 0), + RequestCount: requestCount, + FailInfo: nil, } - for i := 0; i < hc.reqConfig.RetryRule.RetryCount+1; i++ { - if response.RestyResponse, err = hc.request.Send(); nil != err { - } - } - - return nil } diff --git a/define/event.go b/define/event.go index fb2a30c..c77f51e 100644 --- a/define/event.go +++ b/define/event.go @@ -7,20 +7,6 @@ // Date : 2024-05-31 14:51 package define -// BeforeRequestHandler 请求开始之前的handler -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 14:51 2024/5/31 -type BeforeRequestHandler func(req *Request) - -// AfterResponse 请求完成之后的处理handler -// -// Author : zhangdeman001@ke.com<张德满> -// -// Date : 14:53 2024/5/31 -type AfterResponse func(req *Request, rep *Response) - // Http4xxHandler 4xx handler // // Author : go_developer@163.com<白茶清欢> @@ -35,9 +21,23 @@ type Http4xxHandler func(req *Request, rep *Response) // Date : 14:55 2024/5/31 type Http5xxHandler func(req *Request, rep *Response) -// PanicHandler panic的处理 +// HttpBusinessErrorHandler 接口请求业务错误 // // Author : go_developer@163.com<白茶清欢> // -// Date : 14:56 2024/5/31 -type PanicHandler func(req *Request, rep *Response) +// Date : 18:04 2024/6/1 +type HttpBusinessErrorHandler func(req *Request, rep *Response) + +// RequestSendErrorHandler 请求发送失败的处理逻辑 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:23 2024/6/1 +type RequestSendErrorHandler func(req *Request) + +// RequestFinishHandler 请求最终完成事件, 不区分成功 OR 失败 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:34 2024/6/1 +type RequestFinishHandler func(req *Request, rep *Response) diff --git a/define/response.go b/define/response.go index ee26e25..f8ca2da 100644 --- a/define/response.go +++ b/define/response.go @@ -7,7 +7,9 @@ // Date : 2024-05-31 12:34 package define -import "github.com/go-resty/resty/v2" +import ( + "github.com/go-resty/resty/v2" +) // Response 响应的数据结构定义 // @@ -30,6 +32,23 @@ type Response struct { UsedTime int64 `json:"used_time"` // 请求耗时 : ms RestyResponse *resty.Response `json:"-"` // 请求返回 IsSuccess bool `json:"is_success"` // 是否请求成功 - RequestCount int64 `json:"request_count"` // 请求次数 - FailInfoList []any `json:"fail_info_list"` // 请求失败信息记录 + RequestCount int `json:"request_count"` // 请求次数 + FailInfo *ResponseFileInfo `json:"fail_info"` // 请求失败信息记录 } + +// ResponseFileInfo 失败信息 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:48 2024/6/1 +type ResponseFileInfo struct { + Type string `json:"type"` // 失败类型 + Message string `json:"message"` // 失败信息 +} + +const ( + RequestFailTypeSend = "SEND_REQUEST_FAIL" // 发送请求即失败, 问题出现在客户端 + RequestFailTypeClientError = "CLIENT_REQUEST_ERROR" // 请求失败, 原因出在客户端, 对应http code 4xx + RequestFailTypeServerError = "SERVER_DEAL_ERROR" // 服务端处理失败, 对应 http code 5xx + RequestFailTypeBusinessError = "SERVICE_BUSINESS_ERROR" // 返回状态码为200, 但是业务状态码非成功 +) diff --git a/go.mod b/go.mod index f90006f..a64b961 100644 --- a/go.mod +++ b/go.mod @@ -2,28 +2,20 @@ module git.zhangdeman.cn/gateway/httpclient go 1.22.3 -require github.com/go-resty/resty/v2 v2.13.1 +require ( + git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 + github.com/go-resty/resty/v2 v2.13.1 + github.com/tidwall/gjson v1.17.1 +) require ( - git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14 // indirect git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec // indirect - git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect - git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect - git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 // indirect git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 // indirect - git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306 // indirect github.com/BurntSushi/toml v1.4.0 // indirect - github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mozillazg/go-pinyin v0.20.0 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/tidwall/gjson v1.17.1 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.25.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f2e2840..37a04be 100644 --- a/go.sum +++ b/go.sum @@ -1,34 +1,21 @@ -git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14 h1:++ib8C4aR0UnQ+pmPdmRzJ7UlkmMrNyZEtz5crhmjHE= -git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14/go.mod h1:uVhSl2W/YTCKC50pCZ5AJE5VJBgqyimCiLmsOptqf8k= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec h1:ENemx9RGAU9nqpPYC4S6C/Dnw9gwcx96+sTISG/6rsY= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= -git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0= -git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U= -git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y= -git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw= git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4= git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI= -git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306 h1:Iy36ouA7TecVwBY1QTJfWIYNU2d39+APEfOhBC4gvic= -git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306/go.mod h1:7vFN7QrHLLI/iN7ZrJSU0bw/7TyaYjVQ4+clYuIoRrY= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= -github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ= -github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -36,13 +23,7 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= @@ -82,12 +63,14 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/validate/request_config.go b/validate/request_config.go index 54c5f68..7b8e608 100644 --- a/validate/request_config.go +++ b/validate/request_config.go @@ -41,7 +41,7 @@ func (rc *requestConfig) initDefaultConfig(reqConfig *define.Request) { if nil == reqConfig.RetryRule { reqConfig.RetryRule = &define.RequestRetryRule{ RetryCount: 0, - RetryTimeInterval: 0, + RetryTimeInterval: 5, RetryHttpCodeList: make([]int64, 0), RetryBusinessCodeList: make([]string, 0), }