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

技术怎么用Java设计一个短链接生成系统这篇文章主要讲解了“怎么用Java设计一个短链接生成系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java设计一个短链接

本文主要讲解“如何用Java设计一个短链接生成系统”。本文的解释简单明了,易学易懂。现在,请跟随边肖的思路,学习学习“如何用Java设计短链接生成系统”!

00-1010相信你在生活中会收到很多短信,尤其是最近双十一活动期间,那些短信有两个特点。第一个是几乎都是垃圾邮件,这里可以忽略。第二个是链接很短,比如下面这个:

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

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

太长的链接很容易被限制长度。

短链接看起来简洁,长链接看起来愚蠢。

安全,不想暴露参数。

链接转换可以统一,当然也可以实现计数点击等操作。

背后的原理是什么?怎么发生的?你会如何设计这样一个系统?[来自养鹅场采访者]

00-1010短链接展示逻辑

这里最重要的知识点是重定向。让我们先回顾一下http的状态代码:

分类1**服务器收到请求需要请求者继续执行操作2**成功,操作成功收到并处理3**重定向,需要进一步操作完成请求4**客户端错误,请求包含语法错误或无法完成请求5**服务器错误,服务器在处理请求的过程中出现错误,所以以3开头的状态码都是关于重定向的:

00:多种选择,可以存在于多个地点。

31:永久重定向,浏览器会缓存并自动重定向到新地址。

02:临时重定向,客户端将继续使用旧URL。

303:检查其他地址,类似于301。

04:未修改。请求的资源尚未修改。当服务器返回此状态代码时,将不会返回任何资源。

05:访问资源需要代理。

36:放弃状态代码

07:临时重定向,使用获取请求重定向

整个跳跃过程:

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

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

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

02临时重定向可以解决次数不准确的问题,但每次改为短链接系统,对服务器的压力就会增加。

3.浏览器获得重定向的状态代码和真正需要访问的地址,并重定向到真正的长链接。

从下图可以看出,链接确实被302重定向到了新地址,并且在返回的报头中有一个字段:Location是要重定向的地址:

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

00-1010全球发射机

当然,我们首先想到的是压缩。和文件压缩一样,压缩后,我们解压恢复到原来的链接,重定向到原来的链接。不幸的是,这是行不通的。你见过能直接把这么长的数字压缩到这么短的长度的压缩方法吗?其实这是不可能的。就像霍夫曼树一样,它只能高效压缩重复字符多的字符串。和link一样,可能会带很多参数,而且有各种不规则性,所以直接压缩算法是不现实的。

那么https://dx.10086.cn/tzHLFw和https://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?之间的交换是什么渠道=?前面的路径没变,但是变的是后面的路径,也就是tzHLFw和gmccapp/网页/payphonemoney/index.html?通道=之间的转换。

其实也很简单,就是数据库中的一条数据,一个id对应一个长链接(相当于一个全局发送者,一个全局唯一ID):

idurl

ead>

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必须是全局唯一的,如果冲突,必须重新生成)

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

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

性能考虑

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

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

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

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

感谢各位的阅读,以上就是“怎么用Java设计一个短链接生成系统”的内容了,经过本文的学习后,相信大家对怎么用Java设计一个短链接生成系统这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/143176.html

(1)

相关推荐

  • mysql如何使用foreign key

    技术mysql如何使用foreign key这篇文章将为大家详细讲解有关mysql如何使用foreign key,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    攻略 2021年10月27日
  • openwrt设置远程管理(openwrt模式怎么设置)

    技术OpenWRT如何启用工作模式开关和联网小编给大家分享一下OpenWRT如何启用工作模式开关和联网,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 主要配置 rc.local 脚本,内容如下:r

    攻略 2021年12月18日
  • c语言圣诞树(c语言简单圣诞树编程)

    技术如何用C语言实现圣诞树这篇文章主要介绍“如何用C语言实现圣诞树”,在日常操作中,相信很多人在如何用C语言实现圣诞树问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何用C语言实现圣诞树”

    攻略 2021年12月22日
  • 怎么浅谈数据库优化方案

    技术怎么浅谈数据库优化方案今天就跟大家聊聊有关怎么浅谈数据库优化方案,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。下面给大家分析了数据库优化方案,具体内容如下1.

    攻略 2021年12月2日
  • 如何解析Java常量池与字符串intern

    技术如何解析Java常量池与字符串intern这期内容当中小编将会给大家带来有关如何解析Java常量池与字符串intern,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在Java应用程

    攻略 2021年11月23日
  • Socket基础知识有哪些

    技术Socket基础知识有哪些本篇文章给大家分享的是有关Socket基础知识有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。如何一步步掌握Socket相

    攻略 2021年11月25日