Что вы делаете, когда ищете новую работу? Итак, вы собираетесь связаться с HR или выполнить поиск на таких сайтах, как LinkedIn, Glassdoor, StackOverflow и т. Д.

Попробуем другой подход :) Вы слышали о заголовке «X-Recruiting»? Например, если вы посмотрите на заголовки ответов с PayPal.com, вы увидите этот «странный» заголовок.

Интересно, сколько компаний используют этот умный способ поиска подходящих кандидатов?

Мы постараемся ответить на этот вопрос, используя GO и инстанс AWS Free-tier. Вы можете запустить приложение на своем компьютере, если у вас стабильное и хорошее интернет-соединение. Лично для меня это не сработало, потому что маршрутизатор завис через час и его нужно было перезапустить (слишком много запросов UDP).

Требования и ограничения:

  1. Сканирование должно производиться с помощью воркеров (у нас огромный список доменов для сканирования)
  2. Следует использовать случайные DNS-серверы (в противном случае мы будем заблокированы DNS-сервером, потому что мы будем выполнять так много DNS-запросов)
  3. Использование памяти. Мы хотим, чтобы наше приложение использовало небольшой объем памяти, чтобы иметь возможность использовать экземпляр уровня Free, который имеет только 1 ГБ ОЗУ)

Во-первых, я скачал наборы данных доменов из нескольких источников:

wget https://www.domcop.com/files/top/top10milliondomains.csv.zip
unzip unzip top10milliondomains.csv.zip
wget http://downloads.majestic.com/majestic_million.csv
wget http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip
unzip top-1m.csv.zip

Затем мне нужно очистить, объединить, отфильтровать и сохранить домены uniq в отдельный файл, который будет использоваться для сканирования.

awk -F "\"*,\"*" '{print $2}' top-1m.csv > umbrella-1m-domains.txt
awk -F "\"*,\"*" 'NR>1 {print $3}' majestic_million.csv > majestic-1m-domains.txt
awk -F "\"*,\"*" 'NR>1 {print $2}' top10milliondomains.csv > domcop-10m-domains.txt
cat domcop-10m-domains.txt majestic-1m-domains.txt umbrella-1m-domains.txt | sort | uniq -u > uniq-domains.txt

Во-вторых, мне нужно подготовить список DNS-серверов, который будет использоваться для поиска IP-адресов домена.

wget https://public-dns.info/nameservers.csv
awk -F "\"*,\"*" 'NR>1, NF > 0 {print $1}' nameservers.csv > dns-servers.txt

Наконец, у меня есть два файла, которые будут использоваться приложением:

dns-servers.txt
uniq-domains.txt

Насчет кода.

Поиск DNS реализован с помощью популярного пакета http://github.com/miekg/dns. Определен некоторый интерфейс, позволяющий при необходимости изменять реализацию IP-поиска. Resolver загружает содержимое файла в память, а затем использует случайные серверы для каждого поиска. Метод Resolve возвращает список возвращенных IP-адресов, если они найдены.

Приложение реализовано с использованием версии GO модели "Производитель-Потребитель" с каналами. Worker - наш потребитель. Он получил jobs (домены) для сканирования из JobQueue канала и закрывается, когда канал закрывается. (Производитель отвечает за закрытие канала, когда не осталось доменов для сканирования).

Поскольку большая часть нашей работы - это операции ввода-вывода, мы можем создать тысячи подпрограмм (рабочих) и извлечь из этого выгоду даже на машине с 1 процессором.

Мы также используем WaitGroup, чтобы дождаться, пока все рабочие закончат работу.

Мы также используем буферизованный канал при чтении доменов из файла. Это позволяет приложению использовать небольшой объем памяти. Мы могли бы просто загрузить весь файл в память (и на самом деле это произошло с моей первой попытки), но тогда нам нужно будет использовать сервер с большим объемом памяти или создать файл SWAP, если мы все еще хотим использовать его на экземпляре EC2 Free-tier. .

Объект App - наш Потребитель. Он отвечает за создание рабочих, синхронизацию и получение выполненных заданий от рабочих.

Полный код вы можете увидеть в https://github.com/spaiz/hrscanner

Соберите и запустите приложение локально

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

# clone the project
mkdir -p ${GOPATH}/src/github.com/spaiz/
cd ${GOPATH}/src/github.com/spaiz/
git clone [email protected]:spaiz/hrscanner.git .
cd hrscanner
# install dependency manager use in the project
go get -u github.com/kardianos/govendor
# install project's dependencies
govendor sync
# install the app
go install
# unzip domains and DNS servers files
cd ${GOPATH}/src/github.com/spaiz/hrscanner/data/
unzip dns-servers.txt.zip && rm dns-servers.txt.zip
unzip uniq-domains.txt.zip && uniq-domains.txt.zip
cd ${GOPATH}/src/github.com/spaiz/hrscanner/
# run the app with default settings
hrscanner

Запустите приложение на сервере

Я использую MacBook, поэтому для создания двоичного файла для запуска в Linux я использую статическую компиляцию внутри Docker. Я подготовил для этого крошечный скрипт.

./bin/build.sh

Он создаст и поместит двоичный файл в каталог artifacts. Теперь просто загрузите двоичные файлы и файлы данных на серверы и запустите. Для этого я использую scp инструмент (вам нужно настроить SSH-доступ к вашему серверу с помощью ключей).

scp -r -C -i ~/.ssh/mykey.pem ${GOPATH}/src/github.com/spaiz/hrscanner/data/ ec2-user@remote_host:~/data/
scp -i ~/.ssh/mykey.pem ${GOPATH}/src/github.com/spaiz/hrscanner/artifacts/hrscanner ec2-user@remote_host:~/

Перед запуском приложения на сервере мы должны увеличить максимальное количество открытых файлов, иначе мы получим известную ошибку:

слишком много открытых файлов

Есть несколько способов добиться этого. Я сделал это с помощью метода, который сохранит настройки даже после перезапуска сервера. Все действия, совершаемые на инстансе Amazon бесплатного уровня из EMI Image

Создать новый файл:

sudo touch /etc/security/limits.d/custom.conf

И положи:

* soft nofile 1000000
* hard nofile 1000000

Затем отредактируйте /etc/sysctl.conf

sudo nano /etc/sysctl.conf

И добавляем в конец файла:

fs.file-max = 1000000
fs.nr_open = 1000000
net.ipv4.netfilter.ip_conntrack_max = 1048576
net.nf_conntrack_max = 1048576

Вы должны снова подключиться к серверу. Чтобы проверить, были ли применены новые настройки, запустите:

ulimit -n

Я использую tmux для запуска приложения на сервере. Это позволяет мне закрыть терминал, и приложение продолжит работу. Просто установите его на сервер и запустите.

sudo apt install tmux
tmux
# run the app with custom workers number
./hrscanner -workers=500 > logs.txt &
# exit the session
tmux detach 
# now u can close the terminal

В следующий раз, когда вы подключитесь к серверу, вы можете открыть предыдущий сеанс, набрав

tmux attach

Все домены с заголовком X-recruiting будут сохранены в файл results.txt (можно поменять флажками).

В моем случае приложение могло запускаться с ~ 700 RPS, а затем через некоторое время оно снизилось до стабильных ~ 250 RPS. (~ 900 000 запросов в час)

И файл results.txt будет выглядеть так

Исходный код:

Https://github.com/spaiz/hrscanner

P.S.

Решение не идеальное. Нет никаких повторных попыток ... нет гарантии, что все DNS-серверы работают хорошо ... Я не проверяю несколько записей DNS A, если первый HTTP-запрос не удался ... но все же, для меня этого достаточно :)

Кончик.

Вы можете создать свой собственный список доменов, например, убрав angel.co или crunchbase.com и выбрав только релевантные высокотехнологичные компании;)

P.S2

Приложение все еще работает. Я обновлю результаты, когда он закончит сканирование всех 10M сайтов :)

Обновление.
После более чем 24 часов работы приложение обнаружило 1873 домена с заголовком X-Recruiting. Посмотреть отчет можно здесь.