我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于Java设计一个短链接生成系统

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于Java设计一个短链接生成系统

引言

相信大家在生活中,特别是最近的双十一活动期间,会收到很多短信,而那些短信都有两个特征,第一个是几乎都是垃圾短信,这个特点此处可以忽略不计,第二个特点是链接很短,比如下面这个:

我们知道,短信有些是有字数限制的,直接放一个带满各种参数的链接,不合适,另外一点是,不想暴露参数。好处无非以下:

  • 太长的链接容易被限制长度
  • 短链接看着简洁,长链接看着容易懵
  • 安全,不想暴露参数
  • 可以统一链接转换,当然也可以实现统计点击次数等操作

那背后的原理是什么呢?怎么实现的?让你实现这样的系统,你会怎么设计呢?【来自于某鹅场面试官】

短链接的原理

短链接展示的逻辑

这里最重要的知识点是重定向,先复习一下http的状态码:

分类 含义
1** 服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

那么以 3 开头的状态码都是关于重定向的:

  • 300:多种选择,可以在多个位置存在
  • 301:永久重定向,浏览器会缓存,自动重定向到新的地址
  • 302:临时重定向,客户端还是会继续使用旧的URL
  • 303:查看其他的地址,类似于301
  • 304:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。
  • 305:需要使用代理才能访问到资源
  • 306:废弃的状态码
  • 307:临时重定向,使用Get请求重定向

整个跳转的流程:

1.用户访问短链接,请求到达服务器

2.服务器将短链接装换成为长链接,然后给浏览器返回重定向的状态码301/302

301永久重定向会导致浏览器缓存重定向地址,短链接系统统计访问次数会不正确

302临时重定向可以解决次数不准的问题,但是每次都会到短链接系统转换,服务器压力会变大。

3.浏览器拿到重定向的状态码,以及真正需要访问的地址,重定向到真正的长链接上。

从下图可以看出,确实链接被302重定向到新的地址上去,返回的头里面有一个字段Location就是所要重定向的地址:

短链接怎么设计的

全局发号器

肯定我们第一点想到的是压缩,像文件压缩那样,压缩之后再解压还原到原来的链接,重定向到原来的链接,但是很不幸的是,这个是行不通的,你有见过什么压缩方式能把这么长的数字直接压缩到这么短么?事实上不可能。就像是Huffman树,也只能对那种重复字符较多的字符串压缩时效率较高,像链接这种,可能带很多参数,而且各种不规则的情况都有,直接压缩算法不现实。

那https://dx.10086.cn/tzHLFw与https://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?channel=之间的装换是怎么样的呢?前面路径不变,变化的是后面,也就是tzHLFw与gmccapp/webpage/payPhonemoney/index.html?channel=之间的转换。

实际也很简单,就是数据库里面的一条数据,一个id对应长链接(相当于全局的发号器,全局唯一的ID):

id url
1 gd.10086.cn/gmccapp/web…

这里用到的,也就是我们之前说过的分布式全局唯一ID,如果我们直接用id作为参数,貌似也可以:https://dx.10086.cn/1,访问这个链接时,去数据库查询获得真正的url,再重定向。

单机的唯一ID很简单,用原子类AtomicLong就可以,但是分布式的就不行了,简单点可以用 redis,或者数据库自增,或者可以考虑Zookeeper之类的。

id 转换策略

但是直接用递增的数字,有两个坏处:

  • 数字很大的时候,还是很长
  • 递增的数字,不安全,规律性太强了

明显我们平时看到的链接也不是数字的,一般都是大小写字母加上数字。为了缩短链接的长度,我们必须把id转换掉,比如我们的短链接由a-z,A-Z,0-9组成,相当于62进制的数字,将id转换成为62进制的数字:


public class ShortUrl {
 
    private static final String BASE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
    public static String toBase62(long num) {
        StringBuilder result = new StringBuilder();
        do {
            int i = (int) (num % 62);
            result.append(BASE.charAt(i));
            num /= 62;
        } while (num > 0);
 
        return result.reverse().toString();
    }
 
    public static long toBase10(String str) {
        long result = 0;
        for (int i = 0; i < str.length(); i++) {
            result = result * 62 + BASE.indexOf(str.charAt(i));
        }
        return result;
    }
 
