場景
短鏈接服務就是將一段長的URL轉換為短的URL,比如利用新浪微博的短鏈接生成器,可將一段長的URL(http://blog.csdn.net/poem_qianmo/article/details/52344732)轉換為一段短的URL(http://t.cn/RtFFvic),用戶通過訪問短鏈接即可重定向到原始的URL。
整個交互流程如下:
- 用戶訪問短鏈接: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)利用放號器,初始值為0,對於每一個短鏈接生成請求,都遞增放號器的值,再將此值轉換為62進制(a-zA-Z0-9),比如第一次請求時放號器的值為0,對應62進制為a,第二次請求時放號器的值為1,對應62進制為b,第10001次請求時放號器的值為10000,對應62進制為sBc。
(2)將短鏈接服務器域名與放號器的62進制值進行字符串連接,即為短鏈接的URL,比如:t.cn/sBc。
-
重定向過程
生成短鏈接之后,需要存儲短鏈接到長鏈接的映射關系,即sBc -> URL,瀏覽器訪問短鏈接服務器時,根據URL Path取到原始的鏈接,然后進行302重定向。映射關系可使用K-V存儲,比如Redis或Memcache。
優化方案
-
算法優化
采用以上算法,對於同一個原始URL,每次生成的短鏈接是不同的,這樣就會浪費存儲空間,因為需要存儲多個短鏈接到同一個URL的映射,如果能將相同的URL映射成同一個短鏈接,這樣就可以節省存儲空間了。
(1)方案1:查表
每次生成短鏈接時,先在映射表中查找是否已有原始URL的映射關系,如果有,則直接返回結果。很明顯,這種方式效率很低。
(2)方案2:使用LRU本地緩存,空間換時間
使用固定大小的LRU緩存,存儲最近N次的映射結果,這樣,如果某一個鏈接生成的非常頻繁,則可以在LRU緩存中找到結果直接返回,這是存儲空間和性能方面的折中。
-
可伸縮和高可用
如果將短鏈接生成服務單機部署,缺點一是性能不足,不足以承受海量的並發訪問,二是成為系統單點,如果這台機器宕機則整套服務不可 用,為了解決這個問題,可以將系統集群化,進行“分片”。
在以上描述的系統架構中,如果發號器用Redis實現,則Redis是系統的瓶頸與單點,因此,利用數據庫分片的設計思想,可部署多個發號器實例,每個實例負責特定號段的發號,比如部署10台Redis,每台分別負責號段尾號為0-9的發號,注意此時發號器的步長則應該設置為10(實例個數)。
另外,也可將長鏈接與短鏈接映射關系的存儲進行分片,由於沒有一個中心化的存儲位置,因此需要開發額外的服務,用於查找短鏈接對應的原始鏈接的存儲節點,這樣才能去正確的節點上找到映射關系。
ref:
短鏈接服務架構設計與實現
https://blog.csdn.net/lz0426001/article/details/52370177
URL短網址生成算法原理
https://blog.csdn.net/ithomer/article/details/81436493
Yourls開源短鏈接(短網址)程序源碼的各種使用方法
https://blog.csdn.net/qq_40134903/article/details/81022758
官方網站:http://yourls.org