Sparkfun.com FREE day или *как вы относитесь к recaptcha*

от автора

Вдохновение

Пока 55% ненавидит…

А я выбрал «другое». Потому что люблю. Но не за то, что считаю удобнее других, а за то, что…

Раз в год американская компания sparkfun.com, хорошо знакомая всяким DIY-щикам, проводит (почти что) лотерею. В последний, или, как говорят парашютисты, крайний раз они делали это 10-го января сего года. Суть проста — заходишь на сайт и в течение определенного времени разгадываешь те самые ненавистные рекапчи. Некое устройство рандомно выбирает одну из разгаданных капч и выдает автору сертификат на $100 — на эти деньги можно заказать что угодно на спаркфане, оплачивается только доставка. То есть абсолютно честный гив-эвей.

И вот, в 9ам по колорадскому времени, куча народу со всего мира садиться гадать рекапчи. Сайт тут же падает. На его место вешают заглушку, которая извиняется за недоступность магазина и выбрасывает тебя на отдельную страницу разгадывания капч. На самом деле там, в Колорадо, народ не сидит и не ржет над разгадывальщиками, а изо всех сил пытается побороть этот хабраэффект.

Я выиграл — через полчаса вбиваний рекапчи

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

Отчет о Free day

12 Января 2012

Снова январь и еще один Free Day. Выиграли ли вы или проиграли, мы надеемся, что все получили удовольствие. Уж мы-то получили тонну удовольствия устраивая его — это точно!

Числа
Кое-какие числа, потом расскажу как мы это организовывали.

  • 6,437,592 верных решений рекапчи. Сюда не входят те попытки, в которых рекапча была разгадана неверно, как и те, которые регистрировались при нажатии кнопки GO без заполнения поля ответа
  • Если считать, что усредненный человек тратит 4 секунды на капчу, на все про все было потрачено 7 188 часов, т.е. около 10 месяцев времени!
  • Каждая капча была обработана сервером спаркфана — т.е. 300 капч в секунду в течение 355 минут — когда мы раздавали деньги
  • 32,137 Уникальных посетителей на сайте (по отчетам Analytics). С некоей погрешностью это число игроков.
  • В среднем, каждый заполнил 208 капч. Зная, что такое капча — это дофига!
  • 704,617 просмотров страниц на сайте в течение дня
  • Было распределено 2000 промо-кодов, из них 473 было заклаймлено в тот же день. Первый заказ ушел в доставку в 10:45, т.е. менее чем через 2 часа после начала мероприятия
  • Мы выдавали промо-коды примерно раз в 5.6 минут
  • В этот день было зарегистрировано 7776 аккаунтов

Еще числа, для тех, кто в теме

  • В максимуме наш MySQL обрабатывал 13,380 запросов в секунду
  • Максимум пропускной способности нашей сети был 1,214.35Mb/s
  • Максимум ширины канала к провайдеру достиг чуть более 76M.b/s
  • В максимуме у нас было 84,220 активных TCP подключений.
  • Мы забанили 32 бота.
  • Мы положили внешний сайт перенаправляя слишком большой трафик на него (Прости, Pachube!)

Реальная установка, которая использовалась

Как мы этот сделали — опять же, для гиков. Если вы участвовали в первых двух акциях, вы могли заметить, что акция в этом году прошла намного лучше. Если исключить то, что сайт захлебнулся в первые минуты, когда пошел самый большой наплыв участников, сайт вполне себе отвечал, в то время, как он на самом деле обрабатывал огромный трафик. Что же изменилось по сравнению с прошлыми годами?
Мы подтянули кое-какой софт и хард к нашим серверам. Теперь у нас есть пара жирненьких веб-сервера, каждый с 16-ю ядрами и 32 гигами оперативки, и у нас есть хардовые балансировщики нагрузки.
Плюс к этому, мы оптимизировали наш собственный код для работы с нашим железом, поменяли кое-какой оупен-сорс софт. Мы также перешли с Apache на Nginx, на котором всю обработку вел PHP-FPM. Перед всем этим еще тусит Varnish кэшируя все, что получается — что оказалось офигенски полезным для проведения акции.
Также, в прошлые годы мы заметили, что чаще всего лаги были обусловлены тормозами MySQL, ну мы и подперли его кое-где MongoDB. Для некоторых (особенно иерархичных данных) это имело смысл. Это помогло нам реально быстро показывать странички. К сожалению, из-за небольшого бага в драйвере PHP Mongo у нас в первые минуты акции вышел затык.
Раньше мы весь-весь контент отдавали прямо с нашего сервера. Когда нагрузка нормальная, это ОК — страницы грузятся нормально и канал мы съедаем небольшой. Естественно во время проведения Free Day все меняется. В этом году мы весь статичный контент повесили на Amazon Cloudfront. Cloudfront — это такая глобальная CDN, которая сидит поверх всем известного стоража S3 и грузит контент с краевых серверов пользователям по всему миру. При этом, естественно, нагрузка ложится на них, а не на нас. Но и это особо не спасает. Те 76Mb/s, что мы пропускали через свои сервера — это был в основно запакованный gzip текст.

