【问题标题】:How can I programmatically generate Heroku-like subdomain names?如何以编程方式生成类似 Heroku 的子域名?
【发布时间】:2011-11-29 02:20:47
【问题描述】:

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

一些例子:blazing-mist-4652、electric-night-4641、morning-frost-5543、radiant-river-7322,等等。

似乎它们都遵循形容词-名词-4digitnumber 模式(大部分情况下)。他们是否只是简单地打出一些形容词和名词的字典,然后在你推送应用时随机选择组合?是否有一个 Ruby gem 可以做到这一点,也许提供一个可以通过词性搜索的字典,或者这是手动完成的事情?

【问题讨论】:

  • 形容词和名词也可以是“数字”,以基数-[单词表的长度]

标签: ruby heroku subdomain linguistics


【解决方案1】:

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

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

  • 起初我们选择一个名字,尝试INSERT,然后挽救唯一性约束错误来选择一个不同的名字。当我们有大量名称(以及使用它们的应用程序不是那么大)时,这工作得很好,但在一定规模上,我们开始注意到名称生成过程中出现了很多冲突。

    为了使其更具弹性,我们决定选择几个名称,并检查哪些名称在单个查询中仍然可用。由于竞态条件,我们显然仍然需要检查错误并重试,但表中有这么多应用程序,这显然更有效。

    它还有一个额外的好处,即在我们的名称池不足时为我们提供一个简单的钩子来获取警报(例如:如果随机名称的 1/3 被采用,则发送警报)。

  • 我们第一次遇到冲突问题时,我们只是从根本上增加了名称池的大小,从 2 位数字增加到 4 位。有了 61 个形容词和 74 个名词,这使我们的名称从大约 400k 增加到了大约 40mi(@ 987654323@)。

  • 但是当我们运行 200 万个应用程序时,我们再次开始收到碰撞警报,而且比率远高于预期:大约一半的名称发生碰撞,考虑到我们的池大小和正在运行的应用程序数量,这是没有意义的.

    您可能已经猜到的罪魁祸首是rand 是一个非常糟糕的pseudorandom number generator。使用SecureRandom 选择随机元素和数字反而从根本上降低了冲突的数量,使其符合我们最初的预期。

由于要扩展这种方法的工作量如此之大,我们不得不首先询问是否有更好的方法来生成名称。讨论的一些想法是:

  • 使名称生成成为应用程序 ID 的函数。这会更快并完全避免冲突问题,但不利的一面是,它会浪费大量名称与已删除的应用程序(该死,作为不同集成测试的一部分,我们很快就会创建和删除很多应用程序) .

  • 使名称生成具有确定性的另一个选项是在数据库中拥有可用名称池。这样可以很容易地执行一些操作,例如仅在应用被删除 2 周后重用名称。

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

希望这可以帮助任何从事友好名称生成工作的人。

【讨论】:

  • 太好了...为了保持“平均”分布的名称数量,应该考虑的事情是随机化名称出现的经过思考的值,以便名称用得越多,下次出现的机会就越少...(例如用于粒子过滤器)=)
  • @IvanSeidel 我喜欢你的想法!
【解决方案2】:

有几种可能。

你可以generate a random string

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

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

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

【讨论】:

    【解决方案3】:

    我为此创建了一个 gem:RandomUsername

    类似的宝石是BazaarFaker

    【讨论】:

      【解决方案4】:

      感谢@m1foley

      我正在使用你的 gem 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
      

      【讨论】:

        猜你喜欢
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-08
        相关资源
        最近更新 更多