歡迎關注微信公衆號: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) 少碰撞。生成短鏈接性能不會隨着已生成短鏈接數量增加而線性增加。
比較常用的算法有:
- 隨機算法 & hash算法(MD5)
- 發號器 & 進制轉化
- 預生成 & 訪問分配
隨機算法
隨機算法原理是根據長鏈接隨機生成字符串,然後將字符串映射到[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的字符數組。
- 隨機生成36位 0/1的隨機數
- 36位分成6份,通過randomValue>>6以此獲取低6位元素。
- (randomValue>>6) & 0x3F 獲取對應的字符
算法二衝突的概率爲1/646=1/236。
發號器 & 進制轉化
算法三
- 首先請求發號器生成不重複十進制數字
- 十進制數字轉化成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狀態碼進行跳轉。
隨機算法
參考:
- 短網址安全淺談 https://security.tencent.com/index.php/blog/msg/126
- 微博URL短網址生成算法原理及(java版、php版實現實例)http://www.voidcn.com/article/p-ydjqllgt-ed.html
更多互聯網故事和後端技術請關注公衆號:coder家園 和個人主頁(samdyli.github.io)。