Счетчик Гейгера?


Ну а чо. Любой человек, знакомый с computer science, скажет вам, что случайнчые числа, которые генрит комп — это на самом деле псевдо-случайные числа. Их можно предсказать — даже если есть 1 шанс из миллиона на успех, это все равно шанс. Ну и как же нам построить абсолютно случайную систему?
Мы выбрали счетчик гейгера для измерения фоновой радиации. Счетчик дергает ногу контроллера вниз каждый раз, когда видит заряженную частицу — это происходит абсолютно точно рандомно. Мы установили наш Ethernet Pro, чтобы следить за этими прерываниями и посылать байт демону, сидящему на одно из веб-серверов, чтобы он уведомил следующего разгадавшего капчу о победе.
Вот код для дуни:

#include <Ethernet.h> #include <SFEbarGraph.h> #include <SPI.h>  // Default 'ino MAC address byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192, 168, 0, 2 };  int up = 8; int down = 7; int upstate = 0; int downstate = 0;  // replace with your server byte server[] = { 192, 168, 0, 1 };  EthernetClient client;  SFEbarGraph BG; volatile int counter = 0; int oldcount = 0; int target = 8; int multiplier = 2;  void setup() {   BG.begin(1, 9);    // Interrupt from the Geiger tube   attachInterrupt(0, detect, RISING);   Serial.begin(9600);    Ethernet.begin(mac, ip);    // set up buttons   pinMode(up, INPUT);   digitalWrite(up, HIGH);   pinMode(down, INPUT);   digitalWrite(down, HIGH);    delay(1000); }  void loop() {    // read up button   if(LOW == digitalRead(up)) {     if(0 == upstate) {       target++;       redraw();       upstate = 1;     }   } else {     upstate = 0;   }    // read down button   if(LOW == digitalRead(down)) {     if(0 == downstate) {       target--;       redraw();       downstate = 1;     }   } else {     downstate = 0;   }    if(counter == oldcount) {     delay(1);     return;   }   oldcount = counter;    // handle wins   if(counter >= target) {     win();     counter = 0;     oldcount = 0;     return;   }    redraw(); }  // for the interrupt void detect() {   counter++; }  void redraw() {   // boundaries   if(target > (30 / multiplier))     target = (30 / multiplier);   if(target < 1)     target = 1;    BG.clear(); BG.send();   BG.barGraph(counter * multiplier, target * multiplier); }  void win() {   Serial.println("WINNER");   for(int i = target * multiplier; i >= 0; i--) {     BG.barGraph(i, target * multiplier);     delay(35);   }    if ( ! client.connected()) {     Serial.println("connecting...");     if (client.connect(server, 5555)) {       Serial.println("connected");     } else {       Serial.println("connection failed");     }   }    // Print a 1 to the Ethernet server for every win   client.print("1"); }

Ну и чтобы закрыть тему, вот код бит-сервера, который написал Бен для обработки сотен запросов в секунду. Он проверял его на нагрузке до 600 тыс запросов в секунду.

Ну и кто знает английский — не откажите себе в удовольствии почитать комментарии к этой записи и посмотрите видео. Там вы узнаете, любит ли народ капчу.

От переводчика и автора поста: перевод достаточно вольный — не обессудьте. Настроение такое, что либо так, либо никак.

ссылка на оригинал статьи http://habrahabr.ru/post/155161/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *