短連接系統

使用場景(Scenario)

微博和Twitter都有140字數的限制,如果分享一個長網址,很容易就超出限制,發佈出去。短網址服務可以把一個長網址變成短網址,方便在社交網絡上傳播。

需求(Needs)

  • 將長連接變成短連接
  • 用戶訪問短連接,會跳轉到正確的長連接上

 

短網址的長度

當前互聯網上的網頁總數大概是 45 億,45億 超過了 2^32 ,但遠遠小於64位整數的上限值,那麼用一個64位整數足夠了。微博的短網址服務用的是長度爲 7 的字符串,這個字符串可以看做是 62 進制的數,那麼最大能表示 62^7 個網址,遠遠大於 45 億。所以長度爲 7 就足夠了。這個量級遠遠超過互聯網上的 URL 總數了,絕對夠用了。現代的 web 服務器(例如Apache, Nginx)大部分都區分 URL 裏的大小寫了,所以用大小寫字母來區分不同的 URL 是沒問題的。

[a-z,A-Z,0-9] 這62個字母或數字組成的7位的字符串。

一對多映射

一個長網址,對應一個短網址,還是可以對應多個短網址?

一般而言,一個長網址,在不同的地點,不同的用戶等情況下,生成的短網址應該不一樣。這樣,在後端數據庫中,可以更好的進行數據分析。如果一個長網址與一個短網址一一對應,那麼在數據庫中,僅有一行數據,無法區分不同的來源,就無法做數據分析。

以這個7位長度的短網址作爲唯一ID,這個ID下可以掛各種信息,比如生成該網址的用戶名,所在網站,HTTP頭部的 User Agent等信息,收集了這些信息,纔有可能在後面做大數據分析,挖掘數據的價值。短網址服務商的一大盈利來源就是這些數據。

如何計算短網址

現在我們設定了短網址是一個長度爲7的字符串,如何計算得到這個短網址呢?

  • 自增id

    • 無碰撞的方法,沒新增一個短碼,就在上次的短碼id上加1,然後把這個10進制的數,轉成一個62進制的字符串。
    • 可以利用數據庫表中的自增id來完成,每次先查數據庫表中自增id最大值max,然後max+1轉成62進制數
    • 短碼id是從一位長度遞增的,長度不固定,可以指定id從某個數字開始,確保所有短碼長度一致。同事短碼是有序的,可能有安全問題,所以將生成的短碼id結合長網址等其他關鍵字,進行MD5運算生成最後的短碼。
  • 普通隨機數

    • 利用Math.round()生成隨機數,如果庫中存在這個id就重複生成隨機數。
    • 這種情況下,發生碰撞的可能性不小,可能要多次循環纔可以生成一個不衝突的短碼。
  • 摘要算法(哈希算法)

    • 輸入任意長度的數據,輸出固定長度的數據,相同的輸入對應相同的輸出,不同的輸入儘量拿到不同的輸出。
    • (1)將長網址md5生成32位簽名串,分爲4段, 每段8個字節;
    • (2)對這四段循環處理, 取8個字節, 將他看成16進制串與0x3fffffff(30位1)與操作, 即超過30位的忽略處理;
    • (3)這30位分成6段, 每5位的數字作爲字母表的索引取得特定字符, 依次進行獲得6位字符串;
    • (4)總的md5串可以獲得4個6位串;取裏面的任意一個就可作爲這個長url的短url地址;
    • 也會發生碰撞,但是碰撞機率小,一單發生碰撞的話解決衝突比較麻煩。
  • 利用Redis號段模式

    • 將 62^7的 ID 進行分段,比如分爲 N 段,前 K 位一致。那麼剩下的位就可以通過 Redis 來進行生成,防止重複。
    • 假設要獲取一個號段,比如(1,1000]的,只需要在本地利用redis自增一個id就可以,

如何存儲

  • 數據庫存儲

    • 域名,鏈接除域名外的後綴,完成鏈接,生成的短連接,短鏈接失效時間,當前鏈接總的點擊次數。
    • 因爲短鏈接需求可能是相關活動或者熱點數據,所以過濾一定時間熱潮會持續衰退,沒必要永久保存增加每次查詢的負擔。
  • 數據庫分表

    • 如果一條數據是10b的話,總容量是45億×10b,單表肯定無法支撐,所以要分表。
    • 假設分成100張表的話,每張表名通過數字區分。可以通過短鏈接做encoding編碼生成數字類型,然後做路由找到表。
  • 緩存存儲

    • 查詢需求:如果是幾百G的數據量放緩存是不合適的,可以將近3個月的查詢或者新增URL放入緩存,使用LRU算法進行熱點更新。這樣,最近使用的命中緩存概率會高,查不到在查庫更新緩存。
    • 新增需求:新增的就先查緩存是否存在,緩存沒有再查庫,庫的話可以分表,查詢率不會很低。
    • 緩存設計:用戶用短鏈接查真是地址,緩存key是短鏈接,使用KV存就可以。

如何跳轉

當我們在瀏覽器裏輸入 http://bit.ly/a3300 時

  1. DNS首先解析獲得 http://bit.ly的 IP 地址
  2. 當 DNS 獲得 IP 地址以後(比如:12.34.5.32),會向這個地址發送 HTTP GET 請求,查詢短碼 a3300
  3. [http://bit.ly 服務器會通過短碼 a3300 獲取對應的長 URL
  4. 請求通過 HTTP 301 轉到對應的長 URL http://www.theaustralian.news.com.au/story/0,25197,26089617-5013871,00.html。

301是永久重定向,302是臨時重定向。短地址一經生成就不會變化,所以用301是符合http語義的。但是如果用了301, Google百度等搜索引擎,搜索的時候會直接展示真實地址,那我們就無法統計到短地址被點擊的次數了,也無法收集用戶的CookieUser Agent 等信息,這些信息可以用來做很多有意思的大數據分析,也是短網址服務商的主要盈利來源。

所以,正確答案是302重定向。

可以抓包看看mrw.so的短網址是怎麼做的,使用 Chrome 瀏覽器,訪問這個URL http://mrw.so/4UD39p,是我事先發微博自動生成的短網址。來抓包看看返回的結果是啥,可見新浪微博用的就是302臨時重定向。

參考:https://www.cnblogs.com/rickiyang/p/12178644.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章