Как я могу программно сгенерировать имена поддоменов, подобные Heroku?

Мы все видели интересные поддомены, которые автоматически назначаются вам при развертывании приложения в Heroku с помощью простого «heroku create».

Некоторые примеры: пылающий туман-4652, электрическая ночь-4641, утренний мороз-5543, лучистая река-7322 и так далее.

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

29
задан Simone Carletti 2 October 2011 в 12:21
поделиться

2 ответа

Инженер из команды Heroku API: мы пошли с самым простым подходом к генерации имен приложений, что, в основном, и было вашим предложением: хранить массивы прилагательных и существительных в памяти, произвольно выбирать элемент из каждого и объединять его с случайное число от 1000 до 9999.

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

  • Сначала мы выбирали имя, пытаясь на INSERT, а затем спасите ошибку ограничения уникальности, чтобы выбрать другое имя. Это работало нормально, когда у нас был большой пул имен (и не очень большой набор приложений, использующих их), но в определенном масштабе мы начали замечать много коллизий во время генерации имен.

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

    Это также имеет дополнительное преимущество, заключающееся в том, что мы можем легко получать оповещения, если наш пул имен мал (например, если выбрано 1/3 случайных имен, отправьте оповещение).

  • В первый раз, когда у нас возникли проблемы со столкновениями, мы просто радикально увеличили размер нашего пула имен, перейдя с 2 цифр до 4. С 61 прилагательным и 74 существительными это подняло нас от ~ 400k до ~ 40mi имен (61 * 74 * 8999).

  • Но к тому времени, когда мы запустили 2 миллиона приложений, мы снова начали получать оповещения о коллизиях, причем с гораздо большей скоростью, чем ожидалось: около половины имен сталкивались, что не имело смысла, учитывая размер и количество нашего пула запущенных приложений.

    Виновник, как вы могли догадаться, заключается в том, что rand - довольно плохой генератор псевдослучайных чисел . Выбор случайных элементов и чисел с помощью SecureRandom радикально уменьшил количество столкновений, сделав его таким, как мы ожидали.

Из-за огромной работы по масштабированию этого подхода нам пришлось спросить, есть ли лучший способ генерировать имена в первую очередь. Вот некоторые из обсуждаемых идей:

  • Сделать генерацию имени функцией идентификатора приложения. Это было бы намного быстрее и полностью исключило бы проблему со столкновениями, но с другой стороны это привело бы к потере большого количества имен с удаленными приложениями (и, черт возьми, у нас МНОГО приложений, которые создаются и удаляются вскоре после этого как часть различных интеграционных тестов) .

  • Другой вариант сделать генерацию имен детерминированным - это иметь пул доступных имен в базе данных. Это облегчило бы такие вещи, как повторное использование имени через 2 недели после удаления приложения.

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

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

77
ответ дан 28 November 2019 в 00:45
поделиться

Я создал камень для этого: RandomUsername

Подобные камни - Bazaar и Faker .

7
ответ дан 28 November 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: