好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

高性能Web站点技巧原理

大型网站关键技术介绍 1.pv(pageviews),访问量大 带来问题 a.流量大10000000*2m-解决方案买带宽,优化程序(处理图片) b.并发量,同时访问网站的人多.,解决方案 对程序的架构重新设计.-服务器集群示意图: 1.数据量大-10亿记录 解决方法是 a.表的设计合理 b.分表

大型网站关键技术介绍

1. pv值(page views),访问量大

带来问题

a. 流量大 10000000*2m ->解决方案 买带宽 ,优化程序(处理图片)

b. 并发量,同时访问网站的人多.,解决方案

对程序的架构重新设计.->服务器集群 示意图:

1. 数据量大->10亿记录

解决方法是

a. 表的设计合理

b. 分表技术(垂直分割,水平分割) c. 建立索引 d. 读写分离 e. mysql配置优化(调整最大并发量,定时对数据库碎片整理,备份 crontab) f.硬件升级)

c. 页面静态化

d. 缓存技术(memcached)


页面静态化

简单解释一下页面静态化:




看几个概念,然后写代码:

静态网址: 比如 http://localhost/abc.html 即,如果我们访问的页面是静态页面,我们把这个url称为静态网站.

特点: 1. 利用seo (search engine optimization) 搜索引擎优化2. 访问速度快 3. 防止sql注入

http://localhost/index.php?u=xx&p=/*11288 */

如果我们写程序 loginCheck.php

[php] view plaincopy