    public static void main(String[] args) {
        // tzHLFw
        System.out.println(toBase10("tzHLFw"));
        System.out.println(toBase62(27095455234L));
    }
}

id转 62位的key 或者key装换成为id都已经实现了,不过计算还是比较耗时的,不如加个字段存起来,于是数据库变成了:

id key url
27095455234 tzHLFw gd.10086.cn/gmccapp/web…

但是这样还是很容易被猜出这个id和key的对应关系,要是被遍历访问,那还是很不安全的,如果担心,可以随机将短链接的字符顺序打乱,或者在适当的位置加上一些随机生成的字符,比如第1,4,5 位是随机字符,其他位置不变,只要我们计算的时候,将它对应的关系存到数据库,我们就可以通过连接的key找到对应的url。(值得注意的是,key必须是全局唯一的,如果冲突,必须重新生成)

一般短链接都有过期时间,那么我们也必须在数据库里面加上对应的字段,访问的时候,先判断是否过期,过期则不给予重定向。

性能考虑

如果有很多短链接暴露出去了,数据库里面数据很多,这个时候可以考虑使用缓存优化,生成的时候顺便把缓存写入,然后读取的时候,走缓存即可,因为一般短链接和长链接的关系不会修改,即使修改,也是很低频的事情。

如果系统的id用完了怎么办?这种概率很小,如果真的发生,可以重用旧的已经失效的id号。

如果被人疯狂请求一些不存在的短链接怎么办?其实这就是缓存穿透,缓存穿透是指,缓存和数据库都没有的数据,被大量请求,比如订单号不可能为-1,但是用户请求了大量订单号为-1的数据,由于数据不存在,缓存就也不会存在该数据,所有的请求都会直接穿透到数据库。如果被恶意用户利用,疯狂请求不存在的数据,就会导致数据库压力过大,甚至垮掉。

针对这种情况,一般可以用布隆过滤器过滤掉不存在的数据请求,但是我们这里id本来就是递增且有序的,其实我们范围大致都是已知的,更加容易判断,超出的肯定不存在,或者请求到的时候,缓存里面放一个空对象也是没有问题的。

到此这篇关于基于Java设计一个短链接生成系统的文章就介绍到这了,更多相关Java短链接生成系统内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于Java设计一个短链接生成系统

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么用Java设计一个短链接生成系统

这篇文章主要讲解了“怎么用Java设计一个短链接生成系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java设计一个短链接生成系统”吧!引言相信大家在生活中,特别是最近的双十一活动期
2023-06-22

基于JavaSwing+mysql开发一个学生社团管理系统设计和实现

前言: 项目是使用Java swing+mysql开发,可实现基础数据维护、用户登录注册、社团信息列表查看、社团信息添加、社团信息修改、社团信息删除以及退出注销等功能、界面设计比较简单易学、适合作为Java课设设计以及学习技术使用。 引言
2022-05-11

基于java的学生宿舍管理系统设计与实现

基于java的学生宿舍管理系统设计与实现 I. 引言 A.研究背景和动机 研究背景: 随着高校规模的不断扩大和管理的日益复杂,学生宿舍管理成为高校管理的一个重要环节。传统的手工管理方式已经无法满足高校对学生宿舍管理的需求,因此,基于Java
基于java的学生宿舍管理系统设计与实现
2023-12-23

Java如何基于以微秒计的当前时间,生成一个唯一的 ID

利用Java生成基于微秒计当前时间的唯一ID有多种方法。System.currentTimeMillis()提供毫秒级精度,但非唯一;Instant.now()具有纳秒级精度,但唯一性中等;UUID具有128位随机性,唯一性高;ThreadLocalRandom.current().nextInt()提供快速生成整数,但唯一性较低。选择方法取决于应用需求:精度、唯一性和性能。
Java如何基于以微秒计的当前时间,生成一个唯一的 ID
2024-04-02

基于SSM试卷自动生成系统设计与实现是怎样的

这篇文章将为大家详细讲解有关基于SSM试卷自动生成系统设计与实现是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。功能点: 1.后台管理员能够对用户管理,用户批量导入,用户组管理,角色管
2023-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录