從線報羣看短鏈接技術

(提前申明,此文只談技術,不談運營)

最近疫情嚴重,導致副業搜索量大大的增加。而在機緣巧合之下,接觸到了那種所謂的線報羣。就是一個羣裏,定時會有各種各樣的優惠鏈接之類的。先不說質量如何,低廉的價格就很容易讓人產生看一看的慾望。

於是我百度了一下類似的情況,結果發現,這種名叫“淘寶客”的職業。在不斷的研究和嘗試之後,挖掘了一把更深層次的東西。

(正文開始了)

首先從上圖開始吧,可以看到上圖包含的兩個東西,第一個是所謂的“淘口令”,第二個則是所謂的短鏈接。

其實這兩個東西從理論上來講,是同一個東西。我們可以起一個名字叫做映射。簡單來說,就是在服務端以key-value存儲一個映射關係,key代表短鏈接,value代表長連接。需要的時候,直接通過key獲取到value的值就可以了。

舉例說明:(你可以自己嘗試一下,跳轉位置絕對是一模一樣的)

這個是長鏈接

https://jq.qq.com/?_wv=1027&k=cFU9YWW1

這個是生成後的短鏈接(具有時效性)

http://qq.cn.hn/xHS

大致流程是這樣的:我複製(輸入)了一個長鏈接,通過在線的短鏈接的轉化後得到一個以http://qq.cn.h開頭的短鏈接,然後我可以將該網址在互聯網上進行分享和傳播,其他人在訪問該短網址可以進入到之前原本長網址對應的頁面。

  1. 那麼到底是如何才能壓縮鏈接呢?

常見的短鏈接壓縮算法有兩種:

第一種是對 URL 進行hash運算,在得到的hash值上做進一步運算,得到一個較短的hash值。(這種方式說白了,就是給字符串進行hash加密,然後在得到hash值上再次進行運算,這樣理論上得到了一個長度更短的值,但是這種情況下,URL數量不斷的增加,絕對會增加衝突數量,最終導致一部分用戶跳轉到錯誤的地址上。)

第二種是通過數據庫自增ID或分佈式key-value系統模擬發號器進行發號壓縮URL。(這種方式就比較簡單了,先設置一個發號器,給每一個數據發一個號碼,然後通過這個號碼來映射,你說這個號碼也太簡單了,容易被破解?看下圖,對一個數字進行進制化處理,就能滿足你的條件了,如果還不行,在固定位數加上隨機數字?)

(重頭戲啊)

接下里我講一講,我當時遇到的一些坑。

1.key-value到底應該要怎麼存?

其實這裏我做了兩種方案,一種是redis,一種是mysql。這裏的基本邏輯是,在mysql裏存儲對應的key-value值,然後在redis裏進行緩存處理,畢竟每一個生成的短鏈接都是不會在更改的。

2.發號器該如何設置?

其實這個比較簡單,發號器的作用主要是兩個:1.保障能夠每一次發送唯一的字段,這樣就能保障短鏈直接不會再次衝突。2.保證具有一定的規律性,這樣方便索引。這裏推薦兩種形式吧:

利用數據庫的自增id:這種方式很簡單,流程上講,利用id進行64進制轉換,將轉換後的字段作爲短鏈key。這樣能夠保證key 的唯一性,且不會衝突。這種缺點也很明顯,依賴於數據庫的自增,整體的效率以數據庫的效率爲主。(附上64進制轉換代碼)

/**
* 把10進制的數字轉換成64進制
* 
* @param number
* @param shift
* @return
*/
private static String CompressNumber(long number) {
    char[] buf = new char[64];
    int charPos = 64;
    int radix = 1 << 6;
    long mask = radix - 1;
    do {
        buf[--charPos] = digits[(int) (number & mask)];
        number >>>= 6;
    } while (number != 0);
    return new String(buf, charPos, (64 - charPos));
}

雪花算法(沒有任何兩片雪花是一模一樣的):雪花算法完全高可用,不依賴於數據庫,而且生成數量大,每秒中能生成數百萬的自增ID。而且也具有自增id,存入數據庫中,索引效率高。但是這種方法依賴時間,而且長度一般爲64位,雖然有一定的變種,但是短鏈長度仍舊很難把握。

3.併發情況下,如何提高效率。

目前高併發情況下,單一的線程很難跟得上發號問題,因此提出了2種辦法。

第一種,預先發號。簡單來說,每次發1000個號,放到redis裏進行提前存儲,然後每次需要號時候,去redis直接提取。這樣就免除了數據庫的效率限制。依次類推,我們可以實現1000個邏輯發號器,分別髮尾號爲0到999的號。每發一個號,每個發號器加1000,而不是加1。這些發號器獨立工作,互不干擾即可。而且在實現上,也可以先是邏輯的,真的壓力變大了,再拆分成獨立的物理機器單元。1000個節點,估計對人類來說應該夠用了。如果你真的還想更多,理論上也是可以的。

第二種,redis緩存。將一些常用的key-value值進行緩存,這樣能夠保證加載的速度。有常用的,那麼就有不常用的。設計要給淘汰機制,然後把不常用的淘汰掉,剩下的就是常用的了。

 

更多信息,可以關注【計算機俱樂部】!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章