Мы все видели интересные поддомены, которые автоматически назначаются вам при развертывании приложения в Heroku с помощью простого «heroku create».
Некоторые примеры: пылающий туман-4652, электрическая ночь-4641, утренний мороз-5543, лучистая река-7322 и так далее.
Похоже, что все они следуют образцу прилагательное-существительное-4-значное число (по большей части). Они просто набирали словарь некоторых прилагательных и существительных, а затем случайным образом выбирали из них комбинации, когда вы запускали приложение? Есть ли драгоценный камень Ruby, который выполняет это, возможно, предоставляет словарь, в котором можно искать по частям речи, или это нужно делать вручную?
Инженер из команды Heroku API: мы пошли с самым простым подходом к генерации имен приложений, что, в основном, и было вашим предложением: хранить массивы прилагательных и существительных в памяти, произвольно выбирать элемент из каждого и объединять его с случайное число от 1000 до 9999.
Не самый захватывающий код, который я написал, но интересно посмотреть, что мы должны были сделать, чтобы масштабировать это:
Сначала мы выбирали имя, пытаясь на INSERT
, а затем спасите ошибку ограничения уникальности, чтобы выбрать другое имя. Это работало нормально, когда у нас был большой пул имен (и не очень большой набор приложений, использующих их), но в определенном масштабе мы начали замечать много коллизий во время генерации имен.
Чтобы сделать его более устойчивым, мы решили выбрать несколько имен и проверить, какие из них по-прежнему доступны с помощью одного запроса. Очевидно, нам по-прежнему нужно проверять наличие ошибок и повторять попытки из-за условий гонки, но с таким количеством приложений в таблице это явно более эффективно.
Это также имеет дополнительное преимущество, заключающееся в том, что мы можем легко получать оповещения, если наш пул имен мал (например, если выбрано 1/3 случайных имен, отправьте оповещение).
В первый раз, когда у нас возникли проблемы со столкновениями, мы просто радикально увеличили размер нашего пула имен, перейдя с 2 цифр до 4. С 61 прилагательным и 74 существительными это подняло нас от ~ 400k до ~ 40mi имен (61 * 74 * 8999
).
Но к тому времени, когда мы запустили 2 миллиона приложений, мы снова начали получать оповещения о коллизиях, причем с гораздо большей скоростью, чем ожидалось: около половины имен сталкивались, что не имело смысла, учитывая размер и количество нашего пула запущенных приложений.
Виновник, как вы могли догадаться, заключается в том, что rand
- довольно плохой генератор псевдослучайных чисел . Выбор случайных элементов и чисел с помощью SecureRandom
радикально уменьшил количество столкновений, сделав его таким, как мы ожидали.
Из-за огромной работы по масштабированию этого подхода нам пришлось спросить, есть ли лучший способ генерировать имена в первую очередь. Вот некоторые из обсуждаемых идей:
Сделать генерацию имени функцией идентификатора приложения. Это было бы намного быстрее и полностью исключило бы проблему со столкновениями, но с другой стороны это привело бы к потере большого количества имен с удаленными приложениями (и, черт возьми, у нас МНОГО приложений, которые создаются и удаляются вскоре после этого как часть различных интеграционных тестов) .
Другой вариант сделать генерацию имен детерминированным - это иметь пул доступных имен в базе данных. Это облегчило бы такие вещи, как повторное использование имени через 2 недели после удаления приложения.
Рад видеть, что мы сделаем в следующий раз, когда сработает оповещение о столкновении!
Надеюсь, это поможет любому, кто работает над созданием дружественного имени.