要点
将一个长url生成一个短链接是很常见的需求,本文尝试通过serverless的方式来提供这个功能,主要有两部分内容:
- 一个简单的短链接生成方案
- 腾讯云的scf函数如何使用第三方依赖库
如何生成短链接
这里使用了一个很简单的方案,提交url时,先通过mysql的自增id获取一个整数,表结构大致如下:
代码语言:txt复制CREATE TABLE `short_url` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`hash` varchar(45) DEFAULT NULL,
`name` varchar(45) NOT NULL,
`url` varchar(1024) NOT NULL,
`created_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
这样insert数据的时候,id会自增,获取到这个自增的整数值,然后使用hashids这个库将这个id转换为一个短字符串:
https://hashids.org/python/
将这个短字符串作为短网址域名的路径就可以使用了。
腾讯云scf如何使用第三方库
由于使用到了hashids这个第三方库,就需要将这个库也打包一起上传到腾讯云,这里需要注意的要点就是安装hashids库的命令:
代码语言:txt复制pip install hashids -t 云函数代码所在目录
注意后面的 -t 参数,将依赖库安装在云函数的代码所在的目录,这样在使用scf命令打包上传时,依赖库也会被一起上传
直接贴代码
代码语言:txt复制# -*- coding: utf8 -*-
from os import getenv
from hashids import Hashids
import json
import pymysql
from pymysql.err import OperationalError
mysql_conn = None
def init_db():
global mysql_conn
if not mysql_conn:
mysql_conn = pymysql.connect(
host=getenv('DB_BING_HOST'),
port=int(getenv('DB_BING_PORT')),
user=getenv('DB_BING_USER'),
password=getenv('DB_BING_PASSWORD'),
db=getenv('DB_BING_DATABASE'),
charset='utf8mb4',
autocommit=True
)
def close_db():
global mysql_conn
if mysql_conn:
mysql_conn.close()
def __get_cursor():
try:
return mysql_conn.cursor()
except OperationalError:
mysql_conn.ping(reconnect=True)
return mysql_conn.cursor()
def save2db(name, url):
sql_template = """INSERT INTO `bing`.`short_url` (`name`, `url`) VALUES (%s,%s)"""
with __get_cursor() as cursor:
cursor.execute(sql_template, (name, url))
auto_id = cursor.lastrowid
return auto_id
def set_hash(id, hash):
sql_template = """UPDATE `bing`.`short_url` SET `hash` = %s WHERE `id` = %s;"""
with __get_cursor() as cursor:
cursor.execute(sql_template, (hash, id))
def main_handler(event, context):
# 读取请求参数
if "requestContext" not in event.keys():
return {"errorCode":410,"errorMsg":"event is not come from api gateway"}
request = event["requestContext"]
query = json.loads(event['body'])
name = query.get('name')
url = query.get('url')
#初始化数据库连接
init_db()
#插入记录,返回自增id
auto_id = save2db(name, url)
#生成短字符串
hashid = Hashids(salt="bangbangbang")
hash = hashid.encode(auto_id)
print(auto_id, hash)
#将短字符串保存到记录中
set_hash(int(auto_id), hash)
#关闭数据库连接
close_db()
return {"code":200,"data": hash}
测试
在本地创建一个测试数据文件,event.json:
代码语言:txt复制{
"requestContext": {},
"body": "{"name": "测试","url": "http://www.qq.com"}"
}
本地测试验证:
代码语言:txt复制cat event.json |scf native invoke
将返回的短字符串拼接到你想使用的域名后面,就可以获得一个自己的短网址生成器了:
代码语言:txt复制http://short.url/zv
下一篇将通过云函数的方式来实现短链接的跳转功能
需要注意的问题
腾讯云提供了serverless_db_sdk,但是经尝试,这个sdk里面获取到的cousor对象无法获取lastrowid,也就是取不到每次插入记录后的自增id,所以这里自行使用pymysql来操作数据库,所以务必记得在最后要手动关闭链接
生成短网址后实现短链接跳转的函数可参考下一篇 Serverless-实现一个短网址服务(二)