工作这么久了,你应该知道的短链接架构设计

本文介绍了短链接的必要性及其实现流程,包括用户输入长链接获取短链接、通过短链接进行重定向。在关键问题剖析中,讨论了缩短链接的算法,如使用自增ID、16进制和62进制转换,并提到了重定向方式的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


如果我们在平时的沟通中发送个这么长的玩意你说它裂不裂开,所以市面上就有了很多短链接生成器应运而生。

在这里插入图片描述

看到没,直接把又臭又长的url,搞成了短小精悍型的。

在浏览器输入https://t.1yb.co/bo6a会跳转到上面的网页。

为什么使用短链接


说几个理由吧

  • 在浏览器输入url的时候,肯定需要越短越好啊

  • 如果需要在内存或者db中存储url,那肯定越短越好啊

  • url沟通传输中还可以隐藏了一部分参数,对不对

短链接如何实现


实现流程如下

  • 1.先是用户输入长连接去缩短链接,返回一个短链接给用户

  • 2.然后用户在浏览器地址输入短链时,根据短链接重定向跳转到长连接网址

在这里插入图片描述

即相应的设计2个接口:

  • 【缩短链接接口】/api/short?longurl=xxx

  • 【重定向接口】/{shorturl}

关键问题剖析

我们这里仅仅是拿在实现中,比较有难点或者争论的地方来阐述。

1. 缩短链接的算法

1、我首先想到的就是用UUID全局唯一特性来实现一一映射长连接。

效果如下

| shorturl | longurl |

| — | — |

| fc5bc4b050ec4b2a9cfb697786f6e9e8 | https://www.baidu.com/abcdefg?key=7387746869684555 |

| fssdff83ikf8ec41239cfb69sdffeegakhj | https://www.baidu.com/abcdefg?key=7ksjkkldoiueell;g;aa |

但是这个是32个字符,实现的短链效果如下:http://url.cn/fc5bc4b050ec4b2a9cfb697786f6e9e8,不是很理想啊。

2、然后就想着是不是可以使用数据库自增的id来实现。

效果如下:

| shorturl | longurl |

| — | — |

| 1 | https://www.baidu.com/abcdefg?key=7387746869684555 |

| … | … |

| 100000000 | https://www.baidu.com/abcdefg?key=7ksjkkldoiueell;g;aa |

实现的短链效果如下:http://url.cn/1,刚开始的时候是短,但是随着数据量的增加也容易裂开啊,例如:当有一亿映射的时候,地址就变成这样了http://url.cn/100000000,这种长度也很长,而且看起来怪怪的。

3、上面的问题是用10进制表示大数字比较长,那么我们可以改用熟悉的16进制来表示大数字,缩短长度啊

一亿10进制表示为:100000000,用16进制表示为:5f5e100

我们可以用:http://url.cn/5f5e100来代替:http://url.cn/100000000,这看起来可就美滋滋了

效果如下:

| shorturl | longurl |

| — | — |

| 1 | https://www.baidu.com/abcdefg?key=7387746869684555 |

| … | … |

| 5f5e100 | https://www.baidu.com/abcdefg?key=7ksjkkldoiueell;g;aa |

4、但是随着数据量的不断增大16进制字符串也会很长啊,治标不治本裂开。。。

例如:当数据到达200亿的时候,16进制为:4a817c800(9位)

我们知道16进制使用的字符有0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f这16个字符,那么我们能不能选用,进制位更多的32进制来表示呢?那么生成的短链接字符串位数就更短了不是吗?

当然可以了,32进制使用0-9、a-z,抛去 ilou4个字符,共32个字符来表示的,那么我们既然都走到这儿了,为什么不用更多的字符来表示呢,对不对。

我们直接使用常见的0-9、a-z、A-Z ,即10字符+26字符+26字符=62个字符的62进制来表示吧,这也是很多短链接生成器选择的算法

例如:还是200亿62进制表示为:lPvXDa(6位)

那么问题转换为只要实现 62进制和10进制的互转即可

private String ALPHABET = “0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”;

// 10进制转62进制

private static String encoding(long num) {

if(num < 1)

throw new IllegalArgumentException(“num must be greater than 0.”);

StringBuilder sb = new StringBuilder();

for (; num > 0; num /= 62) {

sb.append(ALPHABET.charAt((int) (num % 62)));

}

return sb.toString();

}

// 62进制转10进制

private static long decoding(String str) {

if(str==null || str.trim().length() == 0 ){

throw new IllegalArgumentException(“str must not be empty.”);

}

long result = 0;

for (int i = 0; i < str.length(); i++) {

result += ALPHABET.indexOf(str.charAt(i)) * Math.pow(62, i);

}

return result;

}

  • 细看下代码你就知道了,字符串的位置是可以随便调整的.

  • 那么又有人说了,我在加上字符串+-是不是就是64位了,那必须可以啊。。。

