如何解决移动互联网短网址转换失败造成数据丢失问题?
在很多互联网应用中,一般都会有长网址和短网址之间的转换。比如,用户在某网站发布一篇图文,那么肯定会生成该图文对应的长网址,同时大多数网站还会有一个对应的短网址,如图1

用户后续在客户端(比如手机app)浏览时对应的就可以是短网址了,然后就可以用该短网址去访问该图文的具体内容。这有点像我们熟知的手机短号。如图2

有个长网址可以理解,为什么还要多此一举搞个短网址呢?主要有以下几个方面的原因:
-
一些社交媒体比如微博,是有限制字长的,地址长了,会影响用户发出其他正文内容。
-
用短网址进行数量追踪和统计更方便。
-
如果链接地址太长,在用户看来,视觉上不友好。
-
有些长网址中可能会包含#或者@等特殊字符,这些特殊字符会给客户端的字符串处理带来压力。
比如,如下的一个长网址
http://xxxxx.com/xxxxx.html?xxxx=xxx& xxxx=xxx& xxxx=xxx& xxxxx=xxxx& xxxx=xx
经过转换生成一个短网址,是如下这样子的:
http://t.cn/errrt
看到这个短网址,是不是会感觉很清爽。那怎么把一个长网址转换成短网址呢?其实还是挺简单,下面为一段将长网址转换为短网址的简易代码,仅供参考。
Private static final String[] X36_ARRAY = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M
,N,O,P,Q,R,S,T,U,V,W,X,Y,Z".split(",");
public String getShortUrl(String url) {
long shortUrlSeed = jedis.incr("short_url_seed");
StringBuffer buffer = new StringBuffer();
while(shortUrlSeed > 0) {
buffer.append(X36_ARRAY[(int)(shortUrlSeed % 36)]);
shortUrlSeed = shortUrlSeed / 36;
}
//获取到短链接
String shortUrl = buffer.reverse().toString();
return shortUrl;
}
可以自己用一个长网址测试一下上面这段代码,看看生成的短网址是不是简单到让你惊讶。网址转换为短网址之后,用户使用更方便,应用内部做数据统计和更新也更方便。但是,我们在应用内部大多数场合还是需要长网址。用户在客户端上访问一个博文时传递过来的是短网址,但是要完成访问功能还是需要先转化为长网址。这就好比,用了姓名,我们很多时候还是需要使用身份证号去办理一些业务。
上面的代码了给出了长网址转换为短网址的做法,但是如果要将短网址转化为长网址要怎么实现了?其实很简单,在上面的长短网址转换服务中,将长网址转换为短网址完成后,立马将长短网址的映射关系保存起来,比如保存到数据库中。
然后用户访问时传递短网址地址,服务端会先去地址转换服务查询对应的长网址,对于地址转换服务的逻辑处理也很简单,直接去数据库里查询长短网址映射表,根据当前的短连接查询出对应的长网址。
数据库不是任何时候都一定能做到100%的高可用的。所以如果我们在根据短网址查询长网址时发生宕机了。那肯定是无法完成这次转换操作,该请求将无法继续进行下去。进而导致本次请求失败,数据丢失。那失败之后我们也不能直接忽略,通常我们需要针对这种情况记录一下这些失败的消息,比如,将他们记录到数据库中,如图