"font-family:SimSun;font-size:14px;" > $id = $_GET [‘id’]; $pwd = $_GET [‘pwd’]; $sql =”select pwd from users where id= $id ”; $res =mysql_query( $sql ); if ( $pwd = = =从数据库中取出的密码){ //说明该用户存在   } else {    //说明用户密码错误!   }


动态网址 :比如 http://localhost/news.php?id=112 , 即,访问的是一个PHP页面,可以传入参数.称为动态网之.

特点: 1. 不利用SEO 2. 访问速度慢 3. 有被注入sql可能

伪静态网址 : 在实际开发中,我们希望达到这样目的,把下面的网址

http://localhost/ news.php?lang=cn&class=sprot&id=2

修改成如下网址

http://localhost/news-cn-sport-id2.html

上面的网址,我们称为伪静态网址 :

特点: 1. 利用SEO 2. 防止注入 3. 他任然要访问数据库,速度没有变化

页面静态化技术分类:

从方式看(1. 真静态 2.伪静态)

从范围看(1.全局静态2. 局部静态化[ajax+jquery])


压力测试工具 ab.exe


介绍一款测试压力的工具 该工具程序是apache自带的, 大家在工作中可以使用该工具来测试自己的网站并发量大小,和某个页面的访问时间

基本用法,进入到cmd 控制台

ab.exe –n 访问的总次数 –c 有多少人访问(并发量) 访问的页面url

举例说明:

ab.exe –n 10000 –c 100 http://locahost/test.php

当我们把 –c 调整到1000时,发现apache瘫痪. 给大家说下如何调整apache的最大并发量.

MPM (多路处理模块, 即 apache采用怎样的方式来处理并发.), 主要有三种方式

1. perfork 预处理进程方式

2. worker 工作模式

3. winnt 这个一般说是windows采用的.

原理示意图:

u 如何设置我们的apache的最大并发数 ,步骤如下:

(1) 在httpd.conf 文件中 修改

# Server-pool management (MPM specific)

Include conf/extra/httpd-mpm.conf

(2) 确定当前的apahce是什么MPM模式

进入到 apache/bin

httpd.exe –l

说明: 看 mpm_xxx.c 如果xxx是 winnt 说明是winnt ,另外还可能是 perfork 或者 worker

(1) 修改httpd-mpm.conf 文件.

ThreadsPerChild 1000

MaxRequestsPerChild 0

(2) 重启apahce ,测试

因为在linux下,一般说采用的MPM是 perfork模式,我们看看如何配置.

StartServers 5

MinSpareServers 5

MaxSpareServers 10

MaxClients 150 #并发量

MaxRequestsPerChild 0 #一个进程对应的线程数,对 worker更用.

给大家一个合理的建议配置. 对大部分网站,中型网站,配置:



StartServers 5 #预先启动
MinSpareServers 5
MaxSpareServers 10 #最大空闲进程
ServerLimit 1500 #用于修改apache编程参数
MaxClients 1000 #最大并发数
MaxRequestsPerChild 0

如果你的网站pv值 百万

ServerLimit 2 500 #用于修改apache编程参数
MaxClients 2000 #最大并发数

最后有一个关于html和php的访问效率图 :


分享一下页面seo技巧:

如果一个图片希望被百度到

在网站前台,我们建议 不要使用frame框架,不利用seo

如果我们给图片或者视频取名字,尽量简短.

页面静态化的技术实现有两种方式

1. 使用PHP自己的缓存机制

先说明一下OB缓存的机制.

ob1.php 代码:说明的ob的各个用法->项目中

ob2.php 代码,说明了浏览器缓存存在.



说明: 在php5.2这个版本 在php.ini有一个配置 output_buffering ,默认是关闭,如果是关闭,这刚才的代码就会警告.

? 如何打开ob缓存

① 配置php.ini 文件 output_buffering = 4096

② 直接在程序中 ob_start();

1. 使用模板替换技术实现(正则表达式)

使用ob缓存机制,完成一个简单的新闻管理系统-页面静态化(目标是实现全站静态化)


开发步骤:

(1) 做的页面:


(1) 简单的分析页面

(2) 创建数据表

create table news(

id int unsigned primary key auto_increment, /*新闻id,做成自增*/

title varchar(128) not null default ‘’, /*标题*/

content varchar(256) not null default ‘’, /*新闻内容*/

filename varchar(32) not null default ‘’ /*将来这个新闻对应静态页面*/

) engine=MyISAM charset utf8

测试数据:

insert into news (title,content) values('hello1','北京你好');

insert into news (title,content) values('hello2','四川你好');

(3) 走码

到此,我们已经实现了传统的查询任务,

分析代码后,我们发现问题是,因为新闻内容相对稳定,所以没有必要每次都查询。优化的思路是: 当第一人查看某个新闻时,我们就生成一个对应的静态页面,当后面的人在查看,直接返回该静态页面即可.

代码实现:

newsList.php 代码 showNews.php代码


再想想,上面的代码缺点是什么?

cms(内容管理系统,新闻,软件发布, 文章管理) 内容就固定不变,我们不能接受.

解决方案:

1 我设一个超时,30s, 我们保证30内不去修改,超过30秒,就更新一把.

走码:

2 上面的解决方案有时间延时,所以如果我们希望静态化没有时间延时,就应该使用模板提换技术来搞定.

思路: 图.





代码实现:整理

newslist.php


addnews.html页面


newsAction.php 页面


思考题:

① 请大家完成更新新闻的这个页面静态处理

② 如何把newsList.php 也做成一个静态页面.->思想

任务是: 把新闻管理系统的首页面也静态化.

通用的CMS系统的示意图:


对我们的新闻管理系统首页静态化

思考: 我们能不能再添加新闻后,就直接静态化首页面, 如果你的确希望只要首页的内容有变化,就立即更新,最后的代理整理:

把所有的动态页面,放入到manage文件夹:

manage.html

[html] view plaincopy

span style = "font-family:SimSun;font-size:14px;" > html > head > meta http-equiv = 'content-type' content = 'text/html;charset=utf-8' /> head > h1 > 管理新闻 h1 > hr /> a href = 'addNews.html' > 添加新闻 a > | a href = 'newsList.php' > 更新首页 a > | a href = 'xxx.php' > 列出所有信息 a > html > addNews.html head > title > 新闻标题 title > meta http-equiv = "content-type" content = "text/html;charset=utf-8" /> head > form action = "newsAction.php" method = "post" > table > tr > td > 新闻标题 td > td > input type = "text" name = "title" /> td > tr > tr > td > 新闻内容 td > td > textarea cols = "50" rows = "10" name = "content" > textarea > td > tr > tr > td > input type = "submit" value = "添加" /> td > td > input type = "reset" value = "重新填写" /> td > tr > input type = 'hidden' name = 'oper' value = 'add' /> table > form > html > span >


newsAction.php

[php] view plaincopy

"font-family:SimSun;font-size:14px;" > //处理用户的添加/更新/删除...请求 //先获取 oper值 $oper = $_POST [ 'oper' ]; if ( $oper === 'add' ){ //接收用户的新闻的各个信息 $title = $_POST [ 'title' ]; $content = $_POST [ 'content' ]; //把新闻添加到数据库 //这里大家可以使用工具类完成. $con =mysql_connect( "localhost" , "root" , "root" ); if (! $con ){ die ( "连接失败" ); } mysql_select_db( "newssys" , $con ); $sql = "insert into news values(null,'$title','$content','')" ; //echo $sql; if (mysql_query( $sql , $con )){ //生成静态文件. $id =mysql_insert_id(); $html_filename = 'news-id' . $id . '.html' ; $html_fp = fopen ( "" . $html_filename , 'w' ); //把模板文件读取. $fp = fopen ( 'news.tpl' , 'r' ); //循环读取 //如果没有读到文件的最后,就一直读取 while (! feof ( $fp )){ //一行行读. $row = fgets ( $fp ); //把占位符替换掉->小函数 myreplace //问题? $row = str_replace ( '%title%' , $title , $row ); $row = str_replace ( '%content%' , $content , $row ); fwrite( $html_fp , $row ); } //关闭文件 fclose( $html_fp ); fclose( $fp ); echo "恭喜你,添加成功管理新闻" ; //怎样让首页面立即更新. include "newsList.php" ; } else { die ( '添加失败' ); } } else if ( $oper === 'update' ){ } else if ( $oper === 'delete' ){ }


newsList.php

[php] view plaincopy

"font-family:SimSun;font-size:14px;" > //列出新闻列表 //这里,我使用最简单的方法来操作,没有使用mvc模式 //这里你们可以使用工具类完成. db.class.php $con =mysql_connect( "localhost" , "root" , "root" ); if (! $con ){ die ( "连接失败" ); } mysql_select_db( "newssys" , $con ); $sql = "select * from news" ; $res =mysql_query( $sql , $con ); ob_start(); echo " " ; echo "

新闻列表 " ; echo " " ; echo " id 标题 查看详情 修改新闻 " ; //循环的取出新闻列表 while ( $row =mysql_fetch_assoc( $res )){ echo ' ' . $row [ 'id' ]. ' ' . $row [ 'title' ]. ' . $row [ 'id' ]. '.html">查看详情 修改页面 ' ; } echo " " ; $str_ob =ob_get_contents(); file_put_contents ( 'index.html' , $str_ob ); //这里关闭资源. //清空ob ob_clean(); echo "恭喜你,首页面更新成功点击查看最新新闻列表" ; mysql_free_result( $res ); mysql_close( $con );


完毕,大家可以进一步深入的完成修改和删除.

真静态的优缺点分析

优点: 1. 利用SEO 2. 访问速度快. 3. 防止sql注入

缺点: 1. 因为真静态会生成大量的html文件,占用磁盘空间, 如果你把所有的静态页,都放在同一文件夹,寻找文件的速度随着文件的增多,速度变慢,因此可以考虑创建子文件夹来放.

在以下情况不建议使用真静态:

1.实时性要求高的网站或者页面.(股票、基金)

2.数据量大,同时查询一次后,以后很少查询(国家学历认证网,电信话费查询系统.)

3.不愿意被seo到的页面或者网站

伪静态技术

在我们实际开发中,有需要,不希望使用真静态., 但是有希望利于SEO,可以考虑使用伪静态.

http://localhost/news.php?type=music&id=100

我们希望这个地址可以用下面的访问url来替换

http://localhost/news-music-id100.html

上面的问题可以使用伪静态

1. 实现方式有 直接使用正则表达式来完成

2. 使用apache自带的rewrite机制来完成

看需求:

http://localhost/content.php/1,122,8912.html

我希望上面的地址

http://localhost/content.php?a=1&b=122&c=8912

实现思路:

1. 我们可以使用str 函数,来进行分割处理->可行,但是不够灵活

2. 使用正则来处理

代码是:

[php] view plaincopy

"font-family:SimSun;font-size:14px;" > $path_info = $_SERVER [ 'PATH_INFO' ]; $reg = '/(\d+),(\d+),(\d+)\.html$/i' ; preg_match( $reg , $path_info , $res ); echo "
"  ;      
     print_r( $res  );      
      echo     " 
" ;


在实际开发中,我们实现伪静态,用的更多的还是rewrite 机制,但是他任然是以正则技术为基础的.

我们看看如何实现:

说明:

比如 http://www.hsp.com/news.php?type=music&id=100

希望上面的url 变成

http://www.hsp.comt/news-music-id100.html

原理图


步骤开始:

(1) 启用rewrite模块,在默认情况下,没有启用

修改httpd.conf文件

#启动rewrite模块

LoadModule rewrite_module modules/mod_rewrite.so

确认是否启动成功

(2) 配置我们的虚拟主机

httpd.conf 打开虚拟主机的配置文件

# Virtual hosts

Include conf/extra/httpd-vhosts.conf

修改 httpd-vhost.conf

[plain] view plaincopy

DocumentRoot "C:/myenv/apache/htdocs/static2" #Directory配置节点,用于指定该目录下的文件或是图片.的访问权限 #设置虚拟主机的错误页面,欢迎页面


(1) 在hosts文件中,配置ip和主机的对应关系

127.0.0.1 www.hsp.com

(2) 这时我们访问 http//www.hsp.com/news.php

我们可以访问到该页面.

? 一个重要的知识点:

在apache服务器中,如果某个文件夹,没有指定访问权限,则以上级目录的权限为准,如果他自己指定了访问权限,则以自己的为准.

请注意,在配置访问权限的时候,顺序很重要:

#Order allow,deny 表示先看allow ,在看deny,留下的就是可以访问

Order deny,allow

Deny from all

allow from 127.0.0.1

(3) 关于 节点配置必须掌握

比较完整的配置文件

第一种配置方式

DocumentRoot "C:/myenv/apache/htdocs/static2"

#Directory配置节点,用于指定该目录下的文件或是图片.的访问权限

#设置虚拟主机的错误页面,欢迎页面

ServerName www.hsp.com

#这里可以指定是否让人访问

#Allow from all

#是否列出文件目录结构

# 如果希望列出 indexes 不希望 none

#Options indexes

#如何配置网站的首页面

DirectoryIndex abc.html abc2.html

#如何配置404错误页面,引导用户引入新页面

errorDocument 404 /404.html

#配置我们的rewrite规则

RewriteEngine On

#rewrite的规则 如果 aaa.html 就跳转到news.php

#$1 表示反向引用,第一个子表达式的内容

#说明如果在正则规范中直接引用子表达式的内容,则使用\n

#如果是在后面因为,则使用$n

RewriteRule news-([a-zA-Z]+)-id(\d+)\.html$ news.php?type=$1&id=$2

特别说明: 容易犯的错误,一定要记住启用rewrite模块.


思考: 上面我们配置都要去修改 httpd-vhost.文件,但管理员不给你这个权限,怎么办?

思路: 可以把配置,写到 .htaccess文件.

第二种配置方式: 即把一部分配置放在 http-vhost.conf 文件, 把rewrite 规则放在 .htaccess

DocumentRoot "C:/myenv/apache/htdocs/static2"

#Directory配置节点,用于指定该目录下的文件或是图片.的访问权限

#设置虚拟主机的错误页面,欢迎页面

ServerName www.hsp.com

#这里可以指定是否让人访问

#Allow from all

#是否列出文件目录结构

# 如果希望列出 indexes 不希望 none

#Options indexes

#如何配置网站的首页面

DirectoryIndex abc.html abc2.html

#如何配置404错误页面,引导用户引入新页面

errorDocument 404 /404.html

#如果你配置了allowoverride all 这表示到对应的目录的.htaccess去匹配规则

allowoverride all

在对应的文件下 .htaccess文件

#如果rewrite 模块启用

#配置我们的rewrite规则

RewriteEngine On

#rewrite的规则 如果 aaa.html 就跳转到news.php

#$1 表示反向引用,第一个子表达式的内容

#说明如果在正则规范中直接引用子表达式的内容,则使用\n

#如果是在后面因为,则使用$n

RewriteRule news-([a-zA-Z]+)-id(\d+)\.html$ news.php?type=$1&id=$2

#RewriteRule aaa.html news.php

请注意: 项目中的 .htaccess文件的配置也是继承管理

第三种配置方法:

http-vhost.conf

DocumentRoot "C:/myenv/apache/htdocs/static2"

#Directory配置节点,用于指定该目录下的文件或是图片.的访问权限

#设置虚拟主机的错误页面,欢迎页面

ServerName www.hsp.com

#如果你配置了allowoverride all 这表示到对应的目录的.htaccess去匹配规则

allowoverride all

.htacces文件

#这里可以指定是否让人访问

#Allow from all

#是否列出文件目录结构

# 如果希望列出 indexes 不希望 none

#Options indexes

#如何配置网站的首页面

DirectoryIndex abc.html abc2.html

#如何配置404错误页面,引导用户引入新页面

errorDocument 404 /404.html

#如果rewrite 模块启用

#配置我们的rewrite规则

RewriteEngine On

#rewrite的规则 如果 aaa.html 就跳转到news.php

#$1 表示反向引用,第一个子表达式的内容

#说明如果在正则规范中直接引用子表达式的内容,则使用\n

#如果是在后面因为,则使用$n

RewriteRule news-([a-zA-Z]+)-id(\d+)\.html$ news.php?type=$1&id=$2

#RewriteRule aaa.html news.php


伪静态的实际运用

1. 在一个项目中有两个文件夹,public 和 private ,public文件夹的图片可以被所有人访问.

private只能自己访问.请问如何实现.

第一个方法是. 在 public 和 private 下创建 .htaccess 文件,对于private 只让127.0.0.1访问 public 文件都可以访问

private 文件夹下的配置 .htaccess


Order deny, allow

deny from all

allow from 127.0.0.1

这个的缺点是,没有办法去控制,本apahce的另外一个虚拟主机请求., 另外不能精细化控制,于是我们就换了一个思路使用 http的 referer头信息搞定这个防盗链需求.

第二方法.在private 文件夹下 .htaccess

RewriteEngine On

#你怎么知道,这个请求就是www.hsp.com发来的. referer

#如果你请求的是一个jpg图片, 就禁止

RewriteCond %{HTTP_REFERER} !www.hsp.com

RewriteRule .*\.jpg -[F]

? 说一下如果你的RewriteCond有多个条件

RewriteEngine On

#你怎么知道,这个请求就是www.hsp.com发来的. referer

#如果你请求的是一个jpg图片, 就禁止

RewriteCond %{HTTP_REFERER} !www.hsp.com

#RewriteCond %{ REQUEST_FILENAME} !-f

RewriteRule .*\.jpg -[F]

1. 关于404的说明 就是对于ie浏览器而言,404页面的内容大小不能低于512b字节

2. 如果你在 节点配置了 Options Indexes , 同时你有启用了 rewriteEngine On你会看到403 的禁用提示., 原因是因为 我们的父级目录的Options 本身就配好 ,

Options Indexes FollowSymLinks ,所以,我们要么就不配,要么就一样.

伪静态实际运用案例2

在www.hsp.com 的主目录下,我们编写了 .htaccess文件,并增加规则


#增加规则

[plain] view plaincopy

[img=http://img.bbs.csdn.net/upload/201403/07/1394181458_228087.png][/img] [img=http://img.bbs.csdn.net/upload/201403/07/1394181464_304731.png][/img]


伪静态的实际运用3->引出rewriteCond的使用

思考: 可能有条件指令.

网上找到方案:

最后的配置在 .htaccess

#如果请求的不是一个文件

RewriteCond %{REQUEST_FILENAME} !-f

#并且不是一个目录

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ccc.html index.php

伪静态的实际运用案例4:

在TP框架中使用rewrite简化url地址,目的是SEO, 步骤

1. 在httpd.conf 文件中启用rewrite模块

2. 在虚拟主机中配置 allowoverride all

3. 在tp的配置文件中 conf/config 文件把 URL_MODEL 配置2

4. 在tp框架的入口目录增加 .htaccess文件 写入规则



u 伪静态的特点


u 如何选用伪静态还是真静态,还是不静态?


查看更多关于高性能Web站点技巧原理的详细内容...

  阅读:40次