账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    golang 海量URL访问,如何提升性能
    93
    0
    我有100M的URL,需要访问这些URL,看看哪些能访问。从CSV中读取URL,如果能访问就存入另一个CSV。目前,我将100M的文件拆分成了20个,逐个访问。每次全部读入管道,然后由消费者去处理(测试访问能否成功),处理完的数据再存入管道,主程序从管道中读数据,写入文件,如果监测到没数据了,就结束。目前100万个URL 大约需要2小时。(现在有1亿个)请问如何才能更高效的处理。package mainimport ( "encoding/csv" "fmt" "net/http" "os" "time")func fileWrite(filename string, content string) { f, error := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660) if error != nil { fmt.Println(error.Error()) } defer f.Close() f.WriteString(content)}func consumer(channel_in chan string, channel_out chan string) { for domain := range channel_in { url := "http://" + domain client := http.Client{ Timeout: 1 * time.Second, } res, error := client.Get(url) if error == nil && res.StatusCode == http.StatusOK { channel_out <- domain + "\n" } }}const READ_PATH = "./split/16.csv"const WRITE_PATH = "./canVisit/16.csv"func main() { //读文件 file, _ := os.Open(READ_PATH) defer file.Close() reader := csv.NewReader(file) content, _ := reader.ReadAll() contentLen := len(content) //用来存整个CSV文件的数据 productChannel := make(chan string, contentLen) //消费者会将处理好的数据放入writeChannel writeChannel := make(chan string, contentLen) defer close(productChannel) //将文件内容全部放入管道 for _, row := range content { productChannel <- row[0] } //消费者处理管道中的数据 for i := 0; i < 100; i++ { go consumer(productChannel, writeChannel) } for { select { case item := <-writeChannel: fileWrite(WRITE_PATH, item) case <-time.After(time.Second * 10): goto out } }out: fmt.Println("over!")}
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 傅家二少 普通会员 1楼

      在Go语言中,你可以使用net/http包中的http模块来发送HTTP请求,以获取大量的URL。但是,对于大量URL的访问,这可能会导致性能问题。以下是一些可以提升性能的建议:

      1. 优化请求:可以使用http.Get方法的timeout参数来限制请求的超时时间,以避免请求超时导致的阻塞。

      go http.Get(url, timeouts)

      1. 使用并发请求:如果你有多个并发请求需要处理,可以使用http.ClientConcurrent字段来并发发送请求。

      ```go client := &http.Client{} requests := make([]http.Request, 10) for i := range requests { requests[i] = http.NewRequest("GET", url, nil) }

      for _, request := range requests { client.Do(request) } ```

      1. 使用代理:如果你的URL需要访问的服务器位于其他地方,可以使用代理服务器来将请求转发到远程服务器。

      ```go proxy := &http.ProxyServer{ Address: ":8080", RequestHeaders: http.Header{ "User-Agent": "Go-Proxy", }, }

      client := &http.Client{} requests := make([]http.Request, 10) for i := range requests { requests[i] = http.NewRequest("GET", url, nil) }

      for _, request := range requests { response, err := proxy.Do(request) if err != nil { fmt.Println(err) continue } fmt.Println(response) } ```

      1. 使用缓存:如果你经常访问相同的URL,可以考虑使用缓存来减少HTTP请求的数量。

      go cache := make(map[string]string) cache[url] = "response" http.Get(url)

      1. 使用Goroutine池:如果你需要并发发送多个请求,可以使用Goroutine池来管理请求的执行。

      ```go numConcurrentRequests := 10 concurrentRequests := make(chan *http.Request, numConcurrentRequests) for i := 0; i < numConcurrentRequests; i++ { go sendRequest(concurrentRequests, i) }

      for i := 0; i < numConcurrentRequests; i++ { request := <-concurrentRequests client.Do(request) } ```

      这些只是一些基本的建议,实际的性能优化可能需要根据你的具体需求来定制。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部