<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          長鏈接 轉(zhuǎn)短鏈接URL的設(shè)計(jì)思路

          共 1963字,需瀏覽 4分鐘

           ·

          2020-12-10 00:10

          正確的原理就是通過發(fā)號(hào)策略,給每一個(gè)過來的長地址,發(fā)一個(gè)號(hào)即可,小型系統(tǒng)直接用mysql的自增索引就搞定了。如果是大型應(yīng)用,可以考慮各種分布式key-value系統(tǒng)做發(fā)號(hào)器。不停的自增就行了。第一個(gè)使用這個(gè)服務(wù)的人得到的短地址是 http://xx.xx/0?第二個(gè)是 http://xx.xx/1 第11個(gè)是 http://xx.xx/a 第依次往后,相當(dāng)于實(shí)現(xiàn)了一個(gè)62進(jìn)制的自增字段即可。

          1. 62進(jìn)制如何用數(shù)據(jù)庫或者KV存儲(chǔ)來做?

          其實(shí)我們并不需要在存儲(chǔ)中用62進(jìn)制,用10進(jìn)制就好了。比如第10000個(gè)長地址,我們給它的短地址對(duì)應(yīng)的編號(hào)是9999,我們通過存儲(chǔ)自增拿到9999后,再做一個(gè)10進(jìn)制到62進(jìn)制的轉(zhuǎn)換,轉(zhuǎn)成62進(jìn)制數(shù)即可。這個(gè)10~62進(jìn)制轉(zhuǎn)換,你完全都可以自己實(shí)現(xiàn)。

          2. 如何保證同一個(gè)長地址,每次轉(zhuǎn)出來都是一樣的短地址

          上面的發(fā)號(hào)原理中,是不判斷長地址是否已經(jīng)轉(zhuǎn)過的。也就是說用拿著百度首頁地址來轉(zhuǎn),我給一個(gè)http://xx.xx/abc 過一段時(shí)間你再來轉(zhuǎn),我還會(huì)給你一個(gè) http://xx.xx/xyz。這看起來挺不好的,但是不好在哪里呢?不好在不是一一對(duì)應(yīng),而一長對(duì)多短。這與我們完美主義的基因不符合,那么除此以外還有什么不對(duì)的地方?

          有人說它浪費(fèi)空間,這是對(duì)的。同一個(gè)長地址,產(chǎn)生多條短地址記錄,這明顯是浪費(fèi)空間的。那么我們?nèi)绾伪苊饪臻g浪費(fèi),有人非常迅速的回答我,建立一個(gè)長對(duì)短的KV存儲(chǔ)即可。嗯,聽起來有理,但是。。。這個(gè)KV存儲(chǔ)本身就是浪費(fèi)大量空間。所以我們是在用空間換空間,而且貌似是在用大空間換小空間。真的劃算嗎?這個(gè)問題要考慮一下。當(dāng)然,也不是沒有辦法解決,我們做不到真正的一一對(duì)應(yīng),那么打個(gè)折扣是不是可以搞定?

          這個(gè)問題的答案太多種,各有各招。這個(gè)方案最簡單的是建立一個(gè)長對(duì)短的hashtable,這樣相當(dāng)于用空間來換空間,同時(shí)換取一個(gè)設(shè)計(jì)上的優(yōu)雅(真正的一對(duì)一)。實(shí)際情況是有很多性價(jià)比高的打折方案可以用,這個(gè)方案設(shè)計(jì)因人而異了。那我就說一下我的方案吧。

          我的方案是:用key-value存儲(chǔ),保存“最近”生成的長對(duì)短的一個(gè)對(duì)應(yīng)關(guān)系。注意是“最近”,也就是說,我并不保存全量的長對(duì)短的關(guān)系,而只保存最近的。比如采用一小時(shí)過期的機(jī)制來實(shí)現(xiàn)LRU淘汰。

          這樣的話,長轉(zhuǎn)短的流程變成這樣:

          • 在這個(gè)“最近”表中查看一下,看長地址有沒有對(duì)應(yīng)的短地址

          • 就直接返回,并且將這個(gè)key-value對(duì)的過期時(shí)間再延長成一小時(shí)

          • 如果沒有,就通過發(fā)號(hào)器生成一個(gè)短地址,并且將這個(gè)“最近”表中,過期時(shí)間為1小時(shí)


          所以當(dāng)一個(gè)地址被頻繁使用,那么它會(huì)一直在這個(gè)key-value表中,總能返回當(dāng)初生成那個(gè)短地址,不會(huì)出現(xiàn)重復(fù)的問題。如果它使用并不頻繁,那么長對(duì)短的key會(huì)過期,LRU機(jī)制自動(dòng)就會(huì)淘汰掉它。

          當(dāng)然,這不能保證100%的同一個(gè)長地址一定能轉(zhuǎn)出同一個(gè)短地址,比如你拿一個(gè)生僻的url,每間隔1小時(shí)來轉(zhuǎn)一次,你會(huì)得到不同的短地址。但是這真的有關(guān)系嗎?

          3. 如何保證發(fā)號(hào)器的大并發(fā)高可用

          上面設(shè)計(jì)看起來有一個(gè)單點(diǎn),那就是發(fā)號(hào)器。如果做成分布式的,那么多節(jié)點(diǎn)要保持同步加1,多點(diǎn)同時(shí)寫入,這個(gè)嘛,以CAP理論看,是不可能真正做到的。其實(shí)這個(gè)問題的解決非常簡單,我們可以退一步考慮,我們是否可以實(shí)現(xiàn)兩個(gè)發(fā)號(hào)器,一個(gè)發(fā)單號(hào),一個(gè)發(fā)雙號(hào),這樣就變單點(diǎn)為多點(diǎn)了?依次類推,我們可以實(shí)現(xiàn)1000個(gè)邏輯發(fā)號(hào)器,分別發(fā)尾號(hào)為0到999的號(hào)。每發(fā)一個(gè)號(hào),每個(gè)發(fā)號(hào)器加1000,而不是加1。這些發(fā)號(hào)器獨(dú)立工作,互不干擾即可。而且在實(shí)現(xiàn)上,也可以先是邏輯的,真的壓力變大了,再拆分成獨(dú)立的物理機(jī)器單元。1000個(gè)節(jié)點(diǎn),估計(jì)對(duì)人類來說應(yīng)該夠用了。如果你真的還想更多,理論上也是可以的。

          4. 具體存儲(chǔ)如何選擇

          這個(gè)問題就不展開說了,各有各道,主要考察一下對(duì)存儲(chǔ)的理解。對(duì)緩存原理的理解,和對(duì)市面上DB、Cache系統(tǒng)可用性,并發(fā)能力,一致性等方面的理解。

          5. 跳轉(zhuǎn)用301還是302

          這也是一個(gè)有意思的話題。首先當(dāng)然考察一個(gè)候選人對(duì)301和302的理解。瀏覽器緩存機(jī)制的理解。然后是考察他的業(yè)務(wù)經(jīng)驗(yàn)。301是永久重定向,302是臨時(shí)重定向。短地址一經(jīng)生成就不會(huì)變化,所以用301是符合http語義的。同時(shí)對(duì)服務(wù)器壓力也會(huì)有一定減少。

          但是如果使用了301,我們就無法統(tǒng)計(jì)到短地址被點(diǎn)擊的次數(shù)了。而這個(gè)點(diǎn)擊次數(shù)是一個(gè)非常有意思的大數(shù)據(jù)分析數(shù)據(jù)源。能夠分析出的東西非常非常多。所以選擇302雖然會(huì)增加服務(wù)器壓力,但是我想是一個(gè)更好的選擇。



          class Tool{ /**?????*?64進(jìn)制轉(zhuǎn)十進(jìn)制
          * @date 2017-11-11 * @param $b64 64進(jìn)制參數(shù) * @return bool|int 返回10進(jìn)制數(shù)值 */ public static function b64dec($b64){ $map = array( '0'=>0,'1'=>1,'2'=>2,'3'=>3,'4'=>4,'5'=>5,'6'=>6,'7'=>7,'8'=>8,'9'=>9, 'A'=>10,'B'=>11,'C'=>12,'D'=>13,'E'=>14,'F'=>15,'G'=>16,'H'=>17,'I'=>18,'J'=>19, 'K'=>20,'L'=>21,'M'=>22,'N'=>23,'O'=>24,'P'=>25,'Q'=>26,'R'=>27,'S'=>28,'T'=>29, 'U'=>30,'V'=>31,'W'=>32,'X'=>33,'Y'=>34,'Z'=>35,'a'=>36,'b'=>37,'c'=>38,'d'=>39, 'e'=>40,'f'=>41,'g'=>42,'h'=>43,'i'=>44,'j'=>45,'k'=>46,'l'=>47,'m'=>48,'n'=>49, 'o'=>50,'p'=>51,'q'=>52,'r'=>53,'s'=>54,'t'=>55,'u'=>56,'v'=>57,'w'=>58,'x'=>59, 'y'=>60,'z'=>61,'_'=>62,'='=>63 ); $dec = 0; $len = strlen($b64); for ($i = 0; $i < $len; $i++) { $b = $map[$b64{$i}]; if ($b === null) { return false; } $j = $len - $i - 1; $dec += ($j == 0 ? $b : (2 << (6 * $j - 1)) * $b); } return $dec; } /**?????*?十進(jìn)制轉(zhuǎn)64進(jìn)制
          * @date 2017-11-24 * @param $dec * @return bool|string 返回64進(jìn)制 */ public static function decb64($dec){ if ($dec < 0) { return FALSE; } $map = array( 0=>'0',1=>'1',2=>'2',3=>'3',4=>'4',5=>'5',6=>'6',7=>'7',8=>'8',9=>'9', 10=>'A',11=>'B',12=>'C',13=>'D',14=>'E',15=>'F',16=>'G',17=>'H',18=>'I',19=>'J', 20=>'K',21=>'L',22=>'M',23=>'N',24=>'O',25=>'P',26=>'Q',27=>'R',28=>'S',29=>'T', 30=>'U',31=>'V',32=>'W',33=>'X',34=>'Y',35=>'Z',36=>'a',37=>'b',38=>'c',39=>'d', 40=>'e',41=>'f',42=>'g',43=>'h',44=>'i',45=>'j',46=>'k',47=>'l',48=>'m',49=>'n', 50=>'o',51=>'p',52=>'q',53=>'r',54=>'s',55=>'t',56=>'u',57=>'v',58=>'w',59=>'x', 60=>'y',61=>'z',62=>'_',63=>'=', ); $b64 = ''; do { $b64 = $map[($dec % 64)] . $b64; $dec /= 64; } while ($dec >= 1); return $b64; }}

          瀏覽 63
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  又大又爽 | 亚洲专区在线播放 | 国产婷婷久久 | 啊啊啊啊啊在线观看 | 黄色片视频在线 |