从0开始实现一个代理池

从0开始实现一个代理池

语言Go,数据库Redis

简单设计

最近因为需要,着手搭建了一个代理池,这里时间关系,我也不科普什么是代理池了,直接切入正题,我们需要实现什么?话不多说看图,整个架构包含了Worker,Getter,DB,API等几大模块。

在这里插入图片描述

经过一顿思考,大概的架构图就是如上所示了,代理池具备的能力如下所示:

1.获取代理和校验代理分离。

2.代理解析,代理解析我们通过proxy_getter实现,当新增代理的时候,我们只需要在其中补齐拉取方法即可。

3.redis数据库,用于缓存拿到的代理的数据,当然因为我们获取的数据会比较频繁,所以此时如果使用MySQL的话压力比较大,所以这里使用redis。

4.获取前进行校验,确保代理IP是可用的。

数据结构

type ProxyGetter struct {
   Id            string `json:"id"`            // 生成的随机ID
   Name          string `json:"name"`          // 代理名称
   Host          string `json:"host"`          // 代理IP与Host
   Deadline      string `json:"deadline"`      // 过期时间
   LastCheckTime string `json:"lastCheckTime"` // 最后一次校验时间
   CheckCount    int64  `json:"checkCount"`    // 校验次数
   Lock          bool   `json:"lock"`          // 是否锁定(有的业务不能与其他业务一起共享IP所以需要独占)
   IsHttps       bool   `json:"isHttps"`       // 是否支持https
}

代理池所提供的数据结构如上图所示,主要包括了唯一Id,代理名称,过期时间,是否锁定等。

具体实现

通过上述设计,代理池架构如下所示,api是获取代理池的入口,提供了get,delete,getAll,clear等接口,用于对代理池的操作。

r.GET("/get", get)
r.GET("/delete", delete)
r.GET("/getAll", getAll)
r.GET("/clear", clear)

common模块主要是proxy getter和工具类的实现,其中proxy_getter主要是用于代理的获取与解析。

这里我提供了一个demo用于开发者进行参考。

func QinGuo() []*ProxyGetter {
   var proxyResult = make([]*ProxyGetter, 0)
   var result map[string]interface{}
   resp, err := http.Get("") // 填写申请的URL,发起Get请求
   if err != nil {
      log.Fatalln("request error!")
      return nil
   }
   if body, err := ioutil.ReadAll(resp.Body); err == nil {
      err = json.Unmarshal(body, &result)
   }
   // 解析结果
   if result["Code"].(float64) == 0 {
      data := result["Data"].([]interface{})
      for i := 0; i < len(data); i++ {
         value := data[i].(map[string]interface{})
         proxy := &ProxyGetter{
            Id:            uuid.New().String(),
            Host:          value["host"].(string),
            Deadline:      value["deadline"].(string),
            Name:          "QinGuo",
            LastCheckTime: time.Now().String(),
            CheckCount:    0,
            Lock:          false,
         }
         proxyResult = append(proxyResult, proxy)
      }
   }
   // 返回获取到的代理
   return proxyResult
}

config存放了代理池的配置,其中包括了Version,Name等基础配置,我们只需要适当的修改即可完成配置,其中最核心的就是Proxy参数,用于配置代理池。

var (
   Version   = 1.0                     // 版本号
   Name      = "proxy pool"            // 名称
   CronCheck = "@every 1m"             // 校验定时
   CronPull  = "@every 1m"             // 拉取定时
   Proxy     = map[string]interface{}{ // 填写解析方法
      "QinGuo": common.QinGuo,
   }
   DBKey         = "proxy_pool"
   DBHost        = "" // Redis的主机地址
   DBPassword    = "" // Redis的密码
   DB            = 0
   ProxyAuth     = "" // 代理权限,当然也可以设置白名单
   HttpsValidUrl = "https://www.qq.com"   // https代理校验的URL
   HttpValidUrl  = "http://httpbin.org"   // http代理校验的URL
)

在这里插入图片描述

最后

通过上述的编写,我们就完成了代理池的开发工作,我们可以通过main中的配置完成运行,main的配置如下所示。

func main() {
   switch *runType {
   case "schedule":
      runSchedule()
   case "server":
      runServer()
   default:
      log.Fatalln("please input current type!")
      return
   }
   log.Printf("proxy start success!\nversion: %0.1f \n name: %s", config.Version, config.Name)
}

运行

./main -type server // 服务端主要提供暴露给使用方调用的接口
./main -type schedule // 开启定时任务,主要负责拉取代理并进行校验

代码仓库:https://github.com/guanjiangtao/proxy_pool大佬们路过给个star吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值