短鏈接服務的設計與實現

歡迎關注微信公衆號:coder家園
更多技術討論盡在coder家園。

業務背景

現在很多應用都提供短鏈接的形式,短鏈接較長鏈接比較,有閱讀起來友好、容易複製優勢。

短鏈接服務核心部分包括:

(1) 長鏈接轉短鏈接的算法

(2) 對應關係持久化,方便長鏈接和短鏈接互相查詢

短鏈接重定性流程

http://blog.csdn.net/poem_qianmo/article/details/52344732轉成短鏈接爲:http://t.cn/RtFFvic
用戶通過短鏈接訪問長鏈接過程如下:

  • 用戶訪問短鏈接:http://t.cn/RtFFvic
  • 短鏈接服務器t.cn收到請求,根據URL路徑RtFFvic獲取到原始的長鏈接:http://blog.csdn.net/poem_qianmo/article/details/52344732
  • 服務器返回302狀態碼,將響應頭中的Location設置爲:http://blog.csdn.net/poem_qianmo/article/details/52344732
  • 瀏覽器重新向http://blog.csdn.net/poem_qianmo/article/details/52344732發送請求
  • 返回響應

長鏈接轉短鏈接算法

三隻松鼠

長鏈接轉短鏈接的算法根據實際需要可以選擇支持如下特性:

(1) 高可用,服務可以部署到多臺服務器上不會出現單點故障問題。

(2) 長鏈接和短鏈接1:1映射。一方面可以解決存儲資源,另外也可以方便點擊統計等功能實現。

(3) 少碰撞。生成短鏈接性能不會隨着已生成短鏈接數量增加而線性增加。

比較常用的算法有:

  1. 隨機算法 & hash算法(MD5)
  2. 發號器 & 進制轉化
  3. 預生成 & 訪問分配

隨機算法

隨機算法原理是根據長鏈接隨機生成字符串,然後將字符串映射到[0-9][a-z][A-Z]集合上。

爲了減少隨機造成的衝突,很多公司會使用微博的短鏈接生成算法的變種。

算法一

1)將長網址md5生成32位簽名串,分爲4段, 每段8個字節;
2)對這四段循環處理, 取8個字節, 將他看成16進制串與0x3fffffff(30位1)與操作, 即超過30位的忽略處理;
3)這30位分成6段, 每5位的數字作爲字母表的索引取得特定字符, 依次進行獲得6位字符串;
4)總的md5串可以獲得4個6位串; 取裏面的任意一個就可作爲這個長url的短url地址;

這種算法,雖然會生成4個,但是仍然存在重複機率,下面的算法一和三,就是這種的實現.

算法二

62個可選元素在隨機選兩個組成長度爲64的字符數組。

  1. 隨機生成36位 0/1的隨機數
  2. 36位分成6份,通過randomValue>>6以此獲取低6位元素。
  3. (randomValue>>6) & 0x3F 獲取對應的字符

算法二衝突的概率爲1/646=1/236。

發號器 & 進制轉化

算法三

  1. 首先請求發號器生成不重複十進制數字
  2. 十進制數字轉化成62進制

該算法能夠支持62^6=500多億條長鏈接。

發號器可以選擇數據庫自增ID,snake算法,redis等諸多實現。

預生成 & 訪問分配

算法四

a-zA-Z0-9 這62位取6位組合,可產生500多億個組合數量.把數字和字符組合做一定的映射,就可以產生唯一的字符串,如第62個組合就是aaaaa9,第63個組合就是aaaaba,再利用洗牌算法,把原字符串打亂後保存,那麼對應位置的組合字符串就會是無序的組合。
把長網址存入數據庫,取返回的id,找出對應的字符串,例如返回ID爲1,那麼對應上面的字符串組合就是bbb,同理 ID爲2時,字符串組合爲bba,依次類推,直至到達64種組合後纔會出現重複的可能,所以如果用上面的62個字符,任意取6個字符組合成字符串的話,你的數據存量達到500多億後纔會出現重複的可能。

301還是302?

301永久跳轉
302臨時跳轉

兩者區別主要體現在2個方面:
(1) SEO優化

(2) 瀏覽器緩存

搜索引擎遇到301跳轉時認爲是永久跳轉, 搜索引擎只會將新鏈接加到索引裏。
當遇到302跳轉時, 搜索引擎會同時索引老鏈接和新鏈接。

瀏覽器遇到301跳轉時,會使用瀏覽器緩存,下次訪問老鏈接時會直接訪問新鏈接。當遇到302跳轉時, 瀏覽器會認爲臨時跳轉,新老鏈接都會被訪問到。

因此, 爲了統計到短鏈接訪問次數, 一般使用302狀態碼進行跳轉。

隨機算法

參考:

  1. 短網址安全淺談 https://security.tencent.com/index.php/blog/msg/126
  2. 微博URL短網址生成算法原理及(java版、php版實現實例)http://www.voidcn.com/article/p-ydjqllgt-ed.html

更多互聯網故事和後端技術請關注公衆號:coder家園 和個人主頁(samdyli.github.io)。

發佈了49 篇原創文章 · 獲贊 16 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章