Pull to refresh

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

Reading time5 min
Views17K
Original author: stilldavid
Вдохновение.

Пока 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 тыс запросов в секунду.

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



От переводчика и автора поста: перевод достаточно вольный — не обессудьте. Настроение такое, что либо так, либо никак.
Tags:
Hubs:
Total votes 65: ↑51 and ↓14+37
Comments14

Articles