最近在写一个短链服务,提供两个API给用户使用,一个API用于生成短链,一个API用于根据短链获取长链接。
生成短链的实现原理是把数据库表的递增ID根据规则转换为4到7个字母数字组合。该组合作为长链接的key,利用数据库的主键保证了长链接和key的唯一性。
数据库主键id是十进制的数字。字母数字的组合加上大小写字母一共有62位,所以转换规则就是把10进制的ID转换为62进制。具体做法就是循环对62进行取余,每次取余之后都除以62直到等于零。100万的十进制数会对应4个字母数字组合,1亿的十进制数对应5个,100亿对应6个,1万亿对应7个,足够使用了。
具体生成短链的过程时用户过来一个请求时,先把保存一条记录到数据库中,然后获取该记录的ID,进行转换,获取字母数字组合,再保存到数据库中。
在测试的时候发现这样的做法只能支持每秒3个用户同时进行访问,用户多时就会由于在数据库中给短链设置了唯一索引而报错,因为同时保存了空值到数据库中。
之后考虑添加事务进行解决,在插入记录会出现MySQL error “Deadlock found when trying to get lock; try restartingtransactionn,性能几乎没有提升。
最后加入ReentrantLock锁,在保存数据库之前加锁,更新数据库成功之后进行解锁,性能得到了提升,本机测试每秒200个用户同时访问没有出现失败的情况。
参考衔接
https://javadoop.com/post/url-shortener
网友评论