高性能系统设计:互联网短链接服务

马哥Linux运维

共 3857字,需浏览 8分钟

 ·

2023-08-29 20:02

什么是短链接服务

短链接服务将原本较长的网址转化成较短的网址,从而便于用户的记忆与社交软件上的传播。

假设,我们要做一次简单的营销活动,活动流程大体如下:

  • 首先,将营销落地页,一个较长的 URL ( https://www.glo.com/2021/09/15/ddd/tactics/introduction/#more ) 通过短链接服务转化为一个比较短的 URL( http://glo.com/s );

  • 然后,通过营销渠道将短链接发送给目标用户(比如短信);

  • 在用户获得短链接后,通过链接访问短链接服务。系统接受请求并将请求重定向到原始的长链地址;

  • 最后,用户使用长链地址直接访问目标网站,从而获得最终响应结果。

整体流程如下:

短链接服务的核心流程主要包括 创建短链接 和 访问短链接 。

系统设计要点

短链接服务的核心流程主要围绕 Key 和 Map 进行构建的,如:

  • 创建短链接。首先,生成一个 Key,将长链地址作为 value 保存到 Map 中,然后将短链域名和 key 拼接成短链接,返回给调用方;

  • 访问短链接。服务从 URL 中提取 key,然后在 Map 中查找目标链接,对目标地址做重定向处理。

Map 结构我们可以基于 MySQL 和 Cache 进行构建,那就剩下如下问题了:

  • Key 怎么来,又是怎么维护的?

  • 如何通过 Http 协议进行请求重定向?

2.1 Key 生成

通常情况下,Key 的生成方式由很多。但对于短链接服务来说,生成 Key 的长度是一个非常重要的指标。

首先,生成的 Key 不能重复;其次,Key 要尽可能短。这样才能使最终短链长度尽可能的小。

基于此,我们无法使用分布式 Key 生成算法,如 UUID。最佳的生成策略应该是基于 Number 自增的方案。

结论:我们需要一个基于 Number 自增的 Key 生成器。

2.2 Key 编解码

如果我们使用 Number 作为 Key,那么还有没有方案进一步压缩 Number 长度呢?

对于数字来说:

  • 8 进制比 2 进制短;

  • 10 进制比 8 进制短;

  • 16 进制比 10 进制短;

  • ......

因此,我们可以使用高进制对数字 Key 进行编解码,从而进一步压缩 Key 的长度。

2.3 请求重定向

请求重定向是 HTTP 协议的一部分,JEE 的 HttpServletResponse 就提供重定向接口,同时 Spring MVC 对其也提供了支持。

基于 HttpServletResponse 的重定向:

public void redirect(@PathVariable String code, HttpServletResponse response) throws IOException {    String url = getTargetUrl(code);    // 调用 sendRedirect 方法,进行请求重定向    response.sendRedirect(url);}

基于 Spring MVC 的重定向:

public ModelAndView redirect(@PathVariable String code){    String url = getTargetUrl(code);    // 使用 RedirectView,进行请求重定向    RedirectView redirectView = new RedirectView();    redirectView.setUrl(url);    return new ModelAndView(redirectView);}


要点分析完成后,让我们先把 maven 项目搭建起来。

项目搭建

该项目使用 Spring Boot 作为主要开发框架。

项目依赖组件:

组件 含义
spring-boot-starter-web Web
flyway 数据库管理
Junit 测试
lombok 自动生成getter、setter

随着功能的增加,将为项目添加更多依赖。

3.1. 项目生成

浏览器中输入 https://start.spring.io/ ,打开 spring-boot 项目生成器,按照下列配置生成项目:

名称
项目类型 maven
语言 java
Boot版本 2.1.1
group com.geekhalo
artifact tinyurl
dependency web、flyway、lombok

点击“Generate Project”,生成并下载项目。将下载的项目解压,得到一个完整的 maven 项目,打开熟悉的 IDE,将项目导入到 IDE 中。

我们生成了一个空的 Spring Boot 项目,稍后的所有操作都会基于这个项目完成。

项目成功生成后,让我们对系统进行进一步分析。首先,需要对系统中的核心组件进行梳理。

核心组件

基于设计分析,我们可以整理出系统所需的核心组件。

4.1 NumberGenerator

通过自增方式生成 Number 类型的 Key。

其接口签名如下:

public interface NumberGenerator {    /**     * 生成自增 Key     * @return     */    Long nextNumber(NumberType type);}


4.2 NumberEncoder

对 Number 进行编解码操作,以进一步减少 Key 的长度。

其接口签名如下:

public interface NumberEncoder {    /**     * 对 Number 进行编码     * @param id     * @return     */    String encode(Long id);
/** * 对 Number 进行解密 * @param str * @return */ Long decode(String str);}


4.3 TargetUrlRepository

用于处理目标 URL 的持久化。

其接口定义如下:

public interface TargetUrlRepository {    /**     * 添加链接     * @param targetUrl     */    void save(TargetUrl targetUrl);
/** * 获取连接 * @param id * @return */ TargetUrl getById(Long id);}

至此,系统核心组件就分析完了。接下来,让我们看下核心流程。

核心流程

核心流程主要包括创建短链接和访问短链接。

5.1 创建短链接

创建短链接,主要服务于内部系统,将较长的 URL 地址提交到短链接服务,并获取与之对应的较短的 URL 地址。

创建短链接流程大体如下:

(版权归原作者所有,侵删)


浏览 665
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报