2011-10-01 46 views
23

我們都看到了您在使用裸機「heroku創建」將應用部署到Heroku時自動分配的有趣子域。一些例子:熾烈的霧4652,電夜4641,早霜5543,輻射河7322,等等。如何以編程方式生成類似Heroku的子域名?

看來他們都遵循形容詞 - 名詞-4數字模式(大部分)。他們只是簡單地列出一些形容詞和名詞詞典,然後在推送應用程序時隨機選擇它們的組合?是否有一個Ruby的寶石完成了這一點,或許提供了一個可以通過詞類進行搜索的字典,或者這是手動完成的事情?

+0

形容詞和名詞也可以是「數字」,以base- [單詞列表的長度] – millimoose

回答

67

Heroku API團隊的工程師在這裏:我們用最簡單的方法來生成應用程序名稱,這基本上就是您建議的內容:在內存中保留形容詞和名詞的數組,並隨機選擇一個元素並將其與從1000到9999

不是最驚心動魄的代碼的隨機數,我寫的,但它是有趣的,看看我們有什麼,以規模該做的事:

  • 起初,我們採摘一個名字,試圖INSERT,然後拯救唯一性約束錯誤來選擇一個不同的名字。當我們擁有大量名稱(以及使用它們的不太多的應用程序集)時,這種方式運行良好,但是在一定規模下,我們開始注意到名稱生成過程中發生了很多衝突。

    爲了使其更具彈性,我們決定挑選多個名稱,並檢查哪些名稱仍然可用於單個查詢。我們顯然仍然需要檢查錯誤,並且因爲競爭條件而重試,但在桌面上有這麼多的應用程序,這顯然更有效。

    它還有一個額外的好處,就是如果我們的名字池很低(例如:如果有三分之一的隨機名字被髮送,發送警報),我們就可以輕鬆獲得警報。

  • 我們第一次遇到碰撞問題時,我們從2位數字變爲4,從根本上增加了名稱池的大小.61個形容詞和74個名詞使我們從約400k到約40mi個名字(61 * 74 * 8999) 。

  • 但是,當我們運行200萬個應用程序時,我們又開始接收到碰撞警報,並且速度遠高於預期:大約一半的名字發生了碰撞,考慮到我們的游泳池大小和數量,應用正在運行

    您可能已經猜到的罪魁禍首是rand是一個相當不好的pseudorandom number generator。使用SecureRandom隨機選取元素和數字,而不是從根本上降低碰撞量,使其與我們預期的第一位相匹配。

有了這麼多的工作來擴展這個方法,我們不得不問問是否有更好的方法來生成名字。討論的一些想法是:

  • 使名稱生成是應用程序ID的函數。這會更快,並避免完全碰撞的問題,但在不利方面,它會浪費大量名稱與刪除的應用程序(和該死的,我們有很多應用程序被創建和刪除不久後作爲不同的集成測試的一部分) 。

  • 另一種使命名確定的方法是在數據庫中擁有可用名稱池。這樣可以輕鬆完成諸如在應用被刪除2周後重新使用名稱等操作。

興奮地看看我們下次要做什麼碰撞警報觸發!

希望這有助於任何人在那裏工作的友好名稱的產生。

+1

這很好...爲了保持'平均'分佈的名稱數量,應該考慮的事情是隨意考慮名稱發生率的思考值,以便更多使用名稱的機會更少下次來...(用於例如粒子過濾器)=) –

+0

@IvanSeidel我喜歡你的想法! – Benoit

10

有幾種可能性。

您可以generate a random string

如果你想使用真實的單詞,你需要一本字典。然後,您可以創建一個結果生成單詞和數字的排列。

另一個不錯的選擇是通過Ruote。 Ruote依靠rufus-mnemo爲每個進程生成一個唯一的名稱。 rufus-mnemo提供了將整數轉換成更容易記住「單詞」的方法,反之亦然。

您可以爲記錄生成一個唯一的ID,然後將其轉換爲單詞。

+0

rufus-mnemo看起來不錯,感謝您的鏈接! – dkulchenko