最通俗易懂的短鏈接原理講解

看業務代碼的時候,有些邏輯用到了短鏈接服務,感覺還蠻有意思的,這裏簡單的記錄一下。

這種營銷短信大家應該都收到過,短信有最大字符限制,而且爲了更好的觀感體驗,短信裏的鏈接一般都很短。現成的短鏈接生成服務也比較多,比如新浪百度等,谷歌之前也有短鏈接服務,號稱是最快的,但是在 2018 年關閉了。

一、短鏈接原理

我們點擊短鏈接會發起一個 GET 方式的 HTTP 請求,當請求到對應的 API 後,會解析短鏈接裏的標識獲取到對應的長鏈接,然後重定向到長鏈接,這樣整個流程就結束了。

比如我用新浪的短鏈接服務爲 https://www.google.com/ 生成了一個短鏈接:http://dwz.date/evn,下面是請求短鏈接時對應的 HTTP 信息:

二、短鏈接生成算法

短鏈接標識一般是 [0-9, a-z, A-Z] 隨機組合而成的字符串,字符一共有 62 個,因此短鏈接標識可以用 62 進制的字符串表示。

首先維護一個自增的 ID,當生成短鏈接時,將 10 進制的自增 ID 轉換成 62 進制字符串,這個字符串就可以唯一標識一個長鏈接。由於 ID 是自增的,對應的 62 進制字符串是不同的,這樣就不會出現一個短鏈接對應多個長鏈接的問題,62 個字符排列組合,可以保證短鏈接是用不完的,就算僅限於 6 位長度標識的短鏈接,也有 558 億多種情況,這種算法在網上被稱爲自增序列算法。

維護自增 ID 主要有以下幾種方式:

  1. 數據庫主鍵自增
  2. redis 自增
  3. 分佈式自增主鍵 ID(雪花算法,存在 ID 浪費)

下面是 62 進制的 encode 與 decode 方法,來自 Base62

    private static String base62(Long b10) {
        StringBuilder ret = new StringBuilder();
        while (b10 > 0) {
            ret.insert(0, characters.charAt((int) (b10 % 62)));
            b10 /= 62;
        }
        return ret.toString();
    }

    private static long decodeBase62(String b62) {
        long ret = 0;
        b62 = new StringBuffer(b62).reverse().toString();
        long count = 1;
        for (char character : b62.toCharArray()) {
            ret += characters.indexOf(character) * count;
            count *= 62;
        }
        return ret;
    }

三、一些細節

  1. 自增序列算法也存在一定的缺點,當自增主鍵很大時,生成的 62 進制字符串會變長,以 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 順序的 62 進製爲例,當主鍵大於 56800235583 時,會生成 7 位長度的 62 進制字符串。這個問題可以通過控制自增主鍵的增長速度來解決,而且要避免主鍵浪費。
  2. 62 進制的順序並不一定嚴格按照 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 的順序來表示,這個順序可以是打亂的,這樣生成的短鏈接標識更隨機不易被破解。
  3. 長鏈接與短鏈接是否需要一對多關係,同一個長鏈接使用自增主鍵 ID 算法生成的短鏈接是不同的,因爲自增主鍵 ID 不同,生成的 62 進制字符串自然也不同。如果我們有一個長鏈接唯一對應一個短鏈接需求,可以將長鏈接進行 md5 加密,將加密後的 md5 值存儲在 DB 中,每次生成短鏈接前都根據長鏈接 md5 值查詢 DB,如果存在,則直接返回短鏈接,當然也可以使用其他方式維護這種關係。
  4. 跳轉用 301 還是 302,301 永久重定向,302 是臨時重定向。短地址一經生成就不會變化,所以用 301 是符合 http 語義的。同時對服務器壓力也會有一定減少。
    但是如果使用了 301,我們就無法統計到短地址被點擊的次數了。而這個點擊次數是一個非常有意思的大數據分析數據源。能夠分析出的東西非常非常多。所以選擇 302 雖然會增加服務器壓力,但是我想是一個更好的選擇。from 短 URL 系統是怎麼設計的? by iammutex
  5. 如果短鏈接請求頻繁,可以藉助 redis 做對應的緩存優化。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://blog.csdn.net/codejas/article/details/106102452