Sobes.tech
Senior

Файли калон бо миллион URL вуҷуд дорад, чӣ гуна онҳоро ба зудӣ зеркашӣ кардан мумкин аст, бидуни бор кардани системаву банд шудани сервери хориҷӣ? Кодро чӣ гуна ташкил кардан?

sobes.tech AI

Ҷавоб аз AI

Для быстрой и безопасной загрузки миллиона URL без перегрузки системы и риска бана от сервера нужно:

  1. Ограничить количество одновременных запросов — использовать пул воркеров или семафор для контроля параллелизма.
  2. Реализовать rate limiting — ограничить скорость запросов к одному серверу, чтобы не превысить допустимый лимит.
  3. Обрабатывать ошибки и делать повторные попытки с экспоненциальной задержкой.
  4. Использовать асинхронные или конкурентные механизмы Go (goroutines + каналы).

Пример на Go с контролем параллелизма и задержками:

package main

import (
    "bufio"
    "fmt"
    "net/http"
    "os"
    "sync"
    "time"
)

func worker(urls <-chan string, wg *sync.WaitGroup, rateLimiter <-chan time.Time) {
    defer wg.Done()
    client := &http.Client{Timeout: 10 * time.Second}
    for url := range urls {
        <-rateLimiter // ждем разрешения на запрос
        resp, err := client.Get(url)
        if err != nil {
            fmt.Printf("Ошибка при загрузке %s: %v\n", url, err)
            continue
        }
        resp.Body.Close()
        fmt.Printf("Загружено: %s\n", url)
    }
}

func main() {
    file, err := os.Open("urls.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    urls := make(chan string, 100)
    var wg sync.WaitGroup

    // Ограничение скорости: 10 запросов в секунду
    rateLimiter := time.Tick(100 * time.Millisecond)

    // Запускаем 20 воркеров
    for i := 0; i < 20; i++ {
        wg.Add(1)
        go worker(urls, &wg, rateLimiter)
    }

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        urls <- scanner.Text()
    }
    close(urls)
    wg.Wait()
}

В этом примере:

  • 20 параллельных воркеров обрабатывают URL.
  • rateLimiter ограничивает скорость запросов до 10 в секунду.
  • Используется таймаут HTTP клиента.

Такой подход позволяет эффективно загружать много URL, не перегружая систему и не вызывая блокировки со стороны сервера.