功能

短网址(Short URL),顾名思义就是在形式上比较短的网址。通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流。目前已经有许多类似服务,借助短网址您可以用简短的网址替代原来冗长的网址,让使用者可以更容易的分享链接。
例如:http://t.cn/SzjPjA

短网址服务,可能很多朋友都已经不再陌生,现在大部分微博、手机邮件提醒等地方已经有很多应用模式了,并占据了一定的市场。估计很多朋友现在也正在使用。看过新浪的短连接服务,发现后面主要有6个字符串组成,于是第一个想到的就是原来公司写的一个游戏激活码规则,也就是下面的算法2,
26个大写字母 26小写字母,10个数字,随机生成6个然后插入数据库对应一个id,短连接跳转的时候,根据字符串查询到对应id,即可实现相应的跳转!不过2的62次方,不知道有没有重复的,小概率可以,但是对应不是很大的网站应该足够了

短链接生成算法

嫌懒,就没用发号器,希望不会冲突太严重吧hhhh,用了 随机算法 & hash算法(MD5)

1)将长网址md5生成32位签名串,分为4段, 每段8个字节;

2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;

3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;

4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;

具体项目代码可以看这里:GitHub跳转链接

本地运行网站大概长这样:

前端做的很渣,勿喷23333

数据库我使用的是redis,主要还是为了更快的速度,同时redis还可以设置过期时间

打包部署过程

在Intellij Idea中对当前项目打包,使用maven package命令,在target目录下生成tinyUrl-0.0.1-SNAPSHOT.jar

接下来,在公网上的cent OS服务器上建立ssh连接,预先安装好Java11和redis数据库

随后使用nohup命令,使springboot程序后台执行nohup java -jar tinyUrl-0.0.1-SNAPSHOT.jar >/dev/null 2>log &,确保ssh连接断开后springboot项目仍然能够在指定端口上正常运作,同时由于springboot内部自带了日志输出功能,我们可以不需要额外的日志输出

如果一切正常,那么这个项目应该已经可以在指定端口上跑起来了,通过访问服务器IP:端口就可以打开对应的网站

配合域名和nginx使用

如果配合域名和nginx我们该如何使用呢?

其实只要利用nginx的反向代理就可以达到相应的效果,如将本机的8080端口映射到80/443端口上即可,这样服务器就做到了一个IP管理多个域名,当我们访问对应的域名时时,nginx会将请求在内部转发到8080端口上

配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
server
{
listen 80;
listen 443 ssl http2;
server_name url.rayzhang.top;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/url.rayzhang.top;

#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
#HTTP_TO_HTTPS_END
ssl_certificate /www/server/panel/vhost/cert/url.rayzhang.top/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/url.rayzhang.top/privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;

#SSL-END

#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END

#PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-00.conf;
#PHP-INFO-END

#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/url.rayzhang.top.conf;
#REWRITE-END
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}

location ~ \.well-known{
allow all;
}

access_log /www/wwwlogs/url.rayzhang.top.log;
error_log /www/wwwlogs/url.rayzhang.top.error.log;
}

此外ssl等配置也可以在nginx上完成,但是我们会遇到另一个问题,由于nginx的内网转发,我们在springboot中使用AOP LogAspect获取客户端IP的行为,最终都会变成简单的内网IP 0.0.0.0,毕竟是被本机内部访问的

那么怎么解决呢,注意到我们在nginx中配置了X-Real-IP等参数,当我们访问时nginx已经获取到了IP等信息,并打包进行了转发

我们只需要在Springboot配置文件中加入如下参数即可:

就这样,我就完成了tinyurl网站的部署了,有兴趣的话可以来我刚部署好的网站试一试!