那么我们用这个62进制来看看效果,例如:我们想用最长6位字符来表示短链接,那么6位62进制是能容纳多少数据。

62^6

56 800 235 584

答案是:500多亿,这基本就够用了啊,如果还不够用,那么可以增加字符位数,例如8位,或者换更大的进制数。

2. 重定向方式

为什么会提到重定向方式呢,当然是写文章的时候看到别人的提出的问题了哈哈!

先看看官方解释:

重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)。

常用的重定向方式有:

  • 301 Moved Permanently

描述 状态码301表示永久重定向

场景 网址永久变更

  • 302 Moved Temporarily

描述 状态码302表示临时重定向

场景 网址(资源)临时变更,特别是在Oauth、单点登录等过程中,被大量使用

果然很官方,基本上就是介绍生硬的概念,看不懂哈哈,下面我来通过实践翻译一波这个鸟知识点。

我们常用的Servlet重定向api如下:

httpServletResponse.sendRedirect(redirectUrl);

我用下面的代码测试下,看结果:

@RequestMapping(“/”)

public void redirect(HttpServletResponse httpServletResponse, String url) throws IOException {

httpServletResponse.sendRedirect(url);

System.out.println(url);

}

浏览器访问:http://localhost:8080?url=https://www.baidu.com

浏览器访问3次结果如下:

https://www.baidu.com

https://www.baidu.com

https://www.baidu.com

我们可以看下重定向实现原理

org.apache.catalina.connector.Response 这个类的 sendRedirect(String location, int status)方法,有兴趣的可以去自己看看哦

public static final int SC_FOUND = 302;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

小编在这里分享些我自己平时的学习资料,由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

程序员代码面试指南 IT名企算法与数据结构题目最优解

这是” 本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一-痛点, 本书选取将近200道真实出现过的经典代码面试题,帮助广“大程序员的面试准备做到万无一失。 “刷”完本书后,你就是“题王”!

image.png

《TCP-IP协议组(第4版)》

本书是介绍TCP/IP协议族的经典图书的最新版本。本书自第1版出版以来,就广受读者欢迎。

本书最新版进行」护元,以体境计算机网络技不的最新发展,全书古有七大部分共30草和7个附录:第一部分介绍一些基本概念和基础底层技术:第二部分介绍网络层协议:第三部分介绍运输层协议;第四部分介绍应用层协议:第五部分介绍下一代协议,即IPv6协议:第六部分介绍网络安全问题:第七部分给出了7个附录。

image.png

Java开发手册(嵩山版)

这个不用多说了,阿里的开发手册,每次更新我都会看,这是8月初最新更新的**(嵩山版)**

image.png

MySQL 8从入门到精通

本书主要内容包括MySQL的安装与配置、数据库的创建、数据表的创建、数据类型和运算符、MySQL 函数、查询数据、数据表的操作(插入、更新与删除数据)、索引、存储过程和函数、视图、触发器、用户管理、数据备份与还原、MySQL 日志、性能优化、MySQL Repl ication、MySQL Workbench、 MySQL Utilities、 MySQL Proxy、PHP操作MySQL数据库和PDO数据库抽象类库等。最后通过3个综合案例的数据库设计,进步讲述 MySQL在实际工作中的应用。

image.png

Spring5高级编程(第5版)

本书涵盖Spring 5的所有内容,如果想要充分利用这一领先的企业级 Java应用程序开发框架的强大功能,本书是最全面的Spring参考和实用指南。

本书第5版涵盖核心的Spring及其与其他领先的Java技术(比如Hibemate JPA 2.Tls、Thymeleaf和WebSocket)的集成。本书的重点是介绍如何使用Java配置类、lambda 表达式、Spring Boot以及反应式编程。同时,将与企业级应用程序开发人员分享一些见解和实际经验,包括远程处理、事务、Web 和表示层,等等。

image.png

JAVA核心知识点+1000道 互联网Java工程师面试题

image.png

image.png

企业IT架构转型之道 阿里巴巴中台战略思想与架构实战

本书讲述了阿里巴巴的技术发展史,同时也是-部互联网技 术架构的实践与发展史。

image.png
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
企业级应用程序开发人员分享一些见解和实际经验,包括远程处理、事务、Web 和表示层,等等。

[外链图片转存中…(img-J3nM97by-1713662569458)]

JAVA核心知识点+1000道 互联网Java工程师面试题

[外链图片转存中…(img-undKlEYw-1713662569458)]

[外链图片转存中…(img-9sJLQvfG-1713662569459)]

企业IT架构转型之道 阿里巴巴中台战略思想与架构实战

本书讲述了阿里巴巴的技术发展史,同时也是-部互联网技 术架构的实践与发展史。

[外链图片转存中…(img-lH6ZinGH-1713662569459)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值