最近看騰訊朋友網網絡報卡,發現騰訊的網路服務器有不少,當用戶鏈接慢時,頁面會請求不一樣是服務器,每一個服務器相同路徑下都存儲有同一張圖片,根據加載圖片的時間長短來選擇服務器,以便達到用戶訪問最適合本身,時間最短的服務器。javascript
1.記錄當前頁面開始時間time1css
2.循環請求每一個服務器下面的圖片,記錄圖片開始請求時間和結束時間,html
3.根據結束時間和請求時間差,選擇請求時間最短的服務器java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" /> <title>小診所 - 朋友網(騰訊朋友)</title> <script type="text/javascript"> var startLoad=+new Date(); </script> <style type="text/css"> *{margin:0;padding:0;} body{font:13px/1.8em Verdana,Helvetioa,Arial,sans-serif;background-color:#D2D1D0;color:#444444;} a{ color:#3366CC;text-decoration:none;} a:hover{color:#117CFF;text-decoration:underline;} .wrapper{position:relative;padding:1px;width:650px;margin:20px auto 0;border:solid #bbbbbb 1px;background-color:#ffffff;box-shadow:1px 1px 2px rgba(0,0,0,0.3);} .wrapper .wrapper-entry{background-color:#f4f4f4;} .c-title{margin:0 5px;padding:8px 10px;border-bottom:dotted #E0E0E0 1px;line-height:1.2em;font-size:18px;font-weight:bold;font-family:'Microsoft YaHei';} .c-box{padding:15px;} .c-foot{padding:5px 15px;font-size:12px;border-top:solid #e5e5e5 1px;background-color:#EFEFEF;} .c-btn-box,.c-rs{padding:0 5px;margin:15px 0;} .c-btn,.c-btn:visited{ font-size:13px; background-color:#85AE09; display:inline-block; padding:5px 10px 6px; color:#FFF; text-decoration:none; border-radius:6px; box-shadow:0 1px 3px rgba(0,0,0.0.6); border-bottom:1px solid rgba(0,0,0,0.25); position:relative; cursor:pointer; } .c-btn:hover{text-decoration:none;background-color:#111;color:#fff;background-color:#7A9F09;} .c-btn:active{top:1px;}; .c-rs{color:#717171;_height:5.4em;min-height:5.4em;line-height:1.8em;} .c-rs .title{font-size:14px;font-weight:bold;} .success{color:#81A809;} .error{color:#BF0000;} .c-over{position:absolute;text-align:center;width:250px;background:#fff;border:solid #ccc 1px;} </style> </head> <body> <div class="wrapper"> <div class="wrapper-entry"> <h1 class="c-title"> 朋友網小診所</h1> <div class="c-box"> <p> 爲了讓您天天都能順暢地瀏覽朋友網,您可使用小診所進行診斷分析。</p> <p> 若是小診所沒有解決您的問題,您還能夠下載 <a href="http://guanjia.qq.com/" target="_blank" title="QQ電腦管家"> QQ電腦管家</a>、<a href="http://imgcache.qq.com/tools/emu/checknetwork.signed.zip" title="QQ空間網絡情況分析工具">QQ空間網絡情況分析工具</a>進一步進行診斷。</p> <div class="c-btn-box"> <a href="javascript:void(0);" title="點擊開始診斷" class="c-btn" id="J_Start">開始診斷</a> </div> <div class="c-rs" id="J_Result" style="display: none;"> <div id="J_RS_ISP"> </div> <div id="J_RS_CACHE"> </div> </div> </div> <div class="c-foot"> <a href="http://www.pengyou.com" title="返回朋友網">«返回朋友網</a> </div> <!-- <div class="c-over"><a href="#" title="" class="btn-over">診斷完成,返回朋友網</a></div> END--> </div> </div> <div id="Console"> </div> <script type="text/javascript"> Clinic.init({btn:'J_Start'}); $.speed.set(1,67,3,+new Date(),startLoad); $.ping('/clinic/'); </script> </body> </html>
這些函數有的是跟下面的請求函數定製的,因此你們能看懂大概什麼意思,作了哪些事就好了。
數據庫
function $(d){var ele=typeof(d)==='string'?document.getElementById(d):d;return ele;} String.prototype.trim=function(r){return this.replace(r||/^\s+|\s+$/g,"");}; $.cookie=function(name,value,options){ if(typeof value!='undefined'){ options=options||{'domain':'pengyou.com',path:'/'}; if(value===null){ value=''; options.expires=-1; } var expires='',date; if(options.expires&&(typeof options.expires=="number"||options.expires.toUTCString)){ if(typeof options.expires=="number"){ date=new Date(); date.setTime(date.getTime()+(options.expires*24*60*60*1000)); }else{ date=options.expires; } expirex=';expires='+date.toUTCString(); } var path=options.path?';path='+(options.path):'',domain=';domain='+(options.domain?(options.domain):'pengyou.com'), secure=options.secure?';secure':''; document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join(''); }else{ var cookieValue=''; if(document.cookie){ var cookies=document.cookie.split(';'),cookie; for(var i=0,l=cookies.length;i<l;i++){ cookie=cookies[i].trim(); if(cookie.substring(0,name.length+1)==(name+"=")){ cookieValue=decodeURIComponent(cookie.substring(name,length+1)); break; } } } return cookieValue; } } function pgvGetUserInfo(){ var m=document.cookie.match(/(^|;|\s)*pvid=([^;]*)(;|$)/); if(m){ pvid=m[2] }else{ var pvid=(Math.round(Math.random()*2147483647)*(new Date().getUTCMilliseconds()))%10000000000; if((/^http:\/\/((.*?)\.|)pengyou\.com\/.*/i).test(location.href)){ document.cookie="pvid="+pvid+";path=/;domain=pengyou.com;expires=Sun, 18 Jan 2038 00:00:00 GMT;"; }else{ document.cookie="pvid="+pvid+";path=/:domain=qq.com;expires=Sun, 18 Jan 2038 00:00:00 GMT;"; } } return "&pvid="+pvid; } $.ping=function(urlx,domainx,rurlx,rdomainx){ domainx=domainx||'app.xiaoyou.com'; rurlx=rurlx||'-'; rdomainx=rdomainx||'xiaoyou.qq.com'; var Url; if((/^http:\/\/((.*?)\.|)pengyou\.com\/.*/i).test(location.href)){ Url="http://pingfor.pengyou.com"; }else{ Url="http://pingfor.qq.com"; } Url+="/pingd?dm="+domainx+"&url="+urlx+"&tt=-"+"&rdm="+rdomainx+"&rurl"+escape(rurlx)+pgvGetUserInfo()+"&scr=-&scl=-&lang=-&java=1&cc=-&pf=-&tz=-8&ct=-&vs=3.3" new Image().src=Url+"&emu="+Math.random(); } $.speed={set:function(f2,f3,id,value,basetime){ var key=f2+'_'+f3,startTime,endTime,speed,loadTimes={}; if(!this[key]){ this[key]=[]; } startTime=basetime||this[key][0]||startLoad; endTime=value||(+new Date()); if(id!==0&&startTime!==undefined&&startTime!==null){ speed=endTime-startTime; }else if(id===0){ speed=endTime-1+1; } if(speed!==undefined){ this[key][id]=speed; } }, send:function(f2,f3,setting){ setting=setting||{}; var key=f2+'_'+f3,data=this[key],_arr=[]; if(!data||data.length<=0){ return false; } for(var i=1;i<data.length;i++){ if(data[i]){ _arr.push(i+'='+data[i]); } } var flags=[[f2,f3]],urls=[],copyTo=setting.copyTo; if(copyTo){ if($.isArray(copyTo[0])){ flags=flags.concat(copyTo); }else{ flags.push(copyTo); } } var i=0,cur,times=_arr.join('&'); for(;cur=flags[i++];){ urls.push("http://isdspeed.qq.com/cgi-bin/r.cgi?flag1=164&flag2="+cur[0]+"&flag3="+cur[1]+"&"+times); } var i=0,l=urls.length; for(;i<l;++i){ var imgSendTimePoint=new Image(); imgSendTimePoint.src=urls[i]; } this[key]=[]; }}; //237/240行傳入的參數:800160,1,51 $.returncode=function(flag1,flag2,flag3,sampling,delay){ sampling=sampling||100; //計算sampling值,每次計算的值可能不同 if(sampling<100){ if(Math.floor(Math.random()*100)>=sampling){ return; } //隨機數大於小於100的sampling時返回,這裏多是要求sampling不能過小(好比:1,2,3...,應該儘量的大一點,猜想多是QQ服務器這樣要求的) } sampling=Math.ceil(100/sampling); //取大於等於參數(100/sampling)的最小整數 delay=delay||0; //判斷賦值delay flag2=flag2||1; //判斷賦值flag2 var url="http://isdspeed.qq.com/cgi-bin/v.cgi?flag1="+flag1+"&flag2="+flag2+"&1="+sampling+"&2="+delay; //拼接URL if(flag3){ url+="&flag3="+flag3; } var imgSend=new Image(); //初始化Image對象 setTimeout(function(){imgSend.src=url},0); //指定Image對象的src } function ctest(msg){ //向層Console裏面添加指定內容的div var b=document.createElement('div'); b.innerHTML=msg; document.getElementById("Console").appendChild(b); }
Clinic.ISP={ key:{ //設置key屬性,裏面的參數固定 fast:'FAST', old:'OLD', store:'_store', isstart:'_isstart' }, _timeout:10000, //設置超時時間 test:function(callback){ //開始與服務器的測速 if(this[this.key.isstart]){ return false; } //this[this.key.isstart]==true時,返回至關於lock(object) this[this.key.isstart]=true; //設置this[this.key.isstart]=true表示開始執行 var that=this; //賦值that=this var dms=this.getDomains(), //獲取子域網址 startTime=+new Date(), fn=function(img){ if(dms.length){ setTimeout(function(){ that.request(dms.shift(),{complate:fn}); //執行request函數,傳入子域對象{domain:'ctc.'+'qzonestyle.gtimg.cn',isp:'ctc'}和{complate:fn} fn指當前函數,這樣函數內部在執行fn至關於遞歸 },0); }else{ that.fix(callback,{ //所有子域執行完成後執行提示是否返回朋友網 start:startTime, end:+new Date() }); } }; this._showMsg('正在爲您選擇更快的服務器,請耐心等候。'); fn(); //開始執行fn函數 }, fix:function(success,setting){ //所有子域執行完成後執行的函數,success->函數,setting->{start:startTime,end:+new Date()} setting=setting||{}; //初始化setting var fast=this[this.key.fast]; //獲取this.key.fast對象 if(fast){ //若是fast對象存在 success&&success(fast); //執行傳進來的函數:fn/callback var old={ //初始化old對象 isp:this.get(), cost:null }; this[this.key.old]=old; //本地存儲old對象 $.cookie('ptisp',fast.isp,{expires:1,path:'/'}); //本地cookie存儲參數:'ptisp',子域地址:'ctc.qzonestyle.gtimg.cn',{expires:1,path:'/'} this._statistic(old,fast,{ //執行_statistic函數參數分別是:old,fast,{start:setting.start,end:setting.end} start:setting.start, end:setting.end }); this._showMsg('已經爲您選擇了更快的服務器','success'); //提示正在測速 $.returncode(800160,1,51); //執行returncode函數請求數據 }else{ this._showMsg('對不起,彷佛您的電腦掉線了,選擇服務器操做沒法完成。','error'); //判斷fast若是不存在則可能斷網 $.returncode(800160,1,51); //執行returncode函數請求數據 } this.rest(); //初始化本地數據 }, get:function(){ //獲取本地cookie存儲的子域地址 var isp=$.cookie('ptisp'); return isp; }, //傳入子域對象{domain:'ctc.'+'qzonestyle.gtimg.cn',isp:'ctc'}和{complate:fn} request:function(domainInfo,config){ var _timeout=this._timeout; //設置超時時間 config=config||{}; //判斷賦值config this._showNowcheck(domainInfo); //顯示請求子域提示信息 var src='http://'+domainInfo.domain+'/qzonestyle/xiaoyou_portal_v1/img/logo_qbar_a0a48.gif'; //不一樣域請求的相同的圖片 PS:這裏是正題的開始 var img=new Image(), //初始化Image對象 start=+new Date(), //初始化啓動時間 that=this; var timer,timeStart=+new Date(); img.onload=function(){ //設置Image開始加載事件 var end=+new Date(); //初始化結束時間 var cost=end-start; //初始化時間差 this.onload=this.onerror=null; //清除Image對象的onload,onerror事件 clearTimeout(timer); //清除定時器 that._timeout=Math.min(that._timeout,cost); //比較超時時間和加載結束時間,返回相對小的值 config.complate&&config.complate(this); //執行傳過來的函數fn var rs={ //初始化re對象包括:isp->子域,domain->子域地址,error->是否出錯,cost->加載時間差,start->開始時間,end->加載完成時間 isp:domainInfo.isp, domain:domainInfo.domain, error:0, cost:cost, start:start, end:end }; that._saveResult(rs); //保存rs對象 }; img.onerror=function(d){ //設置Image加載出錯事件 this.onload=this.onerror=null; //清除Image對象的onload,onerror事件 clearTimeout(timer); //清除定時器 config.complate&&config.complate(this); //執行傳過來的函數fn var rs={ //初始化rs對象 isp:domainInfo.isp, domain:domainInfo.domain, error:d&&d.timeout?'timeout':'onerror' }; that._saveResult(rs); }; timer=setTimeout(function(){ img.onerror({timeout:true}); },_timeout+300); src=src+(src.indexOf('?')===-1?'?':'&')+'_='+(+new Date())+'&_='+Math.random(); img.src=src; }, _saveResult:function(data){ //賦值this.key.store,this.key.fast var key=this.key.store; this[key]=this[key]||[]; if(!data.error){ //若是error=0時,若是data.cost存在賦值this.key.fast this[key].push(data); var keyFast=this.key.fast, fast=this[keyFast]; if(data.cost){ if(!fast||data.cost<fast.cost){ //當this.key.fast對象存在時,若是新的服務器請求時間少於this.key.fast對象存儲的時間,則替換 this[keyFast]=data; } } } }, _getResult:function(){ var key='_rsstore'; return this[key]; }, getIsps:function(){ var l=['ctc','cnc','edu','cn','cm','os','']; return l;}, //返回子域前綴數組 getHosts:function(){ var h=['qzonestyle.gtimg.cn'];return h;}, //返回網站網址數組 getDomains:function(){ //返回組合子域與網站網址後的網站網址 var isps=this.getIsps(), //獲取子域前綴數組 hosts=this.getHosts(), //獲取網站網址數組 sr=[]; //組合後的網站網址 while(hosts.length>0){ var i=0,l=isps.length,cur; var h=hosts.shift(); //去除第一個數組對象,並將其從數組中刪除 for(;i<l;i++){ cur=isps[i]; sr.push({ //添加對象到數組中,組合後的數組對象爲:{domain:'ctc'+'qzonestyle.gtimg.cn',isp:'ctc'} domain:(cur?cur+'.':'')+h, isp:cur }); } } return sr; }, rest:function(){ //重置對象 this._timeout=10000; this[this.key.fast]=null; this[this.key.old]=null; this[this.key.store]=null; this[this.key.isstart]=null; }, _showMsg:function(msg,type){ //顯示提示信息,不過多介紹了,你們看看就應該能懂 var box=$('J_RS_ISP'); if(box){ if(type==='success'){ msg='\u221A '+msg; //√ }else if(type==='error'){ msg='\u00D7 '+msg; //× } box.className=type||''; box.innerHTML=msg; } }, _showNowcheck:function(info){ //顯示請求子域提示信息 $('J_Result').style.display=''; var box=$('J_RS_ISP'), spid='J_RS_ISP_DETAIL', sp=$(spid); if(!sp){ sp=document.createElement('p'); sp.setAttribute('id',spid); box.appendChild(sp); } sp.innerHTML=' '+info.domain; }, _statistic:function(old,now,pay){ old.cost&&$.speed.set(1,67,1,old.end,old.start); now.cost&&$.speed.set(1,67,2,now.end,now.start); pay.end&&$.speed.set(1,67,4,pay.end,pay.start); $.speed.send(1,67); var ispf1={ctc:800152,cnc:800153,edu:800154,cn:800155,cm:800156,os:800157,v6:800158}; var ispid={ctc:51,cnc:52,edu:53,cn:54,cm:55,os:56,v6:57}; var ispf2=old.isp===now.isp?1:2; ispf1=ispf1[old.isp]||8800159; ispid=ispid[now.isp]||58; $.returncode(ispf1,ispf2,ispid); } }; Clinic.Cache={ //指定Clinic對象Cache事件,清除緩存 clear:function(){ } };
但願有朝一日能把騰訊網站上的好東東都學會,若是能弄來騰訊的數據庫什麼的最好了 學習學習
數組