Skip to content

jaycGong/sequoiacapJavaAssignment

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

主要步骤为两个:

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

下面这个字符串就是需要的短地址。

重定向 通过 curl -i http://127.0.0.1:9527/7TDhjcamrAI 应用会匹配末端的字符串,去redis里面拿到url,然后通过状态码 302 重定向即可。

性能测试 使用 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)// 一共测5轮
.forks(1)// 创建1个进程来测试
.threads(10)// 线程数
.build();
                

测试结果如下:

# Fork: 1 of 1
# Warmup Iteration   1: 1310.917 ops/s
Iteration   1: 882.723 ops/s
Iteration   2: 697.985 ops/s
Iteration   3: 543.681 ops/s
Iteration   4: 76.458 ops/s
Iteration   5: 56.504 ops/s


Result "com.java.assignment.AppBenchMark.forIndexIterate":
  451.470 ±(99.9%) 1430.300 ops/s [Average]
  (min, avg, max) = (56.504, 451.470, 882.723), stdev = 371.444
  CI (99.9%): [≈ 0, 1881.770] (assumes normal distribution)

Benchmark                      Mode  Cnt           Score           Error  Units
AppBenchMark.longToShort   thrpt    5        4212.848 ±     6263.858  ops/s
AppBenchMark.shortToLong  thrpt    5         451.470 ±      1430.300  ops/s

longToShort 是通过 JMH 直接请求本地方法。dasd100,qps 大概 4000 左右。

shortToLong 是直接调用本地方法服务得到短地址,qps 450 左右,比较理想。

进一步的优化空间可以关注一下进制转换部分,有不必要的基本类型转换。

原理:

Ø 通过发号策略,给每一个请求的长地址分配一个唯一编号,小型系统直接利用数据库的自增主键就可以。

Ø 如果大型应用,可以考虑实现分布式发号器,不断自增就行。第一个使用这个服务的人得到的短地址是http://www.shururl.com/0 第二个是 http:// www.shururl.com /1 第10个是 http://www.shururl.com /a 第依次往后.

增加自定义注解来控制api每秒请求次数,防止攻击

原理:令牌桶

  // 此处设置的是1秒内运行访问10次
    @CurrentLimit(count = 10, timespan = 1)
    @ApiOperation(value = "域名存储", notes = "接受长域名信息,返回短域名信息")
    @GetMapping("/longToShort")

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages