分类目录归档:Web设计

快速安装最新 CentOS + Nginx + PHP-FPM + MySQL[转]

PHP 5.3.1
MySQL 5.0.89
Nginx 0.8.33 或 0.7.65 (可选)

现在,我们可以快速全自动搞定 CentOS + Nginx + PHP-FPM + MySQL 的安装了

这个可比网上流传的什么一键安装包要好得多,强烈推荐此法安装,适合所有菜鸟和高手
我服务器上全用的源代码编译安装,也好不到哪去,还很费劲

我这个装完已经包含 php 的一些常用扩展, PDO,eaccelerator,memcache,tidy等等

本文为 21andy.com 原创,转载请以超级链接方式注明出处 http://www.21andy.com

先新建一个 repo

# vi /etc/yum.repos.d/centos.21andy.com.repo

放入如下内容

[21Andy.com]
name=21Andy.com Packages for Enterprise Linux 5 – $basearch
baseurl=http://www.21andy.com/centos/5/$basearch/
enabled=1
gpgcheck=0
protect=1

启用 EPEL repo
i386

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm

x86_64

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

接着导入key

rpm –import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL

好了,一键安装

# yum install nginx php-fpm mysql-server

爽吧!

如果 nginx 你要用 0.7.65 最新稳定版,把
yum -y install nginx
换成
yum -y install nginx-stable
就可以了

本文为 21andy.com 原创,转载请以超级链接方式注明出处 http://www.21andy.com

更完整的安装

yum -y update
yum -y install mysql-server
service mysqld start
mysqladmin -u root password root
service mysqld stop
yum -y install nginx php-fpm php-cli php-pdo php-mysql php-mcrypt php-mbstring php-gd php-tidy php-xml php-xmlrpc php-pear php-pecl-memcache php-eaccelerator
# APC 和 eAccelerator 有冲突,2选1
yum -y install php-pecl-apc

看下我的完整安装,只要一句

yum -y install nginx mysql-server php-fpm php-cli php-pdo php-mysql php-mcrypt php-mbstring php-gd php-tidy php-xml php-xmlrpc php-pear php-pecl-memcache php-eaccelerator

安装结果,全自动

Dependencies Resolved

==========================================================
Package Arch Version Repository Size
==========================================================
Installing:
mysql x86_64 5.0.89-1.el5 21Andy.com 3.5 M
mysql-server x86_64 5.0.89-1.el5 21Andy.com 10 M
nginx x86_64 0.8.33-3.el5 21Andy.com 422 k
php-cli x86_64 5.3.1-2.el5 21Andy.com 2.4 M
php-eaccelerator x86_64 2:0.9.6-1.el5 21Andy.com 118 k
php-fpm x86_64 5.3.1-2.el5 21Andy.com 1.2 M
php-gd x86_64 5.3.1-2.el5 21Andy.com 110 k
php-mbstring x86_64 5.3.1-2.el5 21Andy.com 1.1 M
php-mcrypt x86_64 5.3.1-2.el5 21Andy.com 27 k
php-mysql x86_64 5.3.1-2.el5 21Andy.com 84 k
php-pdo x86_64 5.3.1-2.el5 21Andy.com 91 k
php-pear noarch 1:1.9.0-1.el5 21Andy.com 420 k
php-pecl-memcache x86_64 2.2.5-3.el5 21Andy.com 44 k
php-tidy x86_64 5.3.1-2.el5 21Andy.com 31 k
php-xml x86_64 5.3.1-2.el5 21Andy.com 115 k
php-xmlrpc x86_64 5.3.1-2.el5 21Andy.com 48 k
Installing for dependencies:
gmp x86_64 4.1.4-10.el5 base 201 k
libXaw x86_64 1.0.2-8.1 base 329 k
libXmu x86_64 1.0.2-5 base 63 k
libXpm x86_64 3.5.5-3 base 44 k
libedit x86_64 2.11-2.20080712cvs.el5 epel 80 k
libmcrypt x86_64 2.5.8-4.el5.centos extras 105 k
libtidy x86_64 0.99.0-14.20070615.el5 epel 140 k
php-common x86_64 5.3.1-2.el5 21Andy.com 554 k
sqlite2 x86_64 2.8.17-5.el5 21Andy.com 165 k
t1lib x86_64 5.1.1-7.el5 epel 208 k
Updating for dependencies:
libevent x86_64 1.4.12-1.el5 21Andy.com 129 k

Transaction Summary
==========================================================
Install 26 Package(s)
Update 1 Package(s)
Remove 0 Package(s)

最后只要 yum -y update 一下,全是最新的
别忘了开机启动

chkconfig –level 345 mysqld on
chkconfig –level 345 php-fpm on
chkconfig –level 345 nginx on

来看看我用虚拟机测试的强大结果
http://www.21andy.com/blog/20100219/1703.html

补充:所有的配置文件都在 /etc 目录下,包括 nginx, php-fpm, mysql 的配置文件,请自行查找设置,以下为我的 nginx 的配置范例

先新建一个 /www 目录,网站和日志也全放在这里
别忘了建日志存放目录,你在配置文件中 access_log 用到的 /www/logs

注意:fastcgi_params 要加入这一行
# vim /etc/nginx/fastcgi_params

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

# vi /etc/nginx/nginx.conf

user nobody nobody;

worker_processes 8; #这里根据你的CPU和内存配置, 设置2到10都OK

error_log  /www/logs/nginx_error.log  crit;

pid        /usr/local/nginx/logs/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;

events {
use epoll;
worker_connections 51200;
}

http {
include       mime.types;
default_type  application/octet-stream;

#charset  gb2312; # 默认编码,可以不设置

server_names_hash_bucket_size 128;
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
client_max_body_size 8m;

sendfile on;
tcp_nopush     on;

keepalive_timeout 60;

tcp_nodelay on;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

gzip on;
gzip_min_length  1k;
gzip_buffers     4 16k;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_types       text/plain text/javascript application/x-javascript text/css application/xml;
gzip_vary on;

#limit_zone  crawler  $binary_remote_addr  10m;
server {
listen 80;
server_name localhost;
root  /www;
location /status {
stub_status on;
access_log  off;
}
location / {
# 这里是把所有不存在的文件和目录,全都转到 index.php 处理
try_files $uri $uri/ /index.php?q=$uri&$args;
}

# 这里分开放到 server.conf 是为了再开 server 的时候方便,统一调用,放到/etc/nginx/ 目录下
include server.conf;

log_format  access  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log  /www/logs/access.log  access;
}

server {
listen 80;
server_name www.21andy.com 21andy.com *.21andy.com;
root  /www/21andy.com;
if ($host !~* 21andy\.com$) {
return 444;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
include server.conf; # 这里复用了,这段就省了
access_log  /www/logs/21andy.com_access.log  access;
}
}

# vi /etc/nginx/server.conf

index index.html index.htm index.php;

#limit_conn   crawler  20;

location ~ /\.ht {
deny all;
}

location ~ .*\.(sqlite|sq3)$ {
deny all;
}

location ~ .*\.php$ {
fastcgi_pass  unix:/tmp/php-cgi.sock;
#fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
expires      30d;
access_log   off;
}

location ~ .*\.(js|css)?$ {
expires      30d;
access_log   off;
}

本行以下内容可以略过
php-fpm 也可以用以下设置,但建议用上面的,比较稳定

location ~ \.php$ {
root           /www;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
#下面这一行要加在 /etc/nginx/fastcgi_params 里
#fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
include        fastcgi_params;
}

不管是使用 php-cgi.sock 或 9000 端口方法,nginx 和 php-fpm 都要同时设置成一样的
nginx 的设置上面已经提过,记得同时修改 php-fpm.conf 相应的地方
# vi /etc/php-fpm.conf

<value name=”listen_address”>127.0.0.1:9000</value>

<value name=”listen_address”>unix:/tmp/php-cgi.sock</value>

优化网站性能 提高网站速度访问速度的14条实践

相信互联网已经越来越成为人们生活中不可或缺的一部分。ajax,flex等等富客户端的应用使得人们越加“幸福”地体验着许多原先只能在C/S实 现的功 能。比如Google机会已经把最基本的office应用都搬到了互联网上。当然便利的同时毫无疑问的也使页面的速度越来越慢。自己是做前端开发的,在性 能方面,根据yahoo的调查,后台只占5%,而前端高达95%之多,其中有88%的东西是可以优化的。

以上是一张web2.0页面的生命周期图。工程师很形象地讲它分成了“怀孕,出生,毕业,结婚”四个阶段。如果在我们点击网页链接的时候能够意识到 这个过程而不是简单的请求-响应的话,我们便可以挖掘出很多细节上可以提升性能的东西。今天听了淘宝小马哥的一个对yahoo开发团队对web性能研究的 一个讲座,感觉收获很大,想在blog上做个分享。

相信很多人都听过优化网站性能的14条规则。更多的信息可见developer.yahoo.com

1. 尽可能的减少 HTTP 的请求数 [content]
2. 使用 CDN(Content Delivery Network) [server]
3. 添加 Expires 头(或者 Cache-control ) [server]
4. Gzip 组件 [server]
5. 将 CSS 样式放在页面的上方 [css]
6. 将脚本移动到底部(包括内联的) [javascript]
7. 避免使用 CSS 中的 Expressions [css]
8. 将 JavaScript 和 CSS 独立成外部文件 [javascript] [css]
9. 减少 DNS 查询 [content]
10. 压缩 JavaScript 和 CSS (包括内联的) [javascript] [css]
11. 避免重定向 [server]
12. 移除重复的脚本 [javascript]
13. 配置实体标签(ETags) [css]
14. 使 AJAX 缓存

在firefox下有一个插件yslow,集成在firebug中,你可以用它很方便地来看看自己的网站在这几个方面的表现。

这是对用yslow对我的网站西风坊测评的结果,很遗憾,只有51分。呵呵。中国各大网站的分值都不高,刚测了一下,新浪和网易都是31分。然后yahoo(美国)的分值确实97分!可见yahoo在这方面作出的努力。从他们总结的这14条规则,已经现在又新增加的20个点来看,有很多细节我们真得是怎么都不会去想,有些做法甚至是有些“变态”了。

第一条、尽可能的减少 HTTP 的请求数Make Fewer HTTP Requests

http请求是要开销的,想办法减少请求数自然可以提高网页速度。常用的方法,合并css,js(将一个页面中的css和js文件分别合并)以及 Image maps和css sprites等。当然或许将css,js文件拆分多个是因为css结构,共用等方面的考虑。阿里巴巴中文站当时的做法是开发时依然分开开发,然后在后台 对js,css进行合并,这样对于浏览器来说依然是一个请求,但是开发时仍然能还原成多个,方便管理和重复引用。yahoo甚至建议将首页的css和js 直接写在页面文件里面,而不是外部引用。因为首页的访问量太大了,这么做也可以减少两个请求数。而事实上国内的很多门户都是这么做的。

而css sprites是指只用将页面上的背景图合并成一张,然后通过css的background-position属性定义不过的值来取他的背景。淘宝和阿里巴巴中文站目前都是这样做的。有兴趣的可以看下淘宝和阿里巴巴的背景图

http://www.csssprites.com/ 这是个工具网站,它可以自动将你上传的图片合并并给出对应的background-position坐标。并将结果以png和gif的格式输出。

第二条、使用CDN(内容分发网络): Use a Content Delivery Network

简单地讲,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的 cache服务器内,通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问近杭州服务器上的内容,北京的访问 近北京服务器上的内容。这样可以有效减少数据在网络上传输的时间,提高速度。更详细地内容大家可以参考百度百科上对于CDN的解释。Yahoo!把静态内容分布到CDN减少了用户影响时间20%或更多。

CDN技术示意图:

CDN组网示意图:

第三条、 添加Expire/Cache-Control 头:Add an Expires Header

现在越来越多的图片,脚本,css,flash被嵌入到页面中,当我们访问他们的时候势必会做许多次的http请求。其实我们可以通过设置Expires header 来缓存这些文件。Expire其实就是通过header报文来指定特定类型的文件在览器中的缓存时间。大多数的图片,flash在发布后都是不需要经常修 改的,做了缓存以后这样浏览器以后就不需要再从服务器下载这些文件而是而直接从缓存中读取,这样再次访问页面的速度会大大加快。一个典型的HTTP 1.1协议返回的头信息:
HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
Content-Length: 1040
Content-Type: text/html

其中通过服务器端脚本设置Cache-Control和Expires可以完成。

如,在php中设置30天后过期:

<!--pHeader("Cache-Control: must-revalidate");
$offset = 60 * 60 * 24 * 30;
$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s"time() + $offset) . " GMT";
Header($ExpStr);-->

也可以通过配置服务器本身完成,这些偶就不是很清楚了,呵呵。想了解跟多的朋友可以参考http://www.web-caching.com/

据我了解,目前阿里巴巴中文站的Expires过期时间是30天。不过期间也有过问题,特别是对于脚本过期时间的设置还是应该仔细考虑下,不然相应的脚本功能更新后客户端可能要过很长一段时间才能“感知”到这样的变化。以前做[suggest项目] 的时候就遇到过这个问题。所以,哪些应该缓存,哪些不该缓存还是应该仔细斟酌一番。

第四条、启用Gzip压缩:Gzip Components

Gzip的思想就是把文件先在服务器端进行压缩,然后再传输。这样可以显著减少文件传输的大小。传输完毕后浏览器会 重新对压缩过的内容进行解压缩,并执行。目前的浏览器都能“良好”地支持 gzip。不仅浏览器可以识别,而且各大“爬虫”也同样可以识别,各位seoer可以放下心了。而且gzip的压缩比例非常大,一般压缩率为85%,就是 说服务器端100K的页面可以压缩到25K左右再发送到客户端。具体的Gzip压缩原理大家可以参考csdn上的《gzip压缩算法 这篇文章。雅虎特别强调, 所有的文本内容都应该被gzip压缩: html (php), js, css, xml, txt… 这一点我们网站做得不错,是一个A。以前我们的首页也并不是A,因为首页上还有很多广告代码投放的js,这些广告代码拥有者的网站的js没有经过gzip压缩,也会拖累我们网站。

以上三点大多属于服务器端的内容,本人也是粗浅地了解而已。说得不对的地方有待各位指正。

第五条、将css放在页面最上面 ( Put Stylesheets at the Top)

将css放在页面最上面,这是为什么?因为 ie,firefox等浏览器在css全部传输完全之前不会去渲染任何的东西。理由诚如小马哥说得那样很简单。css,全称Cascading Style Sheets (层叠样式表单)。层叠即意味这后面的css可以覆盖前面的css,级别高的css可以覆盖级别低的css。在[css之!important] 这篇文章的最下面曾简单地提到过这层级关系,这里我们只需要知道css可以被覆盖的。既然前面的可以被覆盖,浏览器在他完全加载完毕之后再去渲染无疑也是合情合理的很多浏览器下,如IE,把样式表放在页面的底部的问题在于它禁止了网页内容的顺序显示。浏览器阻止显示以免重画页面元素,那用户只能看到空白页了。Firefox不会阻止显示,但这意味着当样式表下载后,有些页面元素可能需要重画,这导致闪烁问题。所以我们应该尽快让css加载完毕

顺着这层意思,如果我们再细究的话,其实还有可以优化的地方。比如本站上面包含的两个css文件,<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/themes/google/style/google.css” type=“text/css” media=“screen” /> 和<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/css/print.css” type=“text/css” media=“print” />。 从media就可以看出第一个css是针对浏览器的,第二个css文件是针对打印样式的。从用户的行为习惯上来将,要打印页面的动作一定是发生在页面页面 显示出来之后的。所以比较好的方法应该是在页面加载完毕之后再动态地为这张页面加上针对打印设备的css,这样又可以提高一点速度。(哈哈)

第六条、将script放在页面最下面 (Put Scripts at the Bottom )

将脚本放在页面最下面的目的有那么两点: 1、 因为防止script脚本的执行阻塞页面的下载。在页面loading的过程中,当浏览器读到js执行语句的时候一定会把它全部解释完毕后在会接下来读下 面的内容。不信你可以写一个js死循环看看页面下面的东西还会不会出来。(setTimeout 和 setInterval的执行有点类似于多线程,在相应的响应时间之前也会继续下面的内容渲染。)浏览器这么做的逻辑是因为js随时可能执 行 location.href或是其他可能完全中断此页面过程的函数,即如此,当然得等他执行完毕之后再加载咯。所以放在页面最后,可以有效减少页面可 视元素的加载时间。        2、脚本引起的第二个问题是它阻塞并行下载数量。HTTP/1.1规范建议浏览器每个主机的并行下载数不超过2个(IE只能为2个,其他浏览器如ff等都是默认设置为2个,不过新出的ie8可以达6个)。因此如果您把图像文件分布到多台机器的话,您可以达到超过2个的并行下载。但是当脚本文件下载时,浏览器不会启动其他的并行下载。

当然对各个网站来说,把脚本都放到页面底部加载的可行性还是值得商榷的。就比如阿里巴巴中文站的页面。很多地方有内联的js,页面的显示严重依赖于此,我承认这和无侵入脚本的理念相差甚远,但是很多“历史遗留问题”却不是那么容易解决的。

第七条、避免在CSS中使用Expressions (Avoid CSS Expressions )

不过这样就多了两层无意义的嵌套,肯定不好。还需要一个更好的办法。

第八条、把javascript和css都放到外部文件中 (Make JavaScript and CSS External )

这点我想还是很容易理解的。不仅从性能优化上会这么做,用代码易于维护的角度看也应该这么做。把css和js写在页面内容可以减少2次请求,但也增 大了页面的大小。如果已经对css和js做了缓存,那也就没有2次多余的http请求了。当然,我在前面中也说过,有些特殊的页面开发人员还是会选择内联 的css和js文件。

第九条、减少DNS查询 (Reduce DNS Lookups)

在 Internet上域名与IP地址之间是一一对应的,域名(kuqin.com)很好记,但计算机不认识,计算机之间的“相认”还要转成ip地址。在网络 上每台计算机都对应有一个独立的ip地址。在域名和ip地址之间的转换工作称为域名解析,也称DNS查询。一次DNS的解析过程会消耗20-120毫秒的 时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页面的加载速度。yahoo的建议一个页面所包含的域 名数尽量控制在2-4个。这就需要对页面整体有一个很好的规划。目前我们这点做的不好,很多打点的广告投放系统拖累了我们。

第十条、压缩 JavaScript 和 CSS (Minify JavaScript )

压缩js和css的左右很显然,减少页面字节数。容量小页面加载速度自然也就快。而且压缩除了减少体积以外还可以起到一定的保护左右。这点我们做得不错。常用的压缩工具有JsMin、YUI compressor等。另外像http://dean.edwards.name/packer/还给我们提供了一个非常方便的在线压缩工具。你可以在jQuery的网页看到压缩过的js文件和没有压缩过的js文件的容量差别:

当然,压缩带来的一个弊端就是代码的可读性没了。相信很多做前端的朋友都遇到过这个问题:看Google的效果很酷,可是去看他的源代码却是一大堆 挤在一起的字符,连函数名都是替换过的,汗死!自己的代码也这样岂不是对维护非常不方便。所有阿里巴巴中文站目前采用的做法是在js和css发布的时候在 服务器端进行压缩。这样在我们很方便地维护自己的代码。

第十一条、避免重定向 (Avoid Redirects )

不久前在ieblog上看到过《Internet Explorer and Connection Limits》这篇文章,比如 当你输入http://www.kuqin.com/ 的时候服务器会自动产生一个301服务器转向 http://www.kuqin.com/ ,你看浏览器的地址栏就能看出来。这种重定向自然也是需要消耗时间的。当然这只是一个例子,发生重定向的原因还有很多,但是不变的是每增加一次重定向就会增加一次web请求,所以因该尽量减少。

第十二条、移除重复的脚本 (Remove Duplicate Scripts )

这点我想不说也知道,不仅是从性能上考虑,代码规范上看也是这样。但是不得不承认,很多时候我们会因为图一时之快而加上一些或许是重复的代码。或许一个统一的css框架和js框架可以比较好的解决我们的问题。小猪的观点很对,不仅是要做到不重复,更是要做到可重用。

第十三条、配置实体标签(ETags) (Configure ETags )

这点我也不懂,呵呵。在inforQ上找到一篇解释得比较详细的说明《使用ETags减少Web应用带宽和负载》,有兴趣的同学可以去看看。

第十四条、使 AJAX 缓存 (Make Ajax Cacheable )

ajax还要去缓存?做ajax请求的时候往往还要增加一个时间戳去避免他缓存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(记住“异步”不是“瞬间”这一点很重要)。记住,即使AJAX是动态产生的而且只对一个用户起作用,他们依然可以被缓 存。

优化结果页数展示的四种方法

优化结果页数展示的四种方法

1、    对于第一个查询,读取并缓存所有结果。这样可以很容易知道一共有多少结果,数据库不必再额外读取后来的页。这种模型下,展示大多数人期望的那样“共找到X个结果,显示共N/M页”。

2、    不显示所有结果。即使是Google也不会让你看到百万多个结果。你只是查看了N个结果,然后就找到了你所需要的。限制结果数到100、500或其它数量。对于结果列表查看的越远,就说明在这个限制下,扫描并丢弃了更多的数据行。如果你想显示500个结果,你可以读取501个,只要第501存在,展示“找到多于500个结果”。
梁婷 说:

3、   
不显示结果总数或是到其他页的直接链接。只显示“下一个”链接。(如果用户想查看“前一个”结果,他们可以使用浏览器的回退按钮。)实现方法就是读取数量
比想要展示的结果数多一个——例如,读取21个结果,只显示20个。如果存在第21个结果,给出“下一个”链接;如果不存在,显示“这是最后一个结果”。
这种方法不需计算到底一共有多少结果,如果缓存困难的话,还有其它可以减小代价的方法。

4、    预测一共会有多少结果。Google是这么做的,而且得到了大家的认可。使用EXPLAIN查看“rows”列——在某些假设下,这是个很好的预测方法。

十个增强读者体验的方法

  1. 让读者更容易联系你,并建议一个 about 页面
  2. 确保访问你 blog 的速度不错
  3. 用 Category(分类) 来组织你的文章,而不是用日期
  4. 在文章中加入图片
  5. 组织好你的文章内容,让读者一目了然
  6. 不要放广告
  7. 及时回复评论,回访发表评论者
  8. 在博客上显示 Top Posts(最受欢迎文章) 和 Related Posts(相关文章)
  9. 使用一个比较独特,个性化的 theme(主题)
  10. 验证你的 blog ,如 XHTML, CSS