1. 程式人生 > >短連結原理分析

短連結原理分析

1. 什麼是短連結


顧名思義,短連結即是長度較短的網址。通過短連結技術,我們可以將長度較長的連結壓縮成較短的連結。並通過跳轉的方式,將使用者請求由短連結重定向到長連結上去。短連結主要用在諸如微博,BBS等對帖子字數有限制的網站,通過使用短連結,使用者可以把注意力放在帖子的內容上,而不是在擔心連結超長的問題。這裡以百度的 dwz.cn 短連結服務為例,我們使用百度搜索"hello world",連結為https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=hello%20world&rsv_pq=8487bffe00068c60&rsv_t=a9e0f5b6haiMQwAi4N2y8PHDv37rM6sjjKrHJb6KdMGg2dQuUjAnmSEnXtE&rqlang=cn&rsv_enter=1&rsv_sug3=10&rsv_sug1=9&rsv_sug7=100,統計了一下,這條連結長度為230。如此長的連結佔據微博篇幅不說,也會影響微博的美觀度。這個時候我們可以使用百度短連結服務壓縮一下上面的長連結,壓縮後的連結為:http://dwz.cn/5DDXhH。可以看到,壓縮後的連結長度比原連結明顯變短了。

百度短地址服務

 

2. 常見的短連結壓縮演算法


常見的短連結壓縮演算法有兩種,第一種是對 URL 進行hash運算,在得到的hash值上做進一步運算,得到一個較短的hash值。第二種是通過資料庫自增ID或分散式key-value系統模擬發號器進行發號壓縮URL。兩種方式各有優劣,hash運算簡單易實現,但是有一定的衝突率。隨著 URL 壓縮數量的增加,衝突數也會增加,最終導致一部分使用者跳轉到錯誤的地址上,影響使用者體驗。而發號器發號壓縮 URL 優缺點恰好和hash壓縮演算法相反,優點是不存在衝突問題。缺點是,實現上稍複雜,要協調發號器取初始號。本文對應的練手專案是基於第二種壓縮演算法實現的,下面也將對詳細分析第二種演算法。

 

3. 使用發號策略壓縮URL


發號策略是這樣的,當一個新的連結過來時,發號器發一個號與之對應。往後只要有新連結過來,發號器不停發號就好。舉個例子,第一個進來的連結發號器發0號,對應的短連結為 xx.xxx/0,第二個進來的連結發號器發1號,對應的短連結為 xx.xxx/1,以此類推。
發號器發出的10進位制號需要轉換成62進位制,這樣可以大大縮短號碼轉換成字串後的長度。比如發號器發出 10,000,000,000 這個號碼,如果不轉換成62進位制,直接拼接在域名後面,得到這樣一個連結 xx.xxx/10000000000。將上面的號碼轉換成62進位制,結果為AOYKUa,長度只有6位,拼接得到的連結為 xx.xxx/AOYKUa。可以看得出,進位制轉換後得到的短連結長度變短了一些。6位62進位制數,對應的號碼空間為626,約等於568億。也就是說發號器可以發568億個號,這個號碼空間應該能夠滿足多數專案的需求了,所以基本上不用擔心發號器無號可發的情況。
上述是發號策略壓縮URL的原理,在實際寫程式碼的過程中還需要考慮很多細節,比如快取,儲存等。本文對應的專案基於 Redis 快取,MySQL 資料庫實現了一個簡單的分散式短連結服務。程式碼放到了 Github 上了 -> 分散式短連結專案程式碼

 

4. 幾個細節問題


Q:同一長連結,每次轉成的短連結是否一樣

A:同一長連結,每次轉成的短連結不一定一樣,原因在於如果查詢快取時,如果未命中,發號器會發新號給這個連結。需要說明的是,快取應該快取經常轉換的熱門連結,假設設定快取過期時間為一小時,如果某個連結很活躍的話,快取查詢命中後,快取會重新整理這個連結的存活時間,重新計時,這個連結就會長久存在快取中。對於一些生僻連結,從存入快取開始,在存活時間內很可能不會被再次訪問,存活時間結束快取會刪除記錄。下一次轉換這個生僻連結,快取不命中,發號器會重新發號。這樣一來會導致一條長連結對應多條短連結的情況出現,不僅浪費儲存空間,又浪費發號器資源。那麼是否有辦法解決這個問題呢?是不是可以考慮建立一個長連結-短連結的key-value表,將所有的長連結和對應的短連結都存入其中,這樣一來就實現了長短連結一一對應的了。但是想法是美好的,現實是不行的,原因在於,將所有的長連結-短連結對存入這樣的表中,本身就需要耗費大量的儲存空間,相對於生僻連結可能會對應多條短連結浪費的那點空間,這樣做顯然就得不償失了。

Q:短連結使用301跳轉還是302跳轉

A:這裡囉嗦一下301和302的跳轉在短連結服務使用場景下的區別:使用者第一次訪問某個短連結後,如果伺服器返回301狀態碼,則這個使用者在後續多次訪問統一短連結,瀏覽器會直接請求跳轉地址,而不是短連結地址,這樣一來伺服器端就無法收到使用者的請求。如果伺服器返回302狀態碼,且告知瀏覽器不快取短連結請求,那麼使用者每次訪問短連結,都會先去短連結服務端取回長連結地址,然後在跳轉。從語義上來說,301跳轉更為合適,因為是永久跳轉,不會每次都訪問服務端,還可以減小服務端壓力。但如果使用301跳轉,服務端就無法精確蒐集使用者的訪問行為了。相反302跳轉會導致服務端壓力增大,但服務端此時就可精確蒐集使用者的訪問行為。基於使用者的訪問行為,可以做一些分析,得出一些有意思的結論。比如可以根據使用者IP地址得出使用者區域分佈情況,根據User-Agent訊息頭分析出使用者使用不同的作業系統以及瀏覽器比例等等。

 

參考


https://www.zhihu.com/question/29270034/answer/46446911
http://blog.csdn.net/xyz_lmn/article/details/8057270
http://blog.csdn.net/beiyeqingteng/article/details/7706010