短地址实现

网上的实现思路问题

目前博客大部分都是使用的hash算法,通过算法把长地址进行压缩,转换为一个很短的字符串。这种实现有什么问题呢?大家都明白,一个短地址不可能完全匹配所有的长地址,MD5在大运算下都会产生碰撞,更何况很短的几个字符串(本人就是用这种方法,数据在一万多条的时候发生了碰撞)。后参考一遍博客,决定使用本文的方式进行实现,将短地址的碰撞的可能性降至更低,本文实现使用md5作为匹配字段,在日常应用中基本不会发生碰撞。

说明

目前项目存在一个缺陷,浏览器创建短地址,url后面的参数无法接收,暂时请大家使用ajax的方式创建,这样可以保存完整的url(包括参数)
欢迎大家在博客留言,共同讨论附加的功能
暂时代码为开源,等项目完善后开源

已经搭建公共的短地址服务器,供各位使用

接口文档

  • 创建短地址:http://urlzz.cn/create
    • 参数:url:原地址完整的URL
    • 返回:短地址链接。例:http://urlzz.cn/wn
  • 短地址使用:在浏览器输入http://urlzz.cn/wn短地址,即可转跳原地址

短地址实现思路

本博文参考网上的一些博客,以及实现思路,最终确定的一个实现方法

  • 生成:
    • 长url进行md5加密,获得64位字符串
    • 将加密串和原地址写入数据库,并获得自增id
    • 将id的十进制数字转为62位进制字符串,得到短地址key
    • 将key作为标识,组合短地址域名前缀,返回短地址
  • 查询:
    • 将key转回10进制
    • 根据id进行查询

测试用到的工具类性能

  • md5加密性能

    • 性能 1000000/秒 (测试环境,mac pro 15.5 2015 i7 16G)
    • 数据长度几乎无影响,1-100个字符,1000000/秒
    • 数据长度几乎无影响,100-200个字符,800000/秒
    • 数据长度几乎无影响,200-400个字符,500000/秒
  • 10进制转62进制

    • 性能:20000000/秒 (测试环境,mac pro 15.5 2015 i7 16G)
    • 数据大小,几乎对性能无影响(1000000000000L)(转换结果为:hBxM5A4)
  • 62进制转10进制

    • 性能:5000000/秒 (测试环境,mac pro 15.5 2015 i7 16G)
    • 数据大小,几乎对性能无影响(hBxM5A4)(转换结果为:1000000000000)

通过测试得出,最终的性能瓶颈还是在数据库

未来考虑的优化方案

  • 查询使用redis缓存
  • 布隆过滤器过滤无效key
  • 插入使用redis暂存,使用mq做削峰填谷(需要保证服务器的可靠性)
  • 做限流,禁止同一台设备短时间大批量创建短地址

NGINX跨域设置

#   指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;
#   预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
#   带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
#   表示允许这个域跨域调用(客户端发送请求的域名和端口)
#   $http_origin动态获取请求客户端请求的域   不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;
#   表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;
#   OPTIONS预检命令,预检命令通过时才发送请求
#   检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
    return 200;
}

前端代码

前端代码可直接执行,后台nginx做了跨域处理
请注意,为了项目更高的并发,没有做任何多余的封装,所以短地址返回的只要一个字符串,ajax接收时,dataType要设置为text

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>短地址生成</title>
        <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
	</head>
	<body>
	</body>
    <script type="text/javascript">
        $(function(){
           $.ajax({
               type: 'get',
               url: "http://urlzz.cn/create",
               data: {"url": "http://www.byshop.ren?test=test&test1=test1"},
               dataType: 'text',
               timeout: 60000,
               success: function(res) {
                   console.log(res)
               }
           })
        })
    </script>
</html>
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot是一个开源的Java框架,可以简化Java应用程序的开发。它提供了很多方便的功能,可以帮助我们快速构建稳定可靠的应用程序。 要实现生成和统计,可以借助SpringBoot的特性和第三方库来完成。以下是一个基本的实现思路: 1. 生成 首先,我们需要设计一个用于生成链的算法或方法。常见的方法是将长链接通过哈希算法转换为字符串。你可以选择使用MD5、SHA1等哈希算法,并取其中一部分字符作为链接。另外,为了避免生成过长的链,可以将其进一步进行压缩。 在SpringBoot中,可以通过创建一个生成链的Controller来实现。Controller接收长链接作为参数,调用生成的方法,然后将生成链接返回给前端。 2. 链重定向 当用户点击链接时,服务器需要将其重定向到原始的长链接地址。可以在SpringBoot中创建一个Controller,设置一个路由映射,并在该Controller中获取链接对应的长链接,然后进行重定向。 3. 统计链点击量 为了统计链的点击量,我们可以在数据库中创建一个表,用于记录链的相关信息,例如链、长链接、点击次数等。 在SpringBoot中,可以定义一个点击事件的Controller,当用户点击链时,将触发该Controller。该Controller负责将点击事件信息保存至数据库,并更新链对应的点击次数。 以上是一个基本的实现思路,你可以根据具体需求和场景进行进一步的优化和改进。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值