Java生成短網址|短鏈接


Java生成短鏈接 (文章)
https://www.cnblogs.com/xijin-wu/p/8483649.html
https://www.seoxiehui.cn/article-156919-1.html
https://search.gitee.com/?skin=rec&type=repository&q=%E7%9F%AD%E7%BD%91%E5%9D%80&repo=&reponame=&lang=java

 


Java netcore
1. Wei.TinyUrl
https://github.com/a34546/Wei.TinyUrl

1.1shorturl
https://github.com/wjup/shorturl

2. ShortURL
https://github.com/zhaopeiym/ShortURL

3.基於JavaFx搭建的實用小工具集合
https://github.com/864381832/xJavaFxTool

4.Alkaids/shortcut   ***
https://github.com/Alkaids/shortcut

 

 ******************************************************************************************************************************************

1.Twitter的分布式雪花算法 SnowFlake 每秒自增生成26個萬個可排序的ID (Java版)
https://blog.csdn.net/yanpenglei/article/details/79542768

2.Twitter的雪花算法(snowflake)自增ID
https://www.cnblogs.com/jifeng/p/9802142.html

*******************************************************************************************************************************************

__________________________________________________________________________________________________

在知乎看到這篇貼子談論短地址生成的方法。 主要步驟為兩個:

  • 實現一個不會重復的發號器
  • 每個新的請求都給它一個新的號碼,轉換成62進制,62進制是帶有阿拉伯數字,英文大小寫的格式,比較適合作為短地址的 url.

發號器

直接不造輪子了,用 Twitter 的雪花算法。

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 
  • 1位標識,由於long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0
  • 41位時間截(毫秒級) 一般來說這個時間能夠使用69年.
  • 10位的數據機器位,可以部署在1024個節點
  • 12位序列,毫秒內的計數,12位的計數順序號支持每個節點每毫秒(同一機器,同一時間截)產生4096個ID序號
  • 加起來剛好64位,為一個Long型。

進制轉換

通過上述發號器得到的Long類型的數據,轉換為62進制,比如

6628238651141500928

轉換為

7TDp0rS917i

下面這個字符串就是需要的短地址。

重定向

通過 curl -i http://127.0.0.1:9527/7TDhjcamrAI 應用會匹配末端的字符串,去redis里面拿到url,然后通過狀態碼 302 重定向即可。

二維碼生成

使用 Google 的 zxing 做的二維碼轉換,詳細代碼可參考這里

性能測試

使用 JMH 做性能基准測試,環境為 CPU: 2.2 GHz Intel Core i7; Memory: 16 GB; OS: Mac OSX

 Options options = new OptionsBuilder().include(BenchmarkTest.class.getName()+".*")
                .warmupIterations(1) // 預熱
                .warmupTime(TimeValue.seconds(1))
                .measurementIterations(5)// 一共測試10輪
                .measurementTime(TimeValue.seconds(5))// 每輪測試的時長
                .forks(1)// 創建幾個進程來測試
                .threads(16)// 線程數
                .build();

測試結果如下:

Benchmark                      Mode  Cnt    Score    Error  Units
BenchmarkTest.httprequest     thrpt    5  1948.349 ± 2028.032  ops/s
BenchmarkTest.serviceRequest  thrpt    5  3945.100 ± 1185.980  ops/s
  1. httprequest 是通過 okhttp 構造 post 請求,直接請求本地前端控制方法。qps 大概 2000 左右。
  2. serviceRequest 是直接調用本地方法服務得到短地址,qps 大概是 http 測試的兩倍,有 4000 左右,比較理想。

進一步的優化空間可以關注一下進制轉換部分,有不必要的基本類型轉換。

____________________________________________________________________________________________________________________________

 

原理:

Ø  通過發號策略,給每一個請求的長地址分配一個唯一編號,小型系統直接利用數據庫的自增主鍵就可以。

Ø  如果大型應用,可以考慮實現分布式發號器,不斷自增就行。第一個使用這個服務的人得到的短地址是http://www.shururl.com/0 第二個是 http:// www.shururl.com /1 第10個是 http://www.shururl.com /a 第依次往后.

 

實現處理流程:

 

A.   核心步驟:

  • 實現唯一發號器.
  • 每個請求獲取一個唯一編號,轉換成62進制,62進制是由 英文字母(大小寫)、阿拉伯數字等格式組合,作為短地址的短碼.

B.        發號器規則:

計算的來源思路: Twitter 雪花算法

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 
  • 1位標識,由於long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0.
  • 41位時間截(毫秒級) 這個是毫秒級的時間,一般實現上不會存儲當前的時間戳,而是時間戳的差值(當前時間-固定的開始時間),這樣可以使產生的ID從更小值開始;41位的時間戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年;
  • 5位的數據中心,可以存在在32個數據中心
  • 5位的機器位,每1個數據中心可以部署32個節點
  • 12位序列號,毫秒內的計數,12位的計數順序號支持每個節點每毫秒(同一機器,同一時間截)產生4096個ID序號
  • 加起來剛好64位,為一個Long型。

C.        進制轉換:

通過上述發號器得到的Long類型的數據,轉換為62進制,比如:6628238651141500928  轉換為: 7TDp0rS917i 下面這個字符串就是需要的短地址,http://127.0.0.1/7TDp0rS917i

 

 

 

 

詳細思路: 

1.      根據發號器的數量,在mongo中建立一張表

 

發號器Id

發號器名稱

機器標識

數據中心標識[LP3] 

應用描述信息

XXX

1號發號器

1

1

Desc.

XXX

2號發號器

2

1

Desc.

XXX

3號發號器

3

1

Desc

XXX

1號發號器

1

2

Desc

XXX

2號發號器

2

2

Desc

指定數據中心的發號器的個數,及配置信息相關.

 

2.      根據上面[實現處理流程-B的處理思路:

1符號位+41位時間截+5位的數據中心位+5位的機器位+12位序列號=64位,一個Long型.

 

3.  將2步計算獲取的10進制數字轉換為62用如:數字10000給它的短地址對應的編號是9999,我們將通過雪花算法獲取的9999,做一個10進制到62進制的轉換。

 

4.      解決發號器的大並發高可用問題,就是將發號器做成分布式,那么多節點要保持同步加1,根據CAP的理論,多點同時寫入保證一致性(Consistency),是不可能真正做到的。解決辦法: 可以實現多個發號器,根據上面的原則我們可以實現32個邏輯發號器,分別發尾號為0到31的號。每發一個號,在5位機器號的基礎上,不斷加1,這些發號器互相獨立,互不干擾。

 

5.      跳轉用301還是302。301是永久重定向,302是臨時重定向。短地址一經生成就不會變化,所以用301是符合http語義的。同時對服務器壓力也會有一定減少。但是如果使用了301,我們就無法統計到短地址被點擊的次數了。而這些信息的捕捉,是數據分析的重要來源。雖然302會增加服務器壓力,但卻是一個最好的選擇。

 


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM