中小型网站实施指南

这是一往篇针对行业的中小型网站实施指南

Mr. netkiller 陈景峰(Neo Chan)


    中国广东深圳保安区龙华镇苹果园518049
    +86 755 29812080
    +86 755 29812080

Mr. 李振韬 freebird


    中国广东深圳深圳市福田区赛格科技园518000

文档尚未完成,请勿转载!

摘要

文档更新时间:Thu Jun 12 02:55:53 UTC 2008

获得该文档:wget -m http://netkiller.mefound.com/book/website/index.html

欢迎提出保贵的建议和意见,点击进入


特别感谢

Jam zheng

目录

前言
1. 案例分析
网站组成
大型网站架构分析
集群负载均衡
缓存技术
静态化
图片服务器分离
压缩数据传输
时间同步
数据存储
网络拓扑
大型社交类网站
新闻出版类网站
电子商务类网站
网站运维
日常管理
预警机制
网站安全
2. 设计篇 Design
XHTML+DIV+CSS
页面结构设计
导航烂
Left Bar
区块设计 Block
表格
图片使用技巧
onMouseOver/onMouseOut
html,css 有效性检查 Validation
3. 数据库篇 Database
数据库设计
用户帐号
分类
文章
评论
数据库性能优化
4. 开发篇
开发环境及工具
开发语言及平台
开发框架 Framework
URL设计
Javascript Framework
模板(template)
Session/Cookie
多语言国际化 Locale database。
Unicode
数据库访问
SEO
网站测试
部署 deploy
项目管理 project manager
A. 附录
基于LVS的集群邮件系统
术语表

范例清单

2.1. 表格排版范例
2.2. XHTML+DIV+CSS排版范例
2.3. 例子
2.4. 例子
4.1. php language package
4.2. sql table language package

前言

第 1 章 案例分析

门户网站的需求

  1. 海量用户访问

  2. 海量用户存储

  3. 国内外互通及南北互通

  4. 快速响应

  5. 7×24不间断运行

  6. 易于维护

门户网站的几个技术要点

  1. 智能域名服务器 Smart DNS

  2. 集群负载均衡 Cluster

  3. 缓存技术 Cache

  4. 静态化

  5. 图片服务器分离

  6. 压缩数据传输

  7. 时间同步

  8. 数据存储

网站组成

一个网站由下面几部分组成:

网站组成

  1. 硬件 hardware

  2. 操作系统 operation system

  3. 应用软件 application software

  4. 网站程序以及开发语言 web program and script

硬件包括

  1. 网络硬件(路由器 route, 交换机 switch)

  2. 服务器 server

  3. KVM over IP

  4. 其他包括,机柜等

操作系统包括

  1. Windows Server

  2. Linux

  3. FreeBSD

  4. Other(Sun,Novell,Sco...)

其中应用软件按平台分类

Windows 应用软件包括

  1. dns (dns)

  2. web (IIS)

  3. ftp (IIS)

  4. mail (Exchange)

  5. database (SQL Server)

  6. ldap (Active Directory)

Unix like 应用软件包括

  1. dns (bind)

  2. web (apache, lighttpd, tomcat)

  3. ftp (proftpd, pureftpd, wu-ftp, vsftpd)

  4. mail (sendmail,postfix, qmail)

  5. database (PostgreSQL, MySQL)

  6. ldap (OpenLDAP)

其他应用软件包括

  1. cache (squid, nginx, memcached...)

  2. web (jboss, weblogic...)

  3. database (Oracle, DB2...)

其他应用软件包括

  1. cache (squid, nginx...)

  2. web (jboss, weblogic...)

  3. database (Oracle, DB2...)

网站程序以及开发语言

  1. php

  2. java (jsp)

  3. .net (aspx)

  4. fastcgi (python,perl,rubby,c/c++ ...)

大型网站架构分析

集群负载均衡

集群有很多实现方法,分为硬件和软件,集群可以在不同网络层面上实现

  1. 实现IP轮循(Bind DNS)

  2. 硬件四层交换(硬件负载均衡设备 F5 BIG IP)

  3. 软件四层交换(linux virtual server)

  4. 应用层上实现(tomcat)

越是低层性能越好,越是上层功能更强

集群的分类

  1. 高可用性集群

  2. 负载均衡集群

  3. 超级计算集群

网站一般用到两种集群分别是高可用性集群和负载均衡集群

DNS负载均衡

这是早期出现的负载均衡技术,直到现在,很多网站仍然使用DNS负载均衡。

你可通过ping命令观看它是如何工作的,例如你可反复ping个网域名。

			
C:\>ping www.163.com

Pinging www.cache.split.netease.com [220.181.28.52] with 32 bytes of data:

Reply from 220.181.28.52: bytes=32 time=226ms TTL=53
Reply from 220.181.28.52: bytes=32 time=225ms TTL=53
Reply from 220.181.28.52: bytes=32 time=226ms TTL=53
Reply from 220.181.28.52: bytes=32 time=226ms TTL=53

Ping statistics for 220.181.28.52:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 225ms, Maximum = 226ms, Average = 225ms

C:\>ping www.163.com

Pinging www.cache.split.netease.com [220.181.28.53] with 32 bytes of data:

Reply from 220.181.28.53: bytes=32 time=52ms TTL=52
Reply from 220.181.28.53: bytes=32 time=53ms TTL=52
Reply from 220.181.28.53: bytes=32 time=52ms TTL=52
Reply from 220.181.28.53: bytes=32 time=52ms TTL=52

Ping statistics for 220.181.28.53:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 52ms, Maximum = 53ms, Average = 52ms

C:\>ping www.163.com

Pinging www.cache.split.netease.com [220.181.28.50] with 32 bytes of data:

Reply from 220.181.28.50: bytes=32 time=51ms TTL=53
Reply from 220.181.28.50: bytes=32 time=52ms TTL=53
Reply from 220.181.28.50: bytes=32 time=52ms TTL=53
Reply from 220.181.28.50: bytes=32 time=51ms TTL=53

Ping statistics for 220.181.28.50:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 51ms, Maximum = 52ms, Average = 51ms

C:\>
			
			

DNS负载均衡主要优点

  1. 技术简单,容易实现,灵活,方便,成本低

  2. Web服务器可以位于互联网的任意位置上,无地理限制。

  3. DNS的主从结构非常稳定

  4. 可以有效的分散DDOS攻击。

  5. 你甚至可以在DNS服务商那里实现,自己不需要添加设备。而且没有带宽开销。

DNS负载均衡主要缺点

  1. DNS负载均衡采用的是简单的轮循负载算法,不能够按照服务器节点的处理能力分配负载。

  2. 不支持故障转移(failover)和自动恢复failback ,如果某台服务器拓机,DNS仍会将用户解析到这台故障服务器上,导致不能响应客户端。

  3. 如果添加节点或撤出节点,不能即时更新到省市级DNS,可导致部分地区不能访问。

  4. 占用大量静态IP。

软件四层交换负载均衡

软件四层交换负载均衡为我们解决了几个问题

  1. 能够按照服务器节点的处理能力分配负载。

  2. 支持故障转移(failover)和自动恢复failback ,如果某节点拓机,调度器自动将它剔除,不响应客户端访问,当节点故障排除调度器立即恢复节点。

  3. 可以随时添加节点或撤出节点,即时生效,方便网站扩容。

软件四层交换负载均衡优点

  1. 仅仅需要一个静态IP。

  2. 节点位于私有网络上与WAN隔离,用户面对的只是调度器。

  3. 可以随时添加节点或撤出节点。

  4. 通过端口可以组建多个集群。

下面是基于LVS的负载均衡的例子

			
                                       .---> media [mp3, wma, wmv, rmvb, asf, divx]-\
                                      /                                       +------------+
                                     .-----> photo [gif, jpg, png, swf] ----> | Raid Array | <--.
    /------------------- <---------\/                                         +------------+     \
user -> dns -> load balancing -> squid -> [cache] <----[html]----\                  /            |
                 \ \ \______<______/\                      +-------------+         /             |
                  \ \                \-----> www web ----> | html        |--------^              |
                   \ \____________________________/\       | php,jsp,cgi |                       |
                    \                               \      +-------------+                       |
                     \                               `-----> memcached [node1, node2, node(n)]   |
                      \__________________________________________/\                              |
                                                                   `------> Database cluster     |
    +-------------------------------------+                                      \               |
    | Author: neo chen <openunix#163.com> |                                       `--------------+
    | Nickname: netkiller                 |
    | Homepage: http://netkiller.8800.org |
    +-------------------------------------+
			
			

应用层负载均衡

mod_proxy_balancer.so

tomcat mod_jk.so

缓存技术

首先要说明,很多缓存技术依赖静态化。下面展示了缓存可能出现的位置。

用户user -> 浏览器缓存 IE/Firefox Cache -> 逆向代理缓存 Reverse proxy Cache -> WEB服务器缓存 Apache cache -> 应用程序缓存 php cache -> 数据库缓存 database cache

当然交换机,网络适配器,硬盘上也有Cache 但这不是我们要讨论的范围。

缓存存储方式主要是内存和文件两种,后者是存于硬盘中。

网站上使用的缓存主要包括五种:

  1. 浏览器 Cache

  2. 逆向代理

  3. WEB服务器缓存

  4. 应用程序

  5. 数据库缓存

将上面的缓存合理地,有选择性的使用可大大提高网站的访问能力。

总之,想让你的网站更快,更多并发,答案是cache,cache 再 cache

浏览器缓存

只要向浏览器输出过期时间HTTP协议头,不论是html还是动态脚本,都能被缓存。

提示

有些浏览器可能不支持。

逆向代理缓存

具有代表性的逆向代理服务器:

  1. Squid

  2. Nginx

其它逆向代理服务器

  1. Apache cache module

  2. 一些提供cache的硬件设备

  3. 最近几年出现了的 China Cache 服务商

WEB服务器缓存

例如,通过配置apache实现自身 cache

应用程序缓存

在这个领域百花齐放,相信你一定能找到适合你的。这些cache会为你提供一些api,来访问它。

代表性的 memcached 据我所是sina广泛使用,腾讯也曾经使用过后来开发了TC(Tencent Cache),台湾雅虎则使用APC Cache。

数据库缓存

数据库本身就有这个配置选项,如果需要你仍然可以在数据库前面加一道Cache。

例如PostgreSQL, MySQL 都提供参数可以将memcached编译到它内部

静态化

静态化方法包括:

  1. 生成方式

  2. 抓取方式

  3. 伪静态化

  4. 混合方式

生成方式

主要由程序实现

例如

			
content = "<html><title>my static</title><body>hello world</body></html>"
file = open( your static file)
file.write(content)
file.close()
			
			

抓取方式

主要由程序实现

程序中抓取

			
content = get_url('http://netkiller.8800.org/index.php')
file = open( index.html)
file.write(content)
file.close()
			
			

使用软件抓取,不仅限于wget。

			
wget http://netkiller.8800.org/index.php -O index.html
			
			

这时只给出简单例子,使用复杂参数实现更复杂的拾取,然后将脚本加入crontab中可。

伪静态化

伪静态化是主要是通过在URL上做一些手脚,使你看去是静态的,实质上它是动态脚本。

伪静态化实现主要包括两种方法:

  1. Rewrite rule

  2. path_info

混合方式

其实目前网站使用的基本上都是上面几种方法混合方式。

例如首先将动态url(example.org/news.php?cid=1&id=1) 通过rewrite转换为 (example.org/new_1_1.html)

接下来就比较容易解决了,一种方法是使用wget example.org/new_1_1.html,另一种方法你无需静态化,直接使用squid规则配置让他永不过期

图片服务器分离

为什么要将图片服务器分离出来?

  1. 图片通常比较大,下载需要更长的时间,而web容器并发数也是相当宝贵的仅次于数据库。

  2. 传统浏览器一个窗口只占用一个链接数,目前主流浏览器都支持多线程下载,下载HTML页面同时,采用多线程下载其它多媒体数据。

提示

图片服务器建议使用lighttpd与squid缓存配合使用效果更好。

压缩数据传输

服务器将html或脚本输出压缩,用户从服务器取得数据后由浏览器解压

压缩数据传输实现方法:

  1. apache mod_deflate

  2. lighttpd compress module

时间同步

将通信网上各种通信设备或计算机设备的时间信息(年月日时分秒)基于UTC(协调世界时)时间偏差限定在足够小的范围内(如100ms),这种同步过程叫做时间同步。

关于时间同步我个人的解决方法:

  1. 使用UTC时间,用户加时区来解决。

  2. 保证所有服务器的时间是同步的

数据存储

网络拓扑

这里包括服务器部署与网络拓扑设计

大型社交类网站

新闻出版类网站

电子商务类网站

网站运维

日常管理

日常管理的几个要点

  1. 服务器负载 load average

  2. 网络负载

  3. 磁盘容量

  4. 登录用户

  5. 日志分析

预警机制

网站安全

第 2 章 设计篇 Design

最近几年,随着业界越来越关注XHTML+CSS的标准化设计,一个新兴职业已经诞生,这就是“网站重构师”,这个新兴职业人才紧缺,他们主要的职责是将HTML+Table+Javascript的架构向XHTML+CSS+Ajax迁移。

XHTML+DIV+CSS

为何使用表格排版是不明智的选择?为什么要选择DIV+CSS?

首选我来说说表格排版,表格排版也是有好处的,一是排版速度快,二是兼容性比CSS好。做为一般的小网站还是比较适合的,如果在大型网站使用表格就不太合适。 表格必须定义很多属性如width="100%" border="0" cellpadding="0" cellspacing="0",并且有时候tr标签显得多余。

例 2.1. 表格排版范例

			
<!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" />


<title>Table Example</title>
</head>

<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td>Logo</td>
    <td>Banner</td>
  </tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td>Home</td>
    <td>News</td>
    <td>Contact</td>
    <td>About</td>
  </tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td><table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td>Top 10 </td>
      </tr>
      <tr>
        <td>xxxxxxxx</td>
      </tr>
      <tr>
        <td>xxxxxxxx</td>
      </tr>
      <tr>
        <td>xxxxxxxx</td>
      </tr>
      <tr>
        <td>xxxxxxxx</td>
      </tr>
    </table>
      <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td>Link </td>
        </tr>
        <tr>
          <td>xxxxxxxx</td>
        </tr>
        <tr>
          <td>xxxxxxxx</td>
        </tr>
        <tr>
          <td>xxxxxxxx</td>
        </tr>
        <tr>
          <td>xxxxxxxx</td>
        </tr>
      </table></td>
    <td><table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td align="center">Article Title </td>
      </tr>
      <tr>
        <td><p>Contect</p>
          <p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
          <p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
          <p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
          <p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p></td>
      </tr>
      <tr>
        <td>Feedback</td>
      </tr>
    </table></td>
  </tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td align="center">Copyright XXXX </td>
  </tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>

			
			

你可以对比上面看看div+css是如何规划版面,并且css很多定义是可以重用的。

例 2.2. XHTML+DIV+CSS排版范例

			
<!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" />
<title>hello world</title>
<style type="text/css">
<!--
body{
	width: 795px;
}
div1{
	border-color: #119EBA;
	border-width: 1px;
	border-style: solid;
	margin: 5px;
}
#header{
}
#logo, #banner{
	float:left;
	height: 75px;
}
#nav{
	clear:both;
}
#nav ul {
	list-style-type:none;
	margin: 0px;
	padding:0px;
}
#nav ul li{
	float:left;
	width: 100px;
}
#main{ clear:both;}
#main #left {
	float:left;
	width: 30%;
}
#main #right {
	float:right;
	width: 70%;
}
.box{}
.box h2 {
	margin: 0;
	padding: 0px;
}
.box a { display:block;}
#footer{ clear:both}
#footer #copyright {
	text-align:center;
}

.article {
	border-color: black;
	border-width: 1px;
	border-style: solid;
	margin: 5px;
	padding: 10px;
}
.article .article_title{
	font-size: 24px;
	font-weight:bold;
	text-align:center;
}
.article .article_content{ font-size:10px;}
-->
</style>
</head>

<body>

<div id="header">
	<div id="logo"> Logo </div>
	<div id="banner"> Banner </div>
</div>

<div id="nav">
	<ul>
		<li><a href="#"> Home </a></li>
		<li><a href="#"> News </a></li>
		<li><a href="#"> Person </a></li>
		<li><a href="#"> Group </a></li>
		<li><a href="#"> Network </a></li>
	</ul>
</div>

<div id="main">
	<div id="left">
		<div class="box">
			<h2>title</h2>
			<a href="#"> link </a>
			<a href="#"> link </a>
			<a href="#"> link </a>
		</div>

		<div class="box">
			<h2>title</h2>
			<a href="#"> link </a>
			<a href="#"> link </a>
			<a href="#"> link </a>
		</div>
	</div>
	<div id="right">
		<div class="article">
			<div class="article_title">
				Article Title
			</div>
			<div class="article_content">
				<p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
				<p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
				<p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
				<p>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</p>
			</div>
		</div>
	</div>
</div>

<div id="footer">
	<div id="copyright"> Copyright Neo Chan</div>
</div>

</body>
</html>
			
			

上面例子我们可以看到div与table相比所使用的标签更少,无形中给网站减了肥。

CSS 的class,id 名称定义规范:

  1. 一定要简单,可读例如header,footer

  2. 对于在页面中不重复,自始至终只出现一次可定义为id,例如id="header",id="footer"

  3. 对于在页面中经常重复出现的,可定义为class,例如id="article_block",id="news_block"

注意

不要使用HTML属性,尽量使用css。 herf,src,class,id等属性除外。

下面是一个例子

			
<font color="red" size="12" face="Arial, Helvetica, sans-serif" >Hello workd</font>
			
			

你应该使用CSS实现,如果能使用CSS实现尽量不要多用一条HTML和属性。

			
<style type="text/css">
.hello{
	color:red;
	font-size:12px;
	font-family:Arial, Helvetica, sans-serif;
}
</style>
<div id="hello">Hello workd</font>
			
			

页面结构设计

页面结构从上到下依次是

  • header 主要包括导航,登录,Logo, Banner

  • body 网站主要内容,并且还可以分为左右两栏,左中右三栏。

  • footer 导航,版权

header,footer将显示在所有页面,一般很少改动。

导航烂

				
<table>
	<tr>
		<td>Home</td>
		<td>News</td>
		<td>About</td>
		<td>Contact</td>
	</tr>
</table>
				
				
				
<div id="nav">
	<ul>
		<li><a href="#"> Home </a></li>
		<li><a href="#"> News </a></li>
		<li><a href="#"> Person </a></li>
		<li><a href="#"> Group </a></li>
		<li><a href="#"> Network </a></li>
	</ul>
</div>
				
				

Left Bar

				
	<div id="left">
		<div class="box">
			<h2>title</h2>
			<a href="#"> link </a>
			<a href="#"> link </a>
			<a href="#"> link </a>
		</div>

		<div class="box">
			<h2>title</h2>
			<a href="#"> link </a>
			<a href="#"> link </a>
			<a href="#"> link </a>
		</div>
	</div>
				
				

区块设计 Block

网站经常用一些方块规划版面。

  • 一种是矩形方框

  • 另一种是有标题,标题下方是矩形方框

  • 现在流行的是标题栏有多个选项卡,标题下方是矩形方框,当选择不同标题时,矩形方框中的内容随之改变。

传统方法如下:

例 2.3.  例子

table block example

				
<table>
	<tr>
		<td>
			内容
		</td>
	</tr>
</table>
				
				

div+css block example

				
<div class="simple_box">
			内容
</table>
				
				

例 2.4.  例子

table title block example

				
<table>
	<tr>
		<td>Top 10</td>
	</tr>
	<tr>
		<td>
			<table>
				<tr>
					<td>No.1</td>
				</tr>
				<tr>
					<td>No.2</td>
				</tr>
				<tr>
					<td>No.3</td>
				</tr>
				<tr>
					<td>No.n</td>
				</tr>
			</table>
		</td>
	</tr>
</table>
				
				

div+css title block example

				
<div class="title_block">
	<h2>
		Title
	<h2>
	<div>
		Content
	</div>
</div>
				
				

使用dl标记实现

				
<dl class="title_block">
	<dt>Title<dt>
	<dd>
		Content
	</dd>
</dl>
				
				

表格

这里的表格不是指用于排版,而是表格数据。

				
<style type="text/css">
.hello{
	width: 100%;
}
.hello tr{

}
.hello td{

}
</style>
<table class="mytable">
	<tr>
		<td></td>
	</tr>
</table>
				
				

图片使用技巧

onMouseOver/onMouseOut

我们在网站冲浪常常看会看到很多图片按钮,当鼠标入上去或鼠标移开图片会随之改变,这个的按钮至少需要三张小图片才能实现这样的功能。

我先说说这样做的缺点

  • 三张图片,你的浏览器会启动三个线程链接你的图片服务器,不划算。

  • 一旦其中一幅图片下载过程中中断,用户当把鼠标放到按钮上时,可能会出现一个红叉叉。

  • 图片太多不好维护,易产生垃圾,占用磁盘空间,linux ext2 一个空文件占用1024K

最优方法是使用一张图片,将三幅图片平行或垂直排开,放到一幅图片中,然后使用CSS控制显示你需要的部分。

html,css 有效性检查 Validation

有效性检查包括

  1. Markup Validation

  2. CSS Validation.

  3. URL Validation.

第 3 章 数据库篇 Database

数据库设计

用户帐号

用户帐号或通行证系统设计,下面以我的数库为例讲解。

我一般使用两个表 passport,profile 完成网站会员系统。

首先说说passport表,你也要以使用user或member等等命名,这个表设计尽可能地简单,不要使用过多字段。仅保存登录所必须用到的字段,如user,password,nickname,email... 登录帐号和密码做复合索引。

