短网址程序想必大家不会陌生。有的时候我们需要发送一条非常长的链接,如果能将其缩短,将会非常方便。市面上有各类现成的短网址服务;如果我们拥有一个短域名,我们也可以自己搭建短域名服务器。
现成的免费短网址程序非常多,比如大名鼎鼎的Yourls, 等等。这些程序大多数基于传统PHP, 性能较差,特别是访问量多了以后数据库查询非常耗时。另外,这些短网址程序也不能提供详细的访问记录与数据分析。
如果您只是想要用短网址程序,那么我推荐您使用我提供的免费短网址服务器。您只需要解析您的域名到我的服务器地址上,即可使用您的短域名添加短链接,非常方便,无需任何设置。具体使用方法可以看这里:https://qing.su/shorturl
如果您仍然想用自己的服务器来搭建,那么今天我来介绍一个好用的高性能短网址程序,Shlink.io. 它基于Swoole-PHP, 采用Mezzio, Doctrine, Symfony等最新的技术,拥有其他短网址程序无法比拟的性能,支持高并发与快速数据库查询。另外,它提供丰富的数据分析和API, 能够按照标签、地域等做单项统计,获得专业的数据分析。它的API功能非常强大,您可以自由定制想要实现的功能。它的搭建过程比较复杂,我们这里先简单介绍一下一键Docker搭建(不推荐),然后再详细介绍手工搭建。程序源码及使用教程在这里https://github.com/shlinkio/shlink. 很遗憾,官方的搭建教程比较简略,建议您参考这篇文章来搭建,否则可能会遇到各种预料之外的情况。
本文作者为香菇肥牛,原文链接为https://qing.su/article/160.html, 转载请注明原文链接。谢谢!
1, 使用Docker搭建
Docker搭建Shlink.io非常简单,您只需要执行下面的命令就可以了。
1 2 3 4 5 6 7 | docker run \ --name my_shlink \ -p 8080:8080 \ -e SHORT_DOMAIN_HOST=qing.su \ -e SHORT_DOMAIN_SCHEMA=https \ -e GEOLITE_LICENSE_KEY=kjh2.qing.su.d3kj345 \ shlinkio/shlink:stable |
命令中的Geolite_License_Key我在后面会详细提到。由于整个程序可以定制和修改的部分较多,因此我这里建议手动安装Shlink.io系统。
2, 手动搭建——系统环境要求
本教程的系统环境为Ubuntu 20.04 LTS 64 bit. 您可以使用其他的操作系统,但是因为Shlink.io需要PHP 7.4, 因此在使用其他操作系统安装的时候可能需要额外添加源。
短网址程序的所有数据均存在数据库中。下面的教程将使用MariaDB数据库,但是您也可以使用MySQL/PostgreSQL/Sqlite/MSSQL等数据库。
短网址程序使用Swoole作为服务器。可以选择前端用Nginx/Apache/HAProxy做反代,也可以直接用Swoole处理HTTP请求,我将在后面分别介绍如何操作。
另外,由于短网址程序需要大量的数据库读写,为了性能考虑,建议您使用NVMe硬盘。本文的搭建环境需要2 GB内存。
Shlink.io统计分析时会需要用到Maxmind IP数据库,您需要在这里注册一个账号,然后申请一个免费的GeoLite2 IP数据库License Key. 请记下这个Licence Key, 后面的安装过程会用到。
请将您的短域名设置A记录,解析到您的服务器的IP地址上。解析生效后,我们就可以开始搭建了。本文中,将用测试域名test.mywi.fi作为示例,搭建短网址程序。
3, 安装数据库
这里介绍安装MariaDB数据库。其他数据库的安装类似。在SSH中执行:
1 | apt-get install mariadb-server |
然后设置root密码:
1 | mysql_secure_installation |
设置完毕后,登录MariaDB新建数据库,用户名以及密码。
1 2 3 4 | mysql -u root -p CREATE DATABASE shlinkdb; GRANT ALL ON shlinkdb.* TO 'shlinkuser' IDENTIFIED BY 'fj09SUH8e40sUf38hyG'; quit; |
4, 安装PHP与Swoole
前面提到过,Shlink.io只支持PHP 7.4. 我们用包管理器安装PHP, 并安装需要的组件。
1 | apt-get install php7.4 php7.4-fpm php7.4-mysql php7.4-json php7.4-gd php7.4-common php7.4-curl php7.4-intl php7.4-xml |
Swoole可以通过pecl来安装。PHP默认不带pecl, 因此我们先安装Pecl.
1 2 | wget http://pear.php.net/go-pear.phar php go-pear.phar |
然后,使用pecl编译安装Swoole. 需要注意的是,默认安装的PHP 7.4不带phpize, 我们需要额外安装php7.4-dev来获取phpize. 另外,如果您的系统上没有安装编译器,您还需要gcc/g++来编译安装包。安装phpize与gcc/g++:
1 | apt-get install php7.4-dev build-essential |
编译安装Swoole:
1 | pecl install swoole |
安装完毕后,我们将swoole模块写入php.ini让其生效。
1 | echo "extension=swoole.so" >> /etc/php/7.4/cli/php.ini |
5, 安装网站程序
配置好数据库与PHP-Swoole之后,我们就可以开始安装短网址站程序了。
1 2 3 4 5 6 7 8 9 10 | mkdir -p /srv/www/shlink cd /srv/www/shlink wget https://github.com/shlinkio/shlink/releases/download/v2.2.1/shlink_2.2.1_dist.zip unzip * rm *.zip mv * public_html cd * chmod -R +w data cd bin ./install |
这样就开始了自动安装程序。安装过程中会需要设置多个选项。比较重要的有下面这些。
- 数据库配置,您需要填入之前新建的数据库名,用户及密码
- 是否启用SSL. 若您只使用自己的短域名,建议您开启SSL. 若您打算开放服务器,允许别人的任意域名解析到您的服务器添加短网址,那么建议您关闭SSL, 选择HTTP.
- Provide a GeoLite2 license key 这里填入我们之前申请的GeoLite2授权码
- REDIRECTS部分,需要填入根域名以及无效短域名的跳转地址。若不填,则默认跳到一个404页面
- Redis缓存,您可以在本地搭建Redis缓存服务,进一步提升性能
具体的安装过程可以在下面的轻视频中查看。
程序安装完毕之后,目前还不能访问。我们需要建一个Swoole的守护进程。编辑文件/etc/init.d/shlink_swoole, 添加下面的内容:
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 | #!/bin/bash ### BEGIN INIT INFO # Provides: shlink_swoole # Required-Start: $local_fs $network $named $time $syslog # Required-Stop: $local_fs $network $named $time $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: Shlink non-blocking server with swoole ### END INIT INFO SCRIPT=/srv/www/shlink/public_html/vendor/bin/mezzio-swoole\ start RUNAS=root PIDFILE=/var/run/shlink_swoole.pid LOGDIR=/var/log/shlink LOGFILE=${LOGDIR}/shlink_swoole.log start() { if [[ -f "$PIDFILE" ]] && kill -0 $(cat "$PIDFILE"); then echo 'Shlink with swoole already running' >&2 return 1 fi echo 'Starting shlink with swoole' >&2 mkdir -p "$LOGDIR" touch "$LOGFILE" local CMD="$SCRIPT &> "$LOGFILE" & echo \$!" su -c "$CMD" $RUNAS > "$PIDFILE" echo 'Shlink started' >&2 } stop() { if [[ ! -f "$PIDFILE" ]] || ! kill -0 $(cat "$PIDFILE"); then echo 'Shlink with swoole not running' >&2 return 1 fi echo 'Stopping shlink with swoole' >&2 kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE" echo 'Shlink stopped' >&2 } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; *) echo "Usage: $0 {start|stop|restart}" esac |
保存退出后,开启Daemon
1 2 3 4 | chmod +x /etc/init.d/shlink_swoole update-rc.d shlink_swoole defaults update-rc.d shlink_swoole enable /etc/init.d/shlink_swoole start |
此时,我们访问域名:8080, 比如我这里是test.mywi.fi:8080, 发生了跳转,说明程序已经安装完毕,可以生效了。
6, 处理前端HTTP请求
Swoole默认开启在8080端口。因此,为了让用户正常通过80或者443端口访问我们的短网址服务器,我们有两个选择。1, 设置一个前端Web服务器,用于反代后端的Swoole-PHP服务器;2, 直接让Swoole监听80端口,用Swoole处理前端HTTP请求。这两个方法各有利弊。使用Swoole直接作为服务器,更为轻量高效,且性能更好,能够充分利用Swoole的特性。使用传统服务器反代,则配置较为方便,尤其是SSL等。这里,我将分别介绍两种情况,您可以自行决定。
(1) 直接使用Swoole
直接使用Swoole比较简单,我们直接修改Swoole监听的端口即可。编辑文件/srv/www/shlink/public_html/vendor/mezzio/mezzio-swoole/src/HttpServerFactory.php, 找到下面这行(我这里是第34行):
1 | public const DEFAULT_PORT = 8080; |
改成
1 | public const DEFAULT_PORT = 80; |
然后重启Swoole服务:
1 | /etc/init.d/shlink_swoole restart |
这样,就设置好了Swoole监听80端口。此时,访问您的短域名,比如我这里的test.mywi.fi, 就可以实现跳转了。
(2) 使用传统服务器反代
我们这里介绍Nginx反代,您也可以使用Apache/HAProxy/LiteSpeed等程序来设置反代。首先,安装Nginx. 这里我们只需要实现一个简单的反代功能,不需要手动编译,直接使用默认安装即可。
1 | apt-get install nginx |
然后,配置虚拟主机文件,添加反代。编辑文件/etc/nginx/sites-enabled/default, 在location里面设置成下面的形式:
1 | proxy_pass http://127.0.0.1:8080; |
需要注意的是,如果我们仅设置成反代8080端口,那么后端Swoole不能确认前端访问的主域名是什么。因此,无论解析什么域名,最后都会按照主域名设置的短链接来跳转。同时,后端Swoole也无法确认前端访客的来源IP, 无法按照地理位置进行数据分析。如果需要实现这些功能,我们还需要通过Nginx将对应的头信息传递给后端Swoole. 同样在location里面添加:
1 2 | proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; |
保存完毕之后,测试Nginx配置文件格式是否正确:
1 | nginx -t |
然后,重新载入Nginx配置文件。
1 | service nginx reload |
这样,我们就配置好了前端Nginx反代。如果您需要额外配置SSL, 则可以使用Let’s Encrypt一键配置,或者手动添加证书。
7, 使用客户端添加短网址
Shlink短网址程序搭建好之后,我们就可以添加短网址了。我们有三种方式添加短网址:1,使用命令行;2,使用官网或者自建客户端;3,使用API. 命令行方式较为麻烦,这里不做过多介绍了。这一节我们先介绍使用客户端添加短网址。
使用客户端添加,本质上也是使用API, 只不过程序已经帮你写好了。您可以使用我编译好的客户端https://qing.su/url (数据全部在您的服务器上,不经过我的服务器),或者按照下面的教程,手动编译客户端。
客户端是用JS写的,我们先下载源码:
1 2 3 | wget https://github.com/shlinkio/shlink-web-client/archive/v2.5.1.zip unzip v2.5.1.zip cd shlink-web-client-2.5.1 |
然后,我们需要配置一下编译选项。编辑文件package.json, 找到下面这行:
1 | "homepage": "" |
将其改成您客户端安装的相对路径。比如,我把客户端安装在https://qing.su/url, 那么我这里就需要改成:
1 | "homepage": "/url" |
如果您的服务器还没有安装node, 使用下面的命令安装。
1 2 | curl -sL https://deb.nodesource.com/setup_14.x | bash - apt-get install -y nodejs |
然后,即可开始编译安装:
1 2 | npm install npm run build |
编译完成之后,将build文件夹放到您的网站目录下,改成对应的目录名即可访问。我们访问安装好的客户端,如下图
首次使用,需要添加后端地址。点击Add a server, 进入下面的界面。
这里可以看到,客户端需要我们输入一个API. API可以在后台生成,我们返回SSH, 进入程序目录并生成API授权码:
1 2 | cd /srv/www/shlink/public_html/bin ./cli api-key:generate |
回到客户端,输入刚才的API授权码以及服务器地址,即可连接上服务器。
需要注意的是,如果您的服务器没有开启HTTPS, 那么在浏览器里面加载的时候会出现HTTPS网站加载HTTP内容的情况,可能会被浏览器自动禁止,需要手动设置允许加载HTTP内容。
点击左侧Create Short URL, 即可开始添加短链接。
8, 使用API添加短链接
使用上一节的客户端,我们可以实现短链接的添加,管理和分析。但是,我们不能让所有访客都有这些权限。访客应该只能添加短链接,而只有 管理员才可以管理链接和分析数据。因此,如果您的短网址网站需要开放给访客使用,您就需要使用API来编写接口程序。
Shlink的API文档在这里https://api-spec.shlink.io/. 我们下面给出一个简单的PHP示例,能够获取前端表单用户提交的长链接、域名等,生成短链接。
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 | function callAPI($method, $url, $data){ $curl = curl_init(); switch ($method){ case "POST": curl_setopt($curl, CURLOPT_POST, 1); if ($data) curl_setopt($curl, CURLOPT_POSTFIELDS, $data); break; case "PUT": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); if ($data) curl_setopt($curl, CURLOPT_POSTFIELDS, $data); break; default: if ($data) $url = sprintf("%s?%s", $url, http_build_query($data)); } curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, array( "accept: application/json", 'X-Api-Key: xxxxxx-qing.su-your-api-key', 'Content-Type: application/json', )); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); $result = curl_exec($curl); if(!$result){die("Connection Failure");} curl_close($curl); return $result; } $long_url=trim($_POST['long_url']); $custom_domain=trim($_POST['custom_domain']); $custom_slug = null; $max_visits = null; if (isset($_POST['custom_slug'])) { $custom_slug = trim($_POST['custom_slug']); } $surl_request_array = array( "longUrl" => $long_url, "tags" => $custom_domain, "validSince" => null, "validUntil" => null, "customSlug" => $custom_slug, "maxVisits" => $max_visits, "findIfExists" => true, "domain" => $custom_domain, "shortCodeLength" => 5, ); $make_API_call = callAPI('POST', 'http://public-url-shortner-03.mywi.fi/rest/v2/short-urls', json_encode($surl_request_array)); $response = json_decode($make_API_call, true); echo "<p>Long URL: "; echo $response["longUrl"]; echo "</p><p>Short URL: "; echo $response["shortUrl"]; |
至此,我们使用Swoole与Shlink.io在Ubuntu 20.04上搭建好了一个完整的高性能的短网址程序,并编写了前端短链接生成接口。如果您有任何疑问,欢迎在这里留言,我将尽力解答。本文作者为香菇肥牛,原文链接为https://qing.su/article/160.html, 转载请注明原文链接。谢谢!
太复杂了,我直接用我自己的博客插件
哈哈,是的,这个确实特别麻烦