http_client.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package client
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "log"
  7. "net/http"
  8. "time"
  9. )
  10. type HttpClient struct {
  11. *http.Client
  12. maxRetries int
  13. retryDelayFunc RetryDelayFunc
  14. }
  15. // NewClient 构造函数,其中 delayFunc 参数是可选的
  16. func NewClient(timeout time.Duration, maxRetries int, delayFunc ...RetryDelayFunc) *HttpClient {
  17. var df RetryDelayFunc
  18. if len(delayFunc) > 0 {
  19. df = delayFunc[0]
  20. } else {
  21. df = defaultRetryDelayFunc
  22. }
  23. return &HttpClient{
  24. Client: &http.Client{Timeout: timeout},
  25. maxRetries: maxRetries,
  26. retryDelayFunc: df,
  27. }
  28. }
  29. func defaultRetryDelayFunc(attempt int) time.Duration {
  30. delay := time.Duration(attempt) * time.Second
  31. if attempt > 0 {
  32. delay *= 2
  33. }
  34. return delay
  35. }
  36. type RetryDelayFunc func(attempt int) time.Duration
  37. // DoWithRetry 发送带有重试机制的HTTP请求,允许用户自定义重试延迟逻辑
  38. func (hc *HttpClient) DoWithRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
  39. attempt := 0
  40. for {
  41. resp, err := hc.Do(req.WithContext(ctx))
  42. if err != nil {
  43. if attempt >= hc.maxRetries {
  44. return nil, fmt.Errorf("请求失败: %w", err)
  45. }
  46. attempt++
  47. delay := hc.retryDelayFunc(attempt)
  48. time.Sleep(delay)
  49. continue
  50. }
  51. return resp, nil
  52. }
  53. }
  54. func (hc *HttpClient) Post(url string, contentType string, buf io.Reader) (resp *http.Response, err error) {
  55. return
  56. }
  57. func (hc *HttpClient) Get(url string) (resp *http.Response, err error) {
  58. req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
  59. if err != nil {
  60. log.Fatalf("创建请求失败: %v", err)
  61. }
  62. resp, err = hc.DoWithRetry(req.Context(), req)
  63. return
  64. }