zoukankan      html  css  js  c++  java
  • 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会增加服务器压力,但却是一个最好的选择。


  • 相关阅读:
    WPF 使用 Direct2D1 画图 绘制基本图形
    WPF 使用 Direct2D1 画图 绘制基本图形
    dot net core 使用 IPC 进程通信
    dot net core 使用 IPC 进程通信
    win2d 图片水印
    win2d 图片水印
    Java实现 LeetCode 240 搜索二维矩阵 II(二)
    PHP closedir() 函数
    PHP chroot() 函数
    PHP chdir() 函数
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/13026529.html
Copyright © 2011-2022 走看看