然后是profile表,这个表与passport是1:1关系,保存用户详细信息

这样设计可以保证海量用户登录时的速度。

			
+----------+
| user     |
|----------|
|id        | <---+
|user      |     |
|passwd    |     |
|nickname  |     |
|status    |     |
+----------+     |
                1:1
+----------+     |
| profile  |     |
|----------|     |
|user_id   | o---+
|name      |
|sex       |
|passwd    |
|nickname  |
|status    |
+----------+
			
			

分类

			
+-----------+
| category  |
|-----------|
|id         | <---+
|title      |     |
|description|    1:n
|status     |     |
|parent_id  | o---+
+-----------+
			
			

文章

看具体情况,拆分表,可按“日”,“月”,“年”等等

			

      +-----------+
      | category  |
      |-----------|
  +-->|id         | <---+
  |   |title      |     |
  |   |description|    1:n
  |   |status     |     |
  |   |parent_id  | o---+
  |   +-----------+
  |
 1:n
  |
  |   +-----------------+            +------------------+
  |   | article_2008_01 |            | feedback_2008_01 |
  |   |-----------------|            |------------------|
  |   |id               |<--1:n--+   |id                |
  |   |title            |        |   |title             |
  |   |content          |        |   |content           |
  |   |datetime         |        |   |datetime          |
  |   |status           |        |   |status            |
  +--o|category_id      |        +--o|news_id           |
  +--o|user_id          |        +-->|user_id           |
  |   +-----------------+        |   +------------------+
  |                              |
 1:n  +----------+     +---1:n---+
  |   | user     |     |
  |   |----------|     |
  +-->|id        | <---+
      |user      |
      |passwd    |
      |nickname  |
      |status    |
      +----------+


			
			

评论

			
+----------+
| user     |
|----------|
|id        | <---+
|user      |     |
|passwd    |     |
|nickname  |     |
|status    |     |
+----------+     |
                1:n
+-----------+    |      +-----------+
| feedback  |    |      | news      |
|-----------|    |      |-----------|
|id         |    |  +-->|id         |
|title      |    |  |   |title      |
|content    |    |  |   |content    |
|datetime   |    | 1:n  |datetime   |
|status     |    |  |   |status     |
|user_id    |o---+  |   |user_id    |
|news_id    |o------+   +-----------+
+-----------+
			
			

数据库性能优化

第 4 章 开发篇

开发环境及工具

Mozilla Firefox 及扩展

  • Web Developer

  • Firebug 调试Ajax必备工具

  • Live HTTP Headers

  • IE Tab 用于IE/Firefox之间切换

  • FoxClocks 如果开发工作跨时区,这个很有用

  • Foxmarks Bookmark Synchronizer 将开发资源放入书签,同时在开发团队中保持同步

  • Fasterfox 可以一显示页面载入时间,方便页面优化

  • FireFTP

  • Adblock Plus

  • Chat Zilla

  • Super DragAndGo

Beyond Compare 文件差异比较与合并

TortoiseSVN 版本控制工具

开发语言及平台

语言只是一个工具,一种实现我们需要的工具,每种每言都有它的优点和缺点和,在不同领域发挥各自的长处,并且都有它存在的意义。

语言不段地发展,市场决定它们是生存还是没落走向死亡。只有最活越,生命力强的语言才能生存下来。.net与java后面是强大的财团做后盾,大量被捆绑的客户支持他,并有完备的客服,从商业角度选择它是没有错误的。

使用你最熟悉的语言,使用你最擅长的数据库和操作系统。

  • visual studio

  • eclipse

开发框架 Framework

选择一个好的开发框架,很重要。不过大部分框架都针对于软件开发,而我们要的是轻量级,适合高负载,灵活的框架。

  • Python Django

  • php CodeIgniter

  • Java Struts,Spring MVC

  • .Net Framework

上面框架可以满足我们绝大多数需求,如URL定义,Session/Cookie管理,多语言国际化,数据库访问等等。

Java和.Net我没有太多的经验,php我有6+年经验,我在各种框架之间做比较发现CodeIgniter框架比较适合我们的需求。

框架是没有100%完美的,你仍需要对它进行二次开发。如果你有充足的时间,针对自身系统系统的特点设计一个更适合您网站的框架,这是最好的选择。

设计一个框架需要用到很多知识,需要有丰富的经验。目前主流框架都是基于MVC设计思想,要设计一个框架你必须了解MVC (Model-View-Controller) 参考:http://www.itisedu.com/phrase/200604231324325.html

开发一个框架包括那些重点呢,下面我把一些要点一一列出,然后一个个地突破,我这里使用php为例子,上面我已经说过语言只是工具,所以学习是设计思想,不要拘泥于语言:

  • JS封装(javascript)

  • 模板(template)

  • url

  • session/cookie

  • 语言包(language package)

  • 编码(unicode)

  • 数据库访问(database OR Mapping)

  • 权限(Permission)

如果重新开发一个框架,我认为太现实,我的建议使用现有pear库,搭建一个MVC框架。例如:

  • Model(pear db)

  • View(smarty template)

  • Controller (pathinfo)

URL设计

一个大型网站,对于URL规划我认为非常重要,这也是为什么我把它单列出来的原因。

当前网站上使用的URL虚虚实实已经不单单是划分目录空间功能,它与程序配合使用,实现复杂的逻辑功能。在应用程序开发框架组成中占有重要的地位。

注意

无论什么文件系统,每个目录下容纳的子目录和文件是有限制的,并且内容过多会影响文件索引速度,所以合理地划分目录空间很重要

下面是URL实例仅供参考,稍后我会详细解释他们这样设计的目的是什么和实现方法。

  • http://sina.allyes.com/main/adfclick?db=sina&bid=120294,154641,159584&cid=0,0,0&sid=146767&advid=2618&camid=19961&show=ignore&url=http://web.topxue.com/gj/bdxm/

  • http://news.sina.com.cn/c/2008-05-22/172315597145.shtml

  • http://linux.chinaunix.net/bbs/thread-1003872-1-1.html

  • http://linux.chinaunix.net/news/2008/05/22/1004862.shtml

  • http://example.org/uk/en/action,ProductDetailShow_productId,51

  • http://example.com/forums/viewforum/59/

  • http://example.com/forums/viewthread/80165/

  • http://trac.example.com/cgi-bin/trac.cgi/ticket/1286

目录设计,以下为真实目录,你在URL看到其它路径都是不存在的。它们是用于rewrite或pathinfo的。

  • images

  • framework

  • model

  • view

  • controller

  • language

  • config

  • logs

常用的URL表现方式

Javascript Framework

javascript是面向过程的,只要请引用.js文件即可访问他的方法(function),并且传统方式会定义很多全局变量。如果大量使用javascript难免会出现变量覆盖,或function同名。

所以我们要将javascript封装成class,另一点我们也需要面向对象支持。下面是几个常用的JS开发框架(javascript framework)。

  • mootools

  • prototype

  • jQuery

  • Dojo

  • rico

模板(template)

模板最早是在cgi程序中广泛应用,cgi是动态页面的第一代,同期还有NSAPI,ISAPI,第二代是fastcgi,asp,php,ColdFusion...第三代是.net与java。

模板的特点:

  • 模板可以分离代码和页面

  • 模板能够改善页面结构

  • 模板可实现页面重用

  • 模板可以区块化,如同搭积木

  • 设计人员不需要关心代码

  • 实现主题

模板有很多优点,但它也会增加系统开销,不过我们可以通过cache来解决这个问题。

Session/Cookie

为什么我要在这里提Session和Cookie,这也大型站点必须要处理问题。

Session

在集群环境中与单服务器是不一样的,集群组成可分为调度服务器和节点,节点数量不定,单个节点安装有web服务器,用户每次访问网站调度服务器随机分配一个节点给该用户, 举一个例子:用户在网站上看新闻,点击第一个连接被分配到node 1上去,当他看完这条新闻并单击下一条时,可能被分配到其它节点上,这里刚才建立的session在node 1上, 它就会因失去session而必须重新登录。

所以我们要同步所有节点上的Session, 另外如果能用Cookie代替Session的地方尽量使用Cookie。

Cookie

Cookie 我这里提到cookie是可以实现“单点登录”功能。

一个网站可能不指一组集群系统,如news.example.org, bbs.example.org, blog.example.org 要实现在一处登录即可在其它站点上同时也处于登录状态,就要用到Cookie来实现。

多语言国际化 Locale database。

在开始具体介绍之前,需要先介绍几个术语:

  • i18n: 就是internationalization, 国际化,由于首字母"i"和末尾字母"n"间有18个字符,所以简称i18n. internationalization指为了使应用程序能适应不同的语言和地区间的变化而不作系统性的变化所采取的设计措施。

  • l10n: 就是localization, 本地化,由于首字母"l"和末尾字母"n"间有10个字母,所以简称l10n. localization指为了使应用软件能够在某一特定语言环境或地区使用而加入本地特殊化部件和翻译后文本的过程。

  • locale: 简单来说是指语言和区域进行特殊组合的一个标志,如:en-us, zh-cn, zh-tw

