1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | <?php /** // youku plugin for Seyret component// * Content code * All rights reserved * Seyret Component is Free Software * Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * by kolidon: http://blog.treeber.com * @Copyright (C) 2008 kolidon@gmail.com */ // no direct access defined(’_VALID_MOS’) or die(’couldn\’t direct access’); $videodownloadsupport = “yes”; $downloadcachingnotimeout = “no”; $downloadcachingtimeout = “60″; function youkugetvideodetails($vidlink, $existingcode, $categorylist, $reqtype) { echo(”::”.$vidlink.”<br />”); global $database, $mosConfig_absolute_path, $mosConfig_live_site, $my; require_once($mosConfig_absolute_path . ‘/administrator/components/com_seyret/seyret_config.php’); // http://v.youku.com/v_show/id_cb00XMjEyMjUxOTY=.html // http://v.youku.com/v_show/id_XMzMyNzcxODA=.html if ($reqtype == “new”) { $vidlink = jalemurldecode($vidlink); $smallvideocode = str_replace(”http://v.youku.com/v_show/“, “”, $vidlink); $smallvideocode = str_replace(”http://www.youku.com/v_show/“, “”, $smallvideocode); // improved security not to call another site… $vidlink = “http://v.youku.com/v_show/” . $smallvideocode; } else if ($reqtype == “refresh”) { if ($vidlink == “”) { $vidlink = “http://v.youku.com/v_show/” . $existingcode; //trytoguess } } $videoservertype = “youku”; $pos = mb_strpos($vidlink, “id_”); $post = mb_strpos($vidlink, “.html”) - $pos; $smallvideocodestrip1 = mb_substr($vidlink, $pos, $post); $smallvideocodestrip1 = mb_eregi_replace(”id_”, “”, $smallvideocodestrip1); $smallvideocodestrip1 = mb_eregi_replace(”.html”, “”, $smallvideocodestrip1); $smallvideocode = $smallvideocodestrip1; $str = jalem_file_get_contents($vidlink); /* <meta name=”title” content=”谭谈交通成都兰博基尼”> <meta name=”keywords” content=”谭谈交通 成都 兰博基尼 ,原创”> <h1 class=”videoName bigTitle”>谭谈交通成都兰博基尼 <a href=”http://www.youku.com/channels_index/c_yc.html” target=”_blank” charset=”400-004-2″ class=”videoClass t_top”>[原创]</a> </h1> */ $pattern0 = ‘<meta name=”title” content=”‘; $pattern1 = ‘”>’; $pos = mb_strpos($str, $pattern0); $post = mb_strpos($str, $pattern1, $pos); $videotitle = mb_substr($str, $pos, $post - $pos); $videotitle = mb_eregi_replace($pattern0, ”, $videotitle, ‘i’); $videotitle = mb_eregi_replace($pattern1, ”, $videotitle); $videotitle = mb_eregi_replace(’\”;’, ”, $videotitle); $pattern0 = ‘<meta name=”keywords” content=”‘; $pattern1 = ‘”>’; $pos = mb_strpos($str, $pattern0); $post = mb_strpos($str, $pattern1, $pos); $videotags = mb_substr($str, $pos, $post - $pos); $videotags = mb_eregi_replace($pattern0, ”, $videotags, ‘i’); $videotags = mb_eregi_replace($pattern1, ”, $videotags); $videotags = mb_eregi_replace(’\”;’, ”, $videotags); $pattern0 = ‘<ul class=”videoInfo” id=”detail” style=”display:none”>’; $pattern1 = ‘<li>’; $pattern2 = ‘</li>’; $pos = mb_strpos($str, $pattern0); $post1 = mb_strpos($str, $pattern1, $pos); $post2 = mb_strpos($str, $pattern2, $post1); // exit(’we are here.’.$pos.’-’.$post1.’-’.$post2); $itemcomment = mb_substr($str, $post1, $post2 - $post1); // exit($itemcomment); $itemcomment = mb_eregi_replace($pattern1, ”, $itemcomment); $itemcomment = mb_eregi_replace($pattern2, ”, $itemcomment); // exit(’we are here1.’); $itemcomment = mb_eregi_replace(”>”, “”, $itemcomment); $itemcomment = mb_eregi_replace(”/”, “”, $itemcomment); $itemcomment = mb_eregi_replace(”\”", “”, $itemcomment); $pattern0= ‘<option value=”http://video\.myspace\.cn[^&]+&img=(http[^"]*)”>Myspace’; if(mb_eregi($pattern0, $str, $arr_thumb)>0) { $picturelink = urldecode($arr_thumb[1]); }; ; // http://so.youku.com/search_video/q_%E8%B0%AD%E8%B0%88%E4%BA%A4%E9%80%9A%E6%88%90%E9%83%BD%E5%85%B0%E5%8D%9A%E5%9F%BA%E5%B0%BC if ($reqtype == “new”) { $renderinputform = renderinputform_kolidon($vidlink, $picturelink, $videotitle, $itemcomment, $categorylist, $videoservertype, $smallvideocode, $videotags); return $renderinputform; } else if ($reqtype == “refresh”) { return array ($picturelink, $videotitle, $itemcomment); } else if ($reqtype == “newdirectadd”) { // by kolidon // to do: query the videoitem table to determine the $vidlink is no double $renderresult = savevideoitem_kolidon($vidlink, $picturelink, $videotitle, $itemcomment, $categorylist, $videoservertype, $smallvideocode, $videotags); return $renderresult; } } function youkuembed($vcode, $vthumb, $downloadcachingnotimeout, $downloadcachingtimeout, $pro, $catid, $setwidth = null, $setheight = null) { global $mosConfig_absolute_path, $mosConfig_live_site; require($mosConfig_absolute_path . ‘/administrator/components/com_seyret/seyret_config.php’); $dlink = “”; $unexpectederror = “”; $fullmd5cachefile = “”; $vdlink = “”; // exit($vocde.”vvv”); $vcode = jalemurldecode($vcode); $vidwindow = mosGetParam($_REQUEST, ‘vidwindow’, null); if ($vidwindow == “popup”) { $videowidth = $popupvideowidth; $videoheight = $popupvideoheight; } if ($setwidth > 0 AND $setheight > 0) { $videowidth = $setwidth; $videoheight = $setheight; } if ($pro == “1″) { $generatenewfile = “0″; if ($usevideoadsystem == “1″) { $subdir = “ad/”; } else { $subdir = “”; } // $vthumb=str_replace(”&”,”%26″,$vthumb); $cachefile = $mosConfig_live_site . “+youku+” . $vcode . $usevideoadsystem; $md5cachefile = md5($cachefile) . “.xml”; $fullmd5cachefile = $mosConfig_absolute_path . “/seyretfiles/cache/pro/youku/” . $subdir . $md5cachefile; $fullmd5cachefilesite = $mosConfig_live_site . “/seyretfiles/cache/pro/youku/” . $subdir . $md5cachefile; if (file_exists($fullmd5cachefile)) { if ($downloadcachingnotimeout <> “yes”) { $cache_file = fopen($fullmd5cachefile, “r”); while (!feof($cache_file)) { $buffer = fgets($cache_file, 1024); $dlink .= $buffer; } fclose ($cache_file); $pos = strpos($dlink, “<vdtime>”) + 8; $post = strpos($dlink, “</vdtime>”) - $pos; $timestamp = substr($dlink, $pos, $post); $now = date(’Y-m-d H:i:s’, time()); $nowdate = strtotime($now); $dltime = strtotime($timestamp); $cacheage = $nowdate - $dltime; $downloadcachingtimeoutseconds = $downloadcachingtimeout * 60; if ($cacheage >= $downloadcachingtimeoutseconds) $generatenewfile = “1″; } // end of checking cache file } else { $generatenewfile = “1″; } if ($generatenewfile == “1″) { $now = date(’Y-m-d H:i:s’, time()); $vcode = jalemurlencode($vcode); $dwnlink = youkugeneratevideodownloadlink($vcode, $pro, “embed”); if ($usevideoadsystem == “1″) { $videoadlink = generatevideoad($catid); $adxml = “<track> <title>Ad</title> <creator>admanager</creator> <location>” . $videoadlink . “</location> <image>” . $vthumb . “</image> </track>”; } $pos = strpos($dwnlink, “<prolink>”) + 9; $post = strpos($dwnlink, “</prolink>”) - $pos; $vdlink = substr($dwnlink, $pos, $post); $makedir = $mosConfig_absolute_path . “/seyretfiles/cache”; if (!is_dir($makedir)) { $oldumask = umask(0); mkdir ($makedir, 0755); umask($oldumask); } $makedir = $mosConfig_absolute_path . “/seyretfiles/cache/pro”; if (!is_dir($makedir)) { $oldumask = umask(0); mkdir ($makedir, 0755); umask($oldumask); } $makedir = $mosConfig_absolute_path . “/seyretfiles/cache/pro/youku”; if (!is_dir($makedir)) { $oldumask = umask(0); mkdir ($makedir, 0755); umask($oldumask); } $makedir = $mosConfig_absolute_path . “/seyretfiles/cache/pro/youku/ad”; if (!is_dir($makedir)) { $oldumask = umask(0); mkdir ($makedir, 0755); umask($oldumask); } $pos = strpos($vdlink, “HTML PUBLIC”); if ($pos > 0) $vdlink = “”; if ($vdlink <> “”) { $fh = fopen($fullmd5cachefile, ‘w’); $dlcachetext = “<playlist version=\”1\” xmlns=\”http://xspf.org/ns/0/\“> <title>Playlist</title> <vdtime>” . $now . “</vdtime> <trackList> ” . $adxml . ” <track> <title>Video</title> <creator>Seyret</creator> <location>” . $vdlink . “</location> <image>” . $vthumb . “</image> <meta rel=\”type\”>flv</meta> </track> </trackList> </playlist>”; fwrite($fh, $dlcachetext); fclose($fh); } $thevideo = $fullmd5cachefile; if (file_exists($thevideo)) { chmod ($thevideo, 0644); } } //end of generate new file if ($usevideoadsystem == “1″) { $repeat = “repeat=true”; } else { $repeat = “repeat=false”; } $embedvideo = “<embed src=\”" . $mosConfig_live_site . “/components/com_seyret/localplayer/seyretplayer.swf\” allowfullscreen=\”true\” height=\”" . $videoheight . “\” width=\”" . $videowidth . “\” type=\”application/x-shockwave-flash\” pluginspage=\”http://www.macromedia.com/go/getflashplayer\” flashvars=\”file=” . $fullmd5cachefilesite . “&image=” . $vthumb . “&showdigits=false&autostart=false&logo=” . $mosConfig_live_site . “/components/com_seyret/localplayer/logo.png&$repeat&usefullscreen=true&backcolor=0×000000&frontcolor=0xCCCCCC\”/>”; // end of pro } $pos404 = strpos($vdlink, “NotFound”); $unexpectederror = “”; if (!file_exists($fullmd5cachefile) AND $vdlink == “”) $unexpectederror = “1″; if ($pos404 > 0) $unexpectederror = “1″; if ($pro <> “1″ OR $unexpectederror == “1″) { // seyret is not pro, generate it in normal ways. /* <ul class=”pasteLink”> <li><span class=”label”>flash地址:</span> <input type=”text” id=”link” value=”http://player.youku.com/player.php/sid/XMjEyMjUxOTY=/v.swf” /><button onclick=”javascript:copyToClipboard(’link’);”>复制</button></li> <li><span class=”label”>html代码:</span> <input id=”link3″ type=”text” value=’<embed src=”http://player.youku.com/player.php/sid/XMjEyMjUxOTY=/v.swf” quality=”high” width=”480″ height=”400″ align=”middle” allowScriptAccess=”sameDomain” type=”application/x-shockwave-flash”></embed>’ /><button onclick=”javascript:copyToClipboard(’link3′);”>复制</button>< /li> </ul> */ $embedvideo = ‘<embed src=”http://player.youku.com/player.php/sid/’ . $vcode . ‘/v.swf” quality=”high” width=”‘ . $videowidth . ‘” height=”‘ . $videoheight . ‘” align=”middle” allowScriptAccess=”sameDomain” type=”application/x-shockwave-flash”></embed>’; } return $embedvideo; } function youkugeneratevideodownloadlink($vcode, $pro, $dltask) { global $database, $mosConfig_live_site, $mosConfig_absolute_path; $vtype = “youku”; $database->setQuery(”SELECT joomlaalemuserid FROM #__seyret_check”); $check = $database->loadObjectList(); foreach ($check as $check) { $joomlaalemuserid = $check->joomlaalemuserid; } $siteforjoomlaalem = $mosConfig_live_site; $siteforjoomlaalem = jalemurlencode($siteforjoomlaalem); if ($pro == “1″) { $pro_file = $mosConfig_absolute_path . “/administrator/components/com_seyret/sql/pro/spphp.php”; require_once($pro_file); $str = generateprodlink($vtype, $vcode); $pos = strpos($str, “<prolink>”) + 9; $post = strpos($str, “</prolink>”) - $pos; $dlink = substr($str, $pos, $post); $pos = strpos($str, “<dltype>”) + 8; $post = strpos($str, “</dltype>”) - $pos; $dtype = substr($str, $pos, $post); if ($dltask <> “embed”) { if ($dtype == “script”) { $downlink = “<script>self.location = \”" . $dlink . “\”;</script>”; } else if ($dtype == “save”) { $downlink = “<a href=\”" . $dlink . “\”>” . _RIGHTCLICKANDSAVE . “</a>”; } return $downlink; } else { return $str; } } else { $func = “generatedownloadlink”; $link = “http://www.joomla-alem.com/index2.php?option=com_joomlaalem&no_html=1&task=” . $func . “&siteinfo=” . $siteforjoomlaalem . “&jalemuserid=” . $joomlaalemuserid . “&vtype=” . $vtype . “&vcode=” . $vcode; $videodownloadlink = jalem_file_get_contents($link); return $videodownloadlink; } } ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | <?php /** * Content code * All rights reserved * Seyret Component is Free Software * Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * by kolidon * @Copyright (C) 2008 kolidon@gmail.com */ // no direct access defined(’_VALID_MOS’) or die(’couldn\’t direct access’); $videodownloadsupport = “no”; $downloadcachingnotimeout = “no”; $downloadcachingtimeout = “60″; function tudougetvideodetails($vidlink, $existingcode, $categorylist, $reqtype) { echo(”::”.$vidlink.”<br />”); global $database, $mosConfig_absolute_path, $mosConfig_live_site, $my; require_once($mosConfig_absolute_path . ‘/administrator/components/com_seyret/seyret_config.php’); // http://www.tudou.com/programs/view/HwIYJQczma4/ if ($reqtype == “new”) { $vidlink = jalemurldecode($vidlink); $smallvideocode = str_replace(”http://www.tudou.com/programs/view/“, “”, $vidlink); $smallvideocode = str_replace(”/”, “”, $smallvideocode); } else if ($reqtype == “refresh”) { if ($vidlink == “”) { $vidlink = “http://www.tudou.com/programs/view/” . $existingcode . “/”; //trytoguess } } $videoservertype = “tudou”; $str = jalem_file_get_contents($vidlink); $str = mb_convert_encoding($str, “UTF-8″, “GBK”); /* <div id=”player”> <div id=”playerObject”><h1>呼吸音 医学</h1></div> </div> */ $pattern0 = ‘<div id=”playerObject”><h1>([^<]*)</h1></div>’; if(mb_eregi($pattern0, $str, $arr_title)) $videotitle = $arr_title[1]; $pattern0 = “<ul class=\”info\”>.*?<li>标签:(<a href=[^>]*>[^<]+</a> ){0,10}</li>”; if(mb_eregi($pattern0, $str, $arr_videotags)){ $videotags = mb_ereg_replace(”标签:”,”",strip_tags($arr_videotags[0])); } $pattern0 = ‘<div id=”memos”>([^<]*)</div>’; if(mb_eregi($pattern0, $str, $arr_itemcomment)) $itemcomment = $arr_itemcomment[1]; //http://so.tudou.com/isearch.do?kw=%B0%AC%BE%C4 /* <a class=”inner” target=”new” title=”艾灸” href=”http://www.tudou.com/programs/view/zlAJthrl9sQ/“> <img width=”120″ height=”90″ class=”pack_clipImg” alt=”艾灸” src=”http://i01.img.tudou.com/data/imgs/i/021/628/123/p.jpg”/></a></div> <div class=”txt”> <h6 class=”caption”><a title=”艾灸” href=”http://www.tudou.com/programs/view/zlAJthrl9sQ/” target=”new”><span class=’highlight’>艾</span><span class=’highlight’>灸</span></a> </h6> <ul class=”info”> <li>时长: 01:18</li> */ $vidlink2 = ‘http://so.tudou.com/isearch.do?kw=’ . $videotitle; $vidlink2 = mb_convert_encoding($vidlink2, “GBK”, “UTF-8″); $str2 = jalem_file_get_contents($vidlink2); $str2 = mb_convert_encoding($str2, “UTF-8″, “GBK”); $pattern0 = ‘<a class=”inner” .*? title=”‘.$videotitle.’” href=”http://www.tudou.com/programs/view/’.$smallvideocode.’/”>[^\f]*?<img .*? src=”([^"]*)”[^\f]*?时长:(.*?)</li>’; if(mb_eregi($pattern0, $str2, $arr_thumb)) { $picturelink = urldecode($arr_thumb[1]); $videotime = $arr_thumb[2]; //留作扩展 }; if ($reqtype == “new”) { $renderinputform = renderinputform_kolidon($vidlink, $picturelink, $videotitle, $itemcomment, $categorylist, $videoservertype, $smallvideocode, $videotags); return $renderinputform; } else if ($reqtype == “refresh”) { return array ($picturelink, $videotitle, $itemcomment); } else if ($reqtype == “newdirectadd”) { // to do: query the videoitem table to determine the $vidlink is no double $renderresult = savevideoitem_kolidon($vidlink, $picturelink, $videotitle, $itemcomment, $categorylist, $videoservertype, $smallvideocode, $videotags); return $renderresult; } } function tudouembed($vcode, $vthumb, $downloadcachingnotimeout, $downloadcachingtimeout, $pro, $catid, $setwidth = null, $setheight = null) { global $mosConfig_absolute_path, $mosConfig_live_site; require($mosConfig_absolute_path . ‘/administrator/components/com_seyret/seyret_config.php’); $dlink = “”; $unexpectederror = “”; $fullmd5cachefile = “”; $vdlink = “”; $vcode = jalemurldecode($vcode); $vidwindow = mosGetParam($_REQUEST, ‘vidwindow’, null); if ($vidwindow == “popup”) { $videowidth = $popupvideowidth; $videoheight = $popupvideoheight; } if ($setwidth > 0 AND $setheight > 0) { $videowidth = $setwidth; $videoheight = $setheight; } $pos404 = strpos($vdlink, “NotFound”); $unexpectederror = “”; if (!file_exists($fullmd5cachefile) AND $vdlink == “”) $unexpectederror = “1″; if ($pos404 > 0) $unexpectederror = “1″; if ($pro <> “1″ OR $unexpectederror == “1″) { $embedvideo = ‘ <object width=”‘.$videowidth.’” height=”‘.$videoheight.’”> <param name=”movie” value=”http://www.tudou.com/v/’.$vcode.’”></param> <param name=”allowScriptAccess” value=”always”></param> <param name=”wmode” value=”transparent”></param> <embed src=”http://www.tudou.com/v/’.$vcode.’” type=”application/x-shockwave-flash” width=”‘.$videowidth.’” height=”‘.$videoheight.’” allowFullScreen=”true” wmode=”transparent” allowScriptAccess=”always”></embed> </object> ’; } return $embedvideo; } function tudougeneratevideodownloadlink($vcode, $pro, $dltask) { global $database, $mosConfig_live_site, $mosConfig_absolute_path; $vtype = “tudou”; $database->setQuery(”SELECT joomlaalemuserid FROM #__seyret_check”); $check = $database->loadObjectList(); foreach ($check as $check) { $joomlaalemuserid = $check->joomlaalemuserid; } $siteforjoomlaalem = $mosConfig_live_site; $siteforjoomlaalem = jalemurlencode($siteforjoomlaalem); if ($pro == “1″) { $pro_file = $mosConfig_absolute_path . “/administrator/components/com_seyret/sql/pro/spphp.php”; require_once($pro_file); $str = generateprodlink($vtype, $vcode); $pos = strpos($str, “<prolink>”) + 9; $post = strpos($str, “</prolink>”) - $pos; $dlink = substr($str, $pos, $post); $pos = strpos($str, “<dltype>”) + 8; $post = strpos($str, “</dltype>”) - $pos; $dtype = substr($str, $pos, $post); if ($dltask <> “embed”) { if ($dtype == “script”) { $downlink = “<script>self.location = \”" . $dlink . “\”;</script>”; } else if ($dtype == “save”) { $downlink = “<a href=\”" . $dlink . “\”>” . _RIGHTCLICKANDSAVE . “</a>”; } return $downlink; } else { return $str; } } else { $func = “generatedownloadlink”; $link = “http://www.joomla-alem.com/index2.php?option=com_joomlaalem&no_html=1&task=” . $func . “&siteinfo=” . $siteforjoomlaalem . “&jalemuserid=” . $joomlaalemuserid . “&vtype=” . $vtype . “&vcode=” . $vcode; $videodownloadlink = jalem_file_get_contents($link); return $videodownloadlink; } } ?> |
WEB应用程序的性能提升和应用编码同样重要,它往往在设计上应一并考虑,然后在编码工作整体完成时花大量精力来调整,kolidon近一年在此问题上殚精竭虑并略有心得。
众所周知,对代码的细微调整常常有显著作用,在LAMP平台上,使用xdebug+cachegrind这样的profiling工具是最佳选择,在ASP.NET应用中,系统自带的DEBUG功能已经非常强大。而本文讨论范围不仅限于代码优化和profiling。
1. MYSQL/MSSQL数据库优化
在WEB2.0时代,数据库服务器面临重大挑战,在典型的社区平台应用中,数据库查询基本上在每一次页面请求发生多次,在这里,数据库服务器的磁盘性能基本上是决定一切的关键。但基本上,一台一般服务器(双xeon5210+4G内存量级),每秒数千次查询勉强能应付高峰时段一千至两千次页面请求,若应用量级更大,对MYSQL来说,采用双机或三机主从结构,分离读写是第一步选择,对MSSQL来说,目前能见到的公开资料和应用讨论并不多,但在某个开源应用DNN与MSSQL SERVER EXPRESS的结合,有令人惊讶的效率;
2.查询语句优化,简化SQL语句,减少关联查询、索引、减少全表扫描次数(MSSQL 尽量使用存储过程)
统计每一类可能出现的查询并记录到专门编程日记上以对在可能是优化之,国内几家CMS厂商对这一类话题有较多的贡献,特别是在MYSQL数据库架构和SQL查询优化的细节上(但我更相信是出自一些大型厂商如IBM的资料整理工作);
3.程序中间代码编译缓存(这一点上,ASP.NET完胜)
OP码缓存功能如apc、Eacc、Xcache一定要开启,据kolidon反复测试,在IIS平台下首选eacc,稳定性不错,性能可以接受,Linux/Unix平台首选Xcache,性能超强(很多专用的WEB2.0应用将20ms当作目标,这一条和下一条经验比较关键);
4.程序内cache
在经验2中,我们已经提到每一条可能发生的查询都应该被记录,当然,此处就是尽可能的缓存结果了,在专用应用如discuz中,所有能够被缓存的对象均已被缓存,因此,不论系统访问量多么巨大,查询数量都能维持在很代的水平,而每次查询确实非常简洁,缓存的destroy和generate策略被精心设计,在每一次查询前后被核对,事实证明,这已经成为当前专有WEB应用的基本设计原则。
而开放框架应用所遭遇的最大挑战,在于插件生成的查询方式和数目完全不可控——在drupal及joomla一类的开放构架应用中,查询数量关系一切。因此,kolidon以为,在开放框架应用的设计上,也应有类似准则和规范以控制查询数目,这个规范,我有空时将专门讨论,当然,还会有小技巧如:kolidon——修改数据库类,建立SELECT查询的缓存策略(待撰写);
5.不要忽略浏览器HTTP请求顺序——重视HTTP请求顺序和速度
一般来说,若核心内容已经被输出,则它的格式应该在无js及css的情况下即具有一定可读性(那么,少量的内嵌CSS和JS代码可以被接受),而随后的CSS和JS,因一般采用标准的框架,代码量相对较大,会需要被外挂,外挂前,首先当然是合并以消来多余的请求,不少工具可以帮助我们做到这一点。甚至,有一套名为PHP_SPEEDY的应用,可以通过直接在当前应用内嵌入指定代码发挥作用,它可以自动合并的有js请求,合并所有css请求,自动压缩,并设置过期时间(原理是扫描母应用中的相应字串,读文件并生成特殊唯一的文件名)。而在ASP.NET的开源应用中,有些框架如DNN自行管理UI元件,用一套精心设计的机制来决定何时分发何种JS及CSS,效果也不错。
最关键的,IE浏览器会有并发HTTP请求的限制,这使大量HTTP请求需要更长的时间完成;
6.页面内容的代码顺序也很重要——重视浏览器生成页面的速度
我们需要仔细审核TEMPLATE(虽然程序部分的TEMPLATE分析器的选择也很重要——smarty或者pattemplate都不错),这一般是考虑到制作者更侧重于UI设计而可能忽略浏览器显示效率这个基本面——减少图片数目,审核所有HTML代码以确定浏览器能够顺利地绘制(简单而言,就是不要套太多层表格、不要使用太大的图片作为修饰,不要在页面上使用JS或CSS做过我的特殊显示效果等)。
另外,若必要,所有背景图片应合并成单张图并使用position属性以仅使用图片中的不同位置,这样,图片总大小不变或减小,而请求数大大减少(关于5和6,YAHOO性能团队有一个名为YSlow的插件及配套的“性能优化XX条准则”,基本上,能够解决这方面的一切问题)。
好吧,行文至此,我得承认,WEB应用的本质就是HTTP请求,因此,题目仅仅是夸张地表述。
7.最后,你在使用什么WEBSERVER呢?
OK,kolidon自己在某台服务器上使用的是IIS6+PHP+FASTCGI+ASP.NET2,数据库用MSSQL SERVER EXPRESS2005,因为有不少旧的应用需要运行在这个平台上,但几年来,遭遇的问题多不胜数——当然,管理员经验丰富能避免一些,并且你知道,这些问题都是可以解决的,只是每次解决后,问题总会再次出现,然后,你没办法知道究竟是因为因而造成了恶果。而能够提供解决办法的来源仅此一家(也可以用google去和大量的垃圾站长分享他们的未作保证的文献),而IIS与系统其他组件有太多的耦合。
关于IIS的不满主要有:1) URL REWREITER(有两个,一个商业的有免费应用,一个开源的但稳定性欠佳,另外,ASP.net似乎已经解决了些问题)。2) 配置文件metabase.xml文件的读写API及可靠性,这个集中式的配置文件很大,我的几年下来有两次损坏经历,解决办法是重装IIS然后恢复以前的备份),而读写API仅有少量商业软件的实现。3) 安全设置和应用程序池回收也让人迷惑:默认的,WINDOWS2003需要更改大量系统文件夹的权限以减少通过WEB被攻击的机会:上传木马-权限提升-系统被爆,而应用程序池这个发明或需进一步加强稳定性和性能(有专门文章讨论IIS6下的虚拟主机设置,特别是ASP.NET虚拟主机设置,但我更愿意在专门时间研究微软的所有默认帐户的权限问题)。4)辅助工具欠缺,比如集成的负载均衡和反向代理等。
IIS7已经释出多时,国外的虚拟主机提供商已有win2008+IIS7平台,据说对nix平台上的WEB服务器思路多有借鉴.
因此,如果可能,Apache/Lighttpd/Nginx+FASTCGI+PHP可能会是上佳选择,当然,除了性能、简洁,更重要的是,我们总有无数的工具可以帮助我们找到和解决问题,如,LVS、Squid一类负载均衡,反向代理,Memcached一类的专用缓存服务器。还有,无尽的开源应用。
我的开发平台上的配置是:Ubuntu sever,Nginx+PHP(fastcgi)+fpm+Xcache+Memcache,运行Memcached+Mysqld守护程序。
据信,金山的爱词霸社区应该是Apache双机负载均衡(来源:该项目组某成员博客)。
如下为kolidon的看家法宝:
有几种编辑器:
Editplus、Notepad++、Ultraedit、VS express、eclipse for php
有几大浏览器
IE
firefox
opera
safari
有对应的调试工具
Httpwatch、IE developer Toolbar、Companion.JS
firebug、Yslow、DOM Inspector、Web Developer
有专用的协议包捕捉工具和HTTP 捕捉工具
Ethereal、Fiddle
还有HTML及CSS工具
HTMLTIDY、http://validator.w3.org/、http://jigsaw.w3.org/css-validator/
有下载工具:
flashget早期版本(有时用来做些不能宣诸于口之事,比迅雷合适)
有系统平台:
win2003、win2008、Ubuntu、Centos
还有系统辅助:
MS Toolkits(Sysinternals)、VNC Vewer、putty
有WEB服务器及配套软件:
IIS6、IIS7、APACHE、LightHTTP、Nginx、.NET framwork、PHP、Python、fastcgi、php-fpm、Server-U、wu-ftpd
有数据库管理:
EMS系列软件、PHPmyAdmin
最后,最有用的其实是:
Photoshop、Office中的excel
一、传统的css方法
在目标对象前后分别加三个块对象,每个对象用css绘出圆角的一个效果——共3px高——短连续线、中间留白两边内缩进2px宽为2px的左右边框、中间留白两边内缩进1px宽为1px的左右边框。
<div class="rg_1"/><div class="rg_2"/><div class="rg_3"/>
<div class="rg"> 医学视频</div>
<div class="rg_4"/><div class="rg_5"/><div class="rg_1"/>
<style type="text/css">
.rg{border-left:1px solid #A5DA94;border-right:1px solid #A5DA94;zoom:1;padding-bottom:1px;background:#DBF1D4}
.rg_1,.rg_2,.rg_3,.rg_4,.rg_5{height:1px;overflow:hidden;font-size:0px;margin:0 1px;border:0px solid #A5DA94;}
.rg_1{background:#A5DA94;margin:0 3px; }
.rg_5,.rg_2{border-left-width: 2px;border-right-width:2px}
.rg_4,.rg_3{border-left-width: 1px;border-right-width:1px}
.rg_4,.rg_5,.rg_2,.rg_3{background:#DBF1D4;}
</style>
效果如下:
二、最省事的背景图办法
1. 直接使用单张背景图(但目标对象的大小要严格限定);
2. 添加上级对象,上级对象使用圆角背景图的左侧,目标对象使用圆角背景图的右侧,如下代码使用此方案:
<ul class="mainlevel" id="ja-splitmenu">
<li><a href="/pictures"><span>医学图谱大全</span></a></li>
<li><a href="/videos"><span>医学动画和视频</span></a></li>
</ul>
<style type="text/css">
#ja-splitmenu li {
margin: 0;
padding: 0;
display: inline;
}#ja-splitmenu a {
float: left;
margin: 0 2px;
padding: 0 0 0 4px;
background: url(/templates/web/images/tableft.gif) no-repeat top left;
text-decoration: none;
text-align: center;
}#ja-splitmenu a span {
float: left;
padding: 7px 15px 6px 11px;
display: block;
background: url(/templates/web/images/tabright.gif) no-repeat top right;
color: #666666;
}
</style>
效果如下:
三、最省事的JS方案
使用脚本在目标对象前后添加如方案一中所述的可被css修饰的元素。实际上,Jquery中的圆角矩形插件 jQuery Corner和其他类似圆角矩形就是如此实现的。
可以简单到一行代码:$(this).corner();
说到Jquery,这儿有15分钟上手的指南:
http://www.blueidea.com/tech/web/2007/4993.asp
TerryLee在博客上转介了Jquery的240个插件大全:
http://www.cnblogs.com/Terrylee/archive/2007/12/09/the-ultimate-jquery-plugin-list.html#Post
……
过程往往人各不同——我们生活在多样化的世界。

关注WEB应用系统架构,侧重效能、可用性研究。欢迎访问treeber.com查看本站整理自网络的非原创精华(筹建中)。