如何以编程方式生成类似Heroku的子域名?

时间:2011-10-01 16:02:00

标签: ruby heroku subdomain linguistics

我们已经看到了当您使用简单的“heroku create”将应用程序部署到Heroku时自动分配的有趣子域。

一些例子:炽热的薄雾4652,电动夜-4641,晨霜-5543,辐射河-7322,等等。

它们似乎都遵循形容词 - 名词 - 4数字模式(大部分)。他们只是输入了一些形容词和名词的字典,然后在推送应用程序时随机选择它们的组合吗?是否有一个Ruby宝石可以实现这一点,也许提供一个可以通过词性搜索的字典,或者这是手动完成的事情?

4 个答案:

答案 0 :(得分:75)

Heroku API团队的工程师:我们采用最简单的方法来生成应用程序名称,这基本上就是你建议的:将形容词和名词的数组保存在内存中,随机选择一个元素并将其与随机数从1000到9999。

不是我编写过的最激动人心的代码,但有趣的是看到我们必须做些什么来扩展它:

  • 首先,我们选择了一个名称,尝试INSERT,然后挽救唯一性约束错误以选择其他名称。这个工作正常,而我们有一大堆名字(以及使用它们的不那么大的应用程序集),但在一定规模上,我们开始注意到在名称生成过程中发生了很多冲突。

    为了使其更具弹性,我们决定挑选几个名称,并通过单个查询检查哪些名称仍然可用。我们显然仍然需要检查错误并因竞争条件而重试,但表中有如此多的应用程序显然更有效。

    如果我们的名字池很低,它还有一个额外的好处就是为我们提供一个简单的钩子(例如:如果采用1/3的随机名称,发送警报)。

    < / LI>
  • 我们第一次遇到碰撞问题时,我们只是从2位数到4位,大大增加了我们名字池的大小。有61个形容词和74个名词,这使我们从〜400k到~40mi名称({ {1}})。

  • 但是当我们运行200万个应用程序时,我们又开始接收碰撞警报,并且速度远高于预期:大约一半的名称发生碰撞,考虑到我们的游泳池大小和数量,没有任何意义运行的应用程序。

    您可能已经猜到的罪魁祸首是61 * 74 * 8999非常糟糕pseudorandom number generator。使用rand挑选随机元素和数字会从根本上降低碰撞量,使其与我们预期的一致。

随着这么多工作要扩展这种方法,我们不得不问,是否有更好的方法来首先生成名称。讨论的一些想法是:

  • 使名称生成成为应用程序ID的函数。这将更快,并完全避免碰撞的问题,但在缺点,它会浪费很多名称与删除的应用程序(该死的,我们有很多应用程序创建和删除后不久作为不同的集成测试的一部分)

  • 使名称生成具有确定性的另一个选项是在数据库中拥有可用名称池。这样可以轻松完成仅删除应用程序2周后重复使用名称的操作。

很高兴看到下次碰撞警报触发后我们会做什么!

希望这有助于任何致力于友好名称生成的人。

答案 1 :(得分:10)

有几种可能性。

你可以generate a random string

如果你想使用真实的单词,你需要一本字典。然后,您可以创建一个生成单词和数字排列的结果。

另一个不错的选择是Ruote采用的另一种选择。 Ruote依赖rufus-mnemo为每个进程生成唯一的名称。 rufus-mnemo提供了将整数转换为更容易记住“单词”的方法,反之亦然。

您可以为记录生成唯一ID,然后将其转换为单词。

答案 2 :(得分:7)

我创建了一个宝石:RandomUsername

类似的宝石有BazaarFaker

答案 3 :(得分:0)

感谢@m1foley

我正在使用你的宝石 https://github.com/polleverywhere/random_username


生成随机名称:

num_size = 2 # you can change this value to change number size
temp_num = (Array.new(num_size) { rand(10).to_s }).join
app_url = RandomUsername.adjective + '-' + RandomUsername.noun + '-' + temp_num

说明:

  1. 首先生成两位数
  2. 然后生成形容词
  3. 然后生成一个名词
  4. 最后用破折号(-)连接起来:形容词+名词+temp_num

一些生成的名称:

# caring-plateau-07
# teal-summer-32
# vivid-snowflake-25
# outrageous-summer-95