l10n有很多历史遗留问题,l10n目前已经被i18n取代。

我自己曾经使用过下面四种方式实现语言包

  1. 定义一个数组

  2. 使用数据库

  3. 使用文件

  4. 使用数据结构

数组方式

这种方式流行于PHP语言,下面是一个例子

例 4.1. php language package

					
<?php
	$language['hello_world'] = 'hello world !!!'
?>
					
					

数据库方式

数据库方式包括

  1. 其他非关系型收据库 (Berkeley DB)

  2. 对象/关系型收据库 ORDBMS (mysql)

Berkeley DB 是一个不错的选择,而且相对关系型数据库比较有优势。因为关系型数据库子并发数有限,连接资源很宝贵。

例 4.2. sql table language package

					
select id,key,value from language where country = 'zh-cn' and key = 'hello_world';
					
					

文件文件

例如.ini文件

				
news=新闻
top10=前十位
				
				

数据结构

数据结构方式主要包括

  1. 哈希表 hash table

  2. 类 class

  3. 字典 dict

  4. 图 map

提示

可能会用到序列化

Unicode

相比几年前,目前各种语言对UTF-8支持都比较好。

在BBS上常常看到一些网友抱怨UTF-8出现“乱码”问题,让我们看看都有哪些地方涉及编码问题。

用户输入法->IDE开发环境,浏览器->web容器->数据库

任何一个环节出现问题有可能出现问题

  • 首先是输入法,早期输入法可能是GB2312或GBK。

  • 其次是IDE开发环境,当你创建一个空文件时,它的已经具备某种编码,一般外国开发工具默认是acsii,这一点我认为Dreamware做的最好,可以随时切换编码。

  • 浏览器现在基本不用担心

  • web容器apache 2.x对unicode支持很好,tomcat本身机器码就是unicode。

  • 数据库问题也不大,PostgreSQL相比MySQL对Unicode支持也早,也比较好。MySQL这方面有点复杂。

提示

如果你不考虑使用Unicode并且想支持繁体和简体中文,你可以使用GBK,但我建议你使用GB18030。

数据库访问

早期php访问数据库的做法是写一个连接文件,include包含进来,然后在页面使用sql操作函数,返回结果。

  • CRUD

  • Active Record

  • OR Mapping

SEO

显示title前20个汉字并在后尾添加省略号。


	    

网站测试

This is the first chapter in my book.

部署 deploy

项目管理 project manager

我在IT行业干了8年,做过大大小小的公司不少,项目管理上有乱来的,有ISO国际化的,先进的CMM过程的,还有开源方式的。

最近几年一直在外企背景的本地公司,开发模式接近开源软件开发方式。

常用的项目管理工具

  • TRAC

  • Subversion

  • Bugzilla

		
TRAC:
1.Roadmap->Milestone->Add new milestone
2.New Ticket

Subversion:

		
		

附录 A. 附录

基于LVS的集群邮件系统

基于开源Postfix的邮件集群系统解决方案:

目的:

1. 可伸缩,动态增加,减少节点.方便扩容.

2. 可维护,当节点出现故障时,立即撤出故障节点并更换新节点只需要1分钟完成.

3. 先写到这,有时间再说...886...

术语表

SNMP

ANSI

(American National Standards Institute) This group is the U.S. member organization that belongs to the ISO, the International Organization for Standardization.

CSS

CSS是Cascading style Sheets的简称,中文译作“层叠样式表单”,在主页制作时采用CSS技术,可以有效地对页面的布局、字体、颜色、背景和其它效果实现更加精确的控制。

集群(Cluster)

所谓集群是指一组独立的计算机系统构成的一个松耦合的多处理器系统,它们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。

负载均衡(Load Balancing)

网络的负载均衡是一种动态均衡技术,通过一些工具实时地分析数据包,掌握网络中的数据流量状况,把任务合理均衡地分配出去。这种技术基于现有网络结构,提供了一种扩展服务器带宽和增加服务器吞吐量的廉价有效的方法,加强了网络数据处理能力,提高了网络的灵活性和可用性。

修订历史
修订 0.0.0May 22, 2008Neo
这是一个值得纪念的日子
修订 0.0.1May 24, 2008Neo
李振韬加入编译团队