roulette.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Proxy代理池时间轮盘切换
  2. package main
  3. import (
  4. "errors"
  5. "fmt"
  6. "sync"
  7. "sync/atomic"
  8. "time"
  9. )
  10. type (
  11. //IpItem
  12. IpItem struct {
  13. Ip string `json:"ip"`
  14. LifeTime int64 `json:"lifetime"`
  15. Ports []string `json:"ports"`
  16. IpType int `json:"iptype"` //proxy 服务器类型
  17. Raw string //ip:port
  18. Index int
  19. }
  20. //
  21. Roulette struct {
  22. Data []*IpItem
  23. Length int32 //数据长度
  24. Cursor int32
  25. lock *sync.RWMutex
  26. }
  27. )
  28. var (
  29. roulette = NewRoulette()
  30. )
  31. // NewRoulette
  32. func NewRoulette() *Roulette {
  33. r := Roulette{lock: new(sync.RWMutex)}
  34. return &r
  35. }
  36. // Init
  37. func (r *Roulette) Init(data []*IpItem) {
  38. r.lock.Lock()
  39. defer r.lock.Unlock()
  40. r.Data = data
  41. r.Length = int32(len(data))
  42. atomic.StoreInt32(&r.Cursor, 0)
  43. }
  44. func (r *Roulette) findOne() *IpItem {
  45. var pos int = 0
  46. if atomic.CompareAndSwapInt32(&r.Cursor, r.Length-1, 0) {
  47. pos = 0
  48. } else {
  49. pos = int(atomic.AddInt32(&r.Cursor, 1))
  50. }
  51. return r.Data[pos]
  52. }
  53. // 从时间轮中获取一个对象,不要近2分钟要过期的代理
  54. func (r *Roulette) Get() (*IpItem, error) {
  55. for j := 0; j < 10000000; j++ {
  56. for i := 0; i < int(r.Length); i++ {
  57. if ip := r.findOne(); ip.LifeTime >= time.Now().Unix()+2*60 {
  58. return ip, nil
  59. } else {
  60. fmt.Print("O")
  61. }
  62. }
  63. fmt.Print("W")
  64. time.Sleep(20 * time.Second)
  65. }
  66. return nil, errors.New("找不到合适的代理")
  67. }