一個go語言實現的短鏈接服務
短連接的原理
很多人一定想的是短連接是通過一定的算法將長鏈接變成短連接的,然后訪問的時候再還原,恩,非常高大上,但是仔細想想,怎么可能,那得多牛逼的壓縮算法,多長的url都可以壓縮為幾個字節,而且還能還原,還是無損壓縮。
所以,實際上,短連接生成核心就兩個字:數數,就是不停的自增一個數,然后有個表保存每個數和原始鏈接的對應關系,訪問短連接的時候將原是連接取出來。
知道了原理就好弄了,最簡單的辦法,就是用一個數組來存儲,數組的索引就是短鏈接,數組的值就是原始鏈接,恩,完美,由于數組下標是短鏈接,那么獲取短鏈接的時間復雜度是O(1),同時生成短鏈接的時間復雜度也是O(1)
短鏈接服務的實現
實現一個短鏈接服務,用數組固然可能,但也顯得太LOW了吧,所以為了實現這個服務,從以下幾個部分來實現。
首先,給兩個概念
- 解析短鏈接,就是請求是短連接,返回一個跳轉的原始鏈接
- 生成短鏈接,就是有個長鏈接,返回生成的短鏈接 </ul>
存儲
持久化的部分使用Redis數據庫來實現,很明顯,key-value的結構很適合存在Redis中這部分主要在 shortlib/RedisAdaptor.go中
計數器
數數的功能可以用Redis的自增功能實現,這樣也保證了原子性,同樣這部分也可以自己實現,因為go語言開線程很容易,專門開一個線程實現這個功能,通過channl來接受請求,保證是串行的就行了,不就是數數嘛,大家都會這部分在shortlib/RedisAdaptor.go和shortService/CountThread.go中,具體實現的時候通過配置文件的參數,返回一個高階函數,調用的時候自動分配到不同的函數實現。
緩存服務
Redis固然很快,但是我們還需要更快,要是熱門數據存在內存中就更快了,而且還有個問題,就是熱門的url要是有人不停的申請短連接會造成浪費,為了防止這個問題,自己實現了一個LRU模塊,解析短鏈接的時候,命中了話直接返回結果,否則從Redis返回數據,如果是申請短鏈接的話,如果在 LRU中,那不再重新生成短鏈接了。這部分主要在 shortlib/LRU.go中。
對外服務
這一部分用的go的http框架,很容易實現高并發,沒啥好說的,現在編程高并發不是問題了,連語言都自帶這框架了。這部分包括shortlib/Router.go , shortService/OriginalProcessor.go,shortService/ShortProcessor.go 這幾個文件。
https://github.com/wyh267/shortService