2014年1月31日星期五

Architect_004:反向代理服务器的工作原理(摘录+整理)

上文谈到Nginx还可以为反向代理服务器,那么什么是反向代理服务器?它有什么作用呢?

注:本文摘自参考文献1,写的非常清楚,非常好。整理如下:

1. 反向代理(Reverse Proxy)概念
反向代理方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。


2. 工作原理
反向代理服务器通常有两种模型:(1)作为内容服务器的替身;(2)作为内容服务器集群的负载均衡器。

(1)作内容服务器的替身                     
如果您的内容服务器具有必须保持安全的敏感信息,如信用卡号数据库,可在防火墙外部设置一个代理服务器作为内容服务器的替身。当外部客户机尝试访问内容服务器时,会将其送到代理服务器。实际内容位于内容服务器上,在防火墙内部受到安全保护。代理服务器位于防火墙外部,在客户机看来就像是内容服务器。
当客户机向站点提出请求时,请求将转到代理服务器。然后,代理服务器通过防火墙中的特定通路,将客户机的请求发送到内容服务器。内容服务器再通过该通道将结果回传给代理服务器。代理服务器将检索到的信息发送给客户机,好像代理服务器就是实际的内容服务器。如果内容服务器返回错误消息,代理服务器会先行截取该消息并更改标头中列出的任何URL,然后再将消息发送给客户机。如此可防止外部客户机获取内部内容服务器的重定向URL。
这样,代理服务器就在安全数据库和可能的恶意攻击之间提供了又一道屏障。与有权访问整个数据库的情况相对比,就算是侥幸攻击成功,作恶者充其量也仅限于访问单个事务中所涉及的信息。未经授权的用户无法访问到真正的内容服务器,因为防火墙通路只允许代理服务器有权进行访问。
可以配置防火墙路由器,使其只允许特定端口上的特定服务器(在本例中为其所分配端口上的代理服务器)有权通过防火墙进行访问,而不允许其他任何机器进出。


(2)作为内容服务器的负载均衡器
可以在一个组织内使用多个代理服务器来平衡各Web服务器间的网络负载。
在此模型中,可以利用代理服务器的高速缓存特性,创建一个用于负载平衡的服务器池。
此时,代理服务器可以位于防火墙的任意一侧。
如果Web服务器每天都会接收大量的请求,则可以使用代理服务器分担Web服务器的负载并提高网络访问效率。
对于客户机发往真正服务器的请求,代理服务器起着中间调停者的作用。代理服务器会将所请求的文档存入高速缓存。如果有不止一个代理服务器,DNS可以采用“循环复用法”选择其 IP 地址,随机地为请求选择路由。客户机每次都使用同一个 URL,但请求所采取的路由每次都可能经过不同的代理服务器。
可以使用多个代理服务器来处理对一个高用量内容服务器的请求,这样做的好处是内容服务器可以处理更高的负载,并且比其独自工作时更有效率。在初始启动期间,代理服务器首次从内容服务器检索文档,此后,对内容服务器的请求数会大大下降。



参考文献:
1. http://blog.csdn.net/keyeagle/article/details/6723408

Architect_003:LAMP网站软件架构方案(摘录+整理)

LAMP(Linux-Apache-MySQL-PHP)网站软件架构是国际上成熟的Web架构,该架构包括:
(1)Linux 操作系统
(2)Apache 动态网页服务器
(3)Nginx 静态网页服务器
(4)Squid Web缓存服务器
(5)Perl、PHP、Python 编程语言以及PHP加速器:eAccelerator
(6)MySQL 数据库
所有组成产品均是开源软件,很多流行的商业应用都是采取这个架构。



1. 高性能的操作系统:CentOS
基于稳定性和性能的考虑,操作系统选择CentOS(Community ENTerprise Operating System)。
CentOS 是Linux发行版之一,是Red Hat Enterprise Linux的精简免费版。

2. 高性能的动态网页服务器:Apache
Apache是世界排名第一的web服务器。
优点:开源、稳定、模块丰富。
缺点:内存和CPU开销大,当进程数超过200个后,web响应速度明显缓慢,说明性能有损耗。
因此Apache不适合负载静态页面,只适合负载动态页面,比如PHP。

3. 高性能的静态网页服务器:Nginx
Nginx以事件驱动的方式编写,所以有非常好的性能和稳定性。
尤其对于静态文件的响应能力远高于Apache,因此Nginx适合负载静态页面。
Nginx同时也可以作为一个反向代理服务器完成负载均衡。

4. 高性能的Web缓存服务器:Squid
Web服务器的缓存也有多种方案,Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。
Squid Cache是一个Web缓存服务器,支持高效的缓存,可以作为网页服务器的前置cache服务器缓存相关请求来提高Web服务器的速度,把Squid放在Apache的前端来缓存Web服务器生成的动态内容,而Web应用程序只需要适当地设置页面实效时间即可。
如果访问量巨大则可考虑使用memcached作为分布式缓存。

5. PHP加速器:eAccelerator
eAccelerator是一个自由开放源码PHP加速器,优化和动态内容缓存,提高了性能PHP脚本的缓存性能,使得PHP脚本在编译的状态下,对服务器的开销几乎完全消除。
它还有对脚本起优化作用,以加快其执行效率。使PHP程序代码执效率能提高1-10倍。

6. 高性能的数据库:MySQL
开源的数据库中,MySQL在性能、稳定性和功能上是首选,可以达到百万级别的数据存储,网站初期可以将MySQL和Web服务器放在一起,但是当访问量达到一定规模后,应该将MySQL数据库从Web Server上独立出来,在单独的服务器上运行,同时保持Web Server和MySQL服务器的稳定连接。
当数据库访问量达到更大的级别,可以考虑使用MySQL Cluster等数据库集群或者库表散列等解决方案。

在今天,全球已有2000万个网站使用LAMP。
LAMP国外案例:
(1)汉莎航空电子订票系统
(2)德意志银行的网上银行
(3)华尔街在线的金融信息发布系统
LAMP国内案例:
(1)LAMP兄弟连:http://www.lampbrother.net/item/porfolio.php
(2)国内最大的教育社区:k12 教育网
(3)鲨威体坛:http://sports.tom.com/

总的来说,LAMP网站软件架构可以满足大量用户访问和高并发请求,同时具有成本低廉、部署灵活、快速开发、安全稳定等特点,是Web网络应用和环境的优秀组合。

参考文献:
1. http://www.williamlong.info/archives/1908.html
2. http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html
3. http://wenku.baidu.com/view/e222e7886529647d2728522e.html

2014年1月30日星期四

Linux_011:如何让普通用户有sudo的权限?

安装软件时有时需要root权限,把root密码告诉别人有很多隐患:
(1)不安全
(2)无法区分哪些操作是谁做的。
(3)密码分发问题。
总之,超级用户root密码应该只掌握在少数人手中。

这时,我们可以使用 sudo,把某些超级权限有针对性的下放,并且不需要普通用户知道root密码。
相对于权限无限制性的 su 来说,sudo 还是比较安全的,所以 sudo 也能被称为受限制的su。
另外 sudo 是需要授权许可的,所以也被称为授权许可的 su;
sudo执行命令的流程是当前用户切换到root(或其它指定切换到的用户),然后以 root(或其它指定的切换到的用户)身份执行命令,执行完成后,直接退回到当前用户;而这些的前提是要通过 sudo 的配置文件 /etc/sudoers 来进行授权。

查看/etc/sudoers

## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
##
## This file must be edited with the 'visudo' command.

## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem


## Command Aliases
## These are groups of related commands...

## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp

## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe

# Defaults specification

#
# Disable "ssh hostname sudo ", because it will show the password in clear. 
#         You have to run "ssh -t hostname sudo ".
#
Defaults    requiretty

#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
Defaults   !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults    always_set_home

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += "HOME"

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
## user MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
# %wheel ALL=(ALL) ALL

## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL

## Allows members of the users group to mount and unmount the
## cdrom as root
# %users  ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

## Allows members of the users group to shutdown this system
# %users  localhost=/sbin/shutdown -h now

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d
maping ALL=(root) NOPASSWD: ALL

在文件内容的最后一行,我给用户maping授予了sudo root用户的权限,密码永不过期。
你也可以给一个组授予sudo的权限,在组名前加“%”即可,比如:%wheel ALL=(ALL) NOPASSWD: ALL。

这样设置好了以后,以用户maping登录,就可以随时使用sudo命令执行root用户才能执行的命令。
比如:sudo vi /etc/profile,这时会提示输入口令(我这里设置成NOPASSWD,所以不需要输入),你只需要输入用户maping的口令就可以了,不需要输入root口令。
也就是说,你无须知道root口令就可以执行root用户才能执行的命令。
这就是使用sudo的好处。

另外,如果为了频繁的执行某些只有超级用户才能执行的权限,而不用每次输入密码,可以使用命令:sudo -i。提示输入密码时该密码为当前账户的密码。没有时间限制。
sudo -i 与 sudo 的区别是:sudo 是暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码。不过有时间限制,默认为一次时长 15 分钟。而 sudo -i 没有时间限制。

参考文献:
1. http://blog.csdn.net/trochiluses/article/details/8810010

Linux_010:CentOS6.5下开机自启动GlassFish4

首先要安装好GlassFish,请参考《在CentOS6.5上安装GlassFish4.0》。

以下操作均是在root用户下执行

1. 在/etc/init.d/目录下创建脚本:glassfish4

#! /bin/sh
# This shell script takes care of starting and stopping
# the glassfish DAS and glassfish instance.
#
# chkconfig: - 64 36
# description: glassfish management
# processname: glassfish

export AS_JAVA=/usr/java/jdk1.7.0_45
#export CLASSPATH=.;$AS_JAVA/lib/dt.jar;$AS_JAVA/lib/tools.jar

GLASSFISHPATH=/home/glassfish/glassfish4/bin/
export PASSWD=/home/glassfish/glassfish4/bin/.passwd

case "$1" in
start)
echo "starting glassfish from $GLASSFISHPATH"
su - root $GLASSFISHPATH/asadmin start-domain

#start your instance at start time, if you do not have instance, comment these two lines
echo "starting instance st_server"
$GLASSFISHPATH/asadmin --user admin --passwordfile $PASSWD start-instance st_server
#we need to use this later when we enable https
#sudo -u glassfish $GLASSFISHPATH/asadmin --secure start-domain domain1
;;
status)
$0 start
;;
restart)
$0 stop
$0 start
;;
stop)

echo "stopping instance st_server"
$GLASSFISHPATH/asadmin --user admin --passwordfile $PASSWD stop-instance st_server
echo "stopping glassfish from $GLASSFISHPATH"
su - root $GLASSFISHPATH/asadmin stop-domain

#we need to use this later when we enable https
#sudo -u root $GLASSFISHPATH/asadmin --secure stop-domain domain1
;;
*)
echo $"usage: $0 {start|stop|restart|status}"
exit 3
;;
esac

2. 设置成可执行文件:chmod +x /etc/init.d/glassfish4

3. 在/home/glassfish/glassfish4/bin/目录下创建.passwd文件
内容如下:
AS_ADMIN_PASSWORD=administration-password
把administration-password 替换成你的GlassFish的管理密码。

4. 检查GlassFish状态:chkconfig --list glassfish4
输出如下:
glassfish4 服务支持 chkconfig,但它在任何级别中都没有被引用(运行“chkconfig --add glassfish4”)

5. 开启GlassFish状态:chkconfig glassfish4 on

6. 再次检查GlassFish状态:chkconfig --list glassfish4
输出如下:
glassfish4     0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭

7. 重启

8. 登入后,直接访问:http://localhost:4848/common/index.jsf

参考文献:
1. http://yhjhoo.iteye.com/blog/1154010
2. http://os.51cto.com/art/201301/377515.htm

Linux_009:在Ubuntu13.10上安装JDK1.7

安装介质:jdk-7u51-linux-x64.tar.gz。
之所以选择.tar.gz格式而没有选择.rpm格式,是因为Ubuntu使用的是DEB格式的软件包,RPM包是RedHat开发的,只用于RedHat、CentOS等遵循RedHat规定的操作系统。

1.安装到某个用户主目录下,比如/home/maping
(1)在用户主目录下创建java目录:mkdir java
(2)复制jdk-7u51-linux-x64.tar.gz到java目录下:cp jdk-7u51-linux-x64.tar.gz /home/maping/java
(3)解压安装:tar -zxvf jdk-7u51-linux-x64.tar.gz。
完成后,会在java目录下生成jdk1.7.0_51目录,里面就是JDK的全部东东。
(4)修改用户主目录下的.bashrc文件,注意该文件是隐含文件。
在文件最后增加如下内容:
#Set Java Environment
export JAVA_HOME=/home/maping/jdk1.7.0_51
export CLASSPATH=.:$JAVA_HOME/lib.tools.jar
export PATH=$JAVA_HOME/bin:$PATH
(5)重启
(6)以该用户登录,运行java -version。

2.安装到/usr/java目录下,对所有用户起作用。
(1)切换到root用户:su root
注意,默认情况下,安装Ubuntu时并没有提示设置root密码,只有一个普通用户。
可以按如下方式设置root密码:
以普通用户登入,在终端输入sudo passwd,会提示你输入当前用户的密码。
输入完成后,终端会提示输入新的密码并确认,这个密码就是root密码。
(2)在/usr目录下创建java目录:mkdir java
(3)复制jdk-7u51-linux-x64.tar.gz到java目录下:cp jdk-7u51-linux-x64.tar.gz /usr/java
(4)解压安装:tar -zxvf jdk-7u51-linux-x64.tar.gz。
完成后,会在java目录下生成jdk1.7.0_51目录,里面就是JDK的全部东东。
(5)修改/etc/profile文件,注意该文件是隐含文件。
在文件最后增加如下内容:
#Set Java Environment
export JAVA_HOME=/user/java/jdk1.7.0_51
export CLASSPATH=.:$JAVA_HOME/lib.tools.jar
export PATH=$JAVA_HOME/bin:$PATH
(6)将系统默认的jdk修改过来
update-alternatives --install /usr/bin/java java /usr/java/jdk1.7.0_51/bin/java 300
update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.7.0_51/bin/javac 300
update-alternatives --config java
update-alternatives --config javac
(8)重启
(9)以用户maping登录,运行java -version。
(10)创建新用户再测试
由于已经对用户maping设置了环境,为了确认对所有用户都起作用,这里创建一个新用户:guolijie。
切换到root用户:su root
创建用户:useradd -d /home/guolijie -m -s /bin/bash guolijie
为用户guolijie设置密码:passwd guolijie
(11)以用户guolijie登入,运行java -version。
(12)测试完毕后可以删除用户guolijie
删除用户及相关账户信息:userdel -r guolijie

参考文献:
1. http://www.linuxidc.com/Linux/2012-12/76532.htm

2014年1月26日星期日

Tools_026:使用Yslow评估你的网站

Yslow是内嵌在FireBug中的一个子功能,它是根据雅虎14条法则来评估你的网站的。
关于雅虎14条法则,可以参考《提高网站速度的雅虎14条法则》。

下载地址:https://addons.mozilla.org/en-US/firefox/search?q=YSLOW&cat=all。

我们来看看www.sina.com的得分吧。

1. 总体得分:E (A最高,F最低)

每一项的得分参看左边的列表。
比如:Make fewer HTTP reqeust得分是F,点击后会告诉为什么是这个得分,并给你一些修改建议:
Grade F on Make fewer HTTP requests

This page has 54 external Javascript scripts. Try combining them into one.
This page has 32 external background images. Try combining them with CSS sprites.

Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Some ways to reduce the number of components include: combine files, combine multiple scripts into one script, combine multiple CSS files into one style sheet, and use CSS Sprites and image maps.

2. 统计项
会列出该页面有多少个HTTP Request(无缓存情况下,有缓存的情况下)
其中有多少个HTML、JS、CSS、Image等等。


怎么样?相当不错的软件吧,以后就用Yslow来评估你的网站吧。

Architect_002:提高网站速度的雅虎14条法则(翻译+整理)

笔者注:以下14条法则用于优化网站前端的性能,而不是后端的性能。
我个人认为最重要的法则是1、2、4、5、6、7、8。
另外,我还在最后补充了两个法则。

法则 1. 减少 HTTP 请求次数
80%的最终用户响应时间的花费在前端,而其中的大部分时间花在下载各种页面元素:如图像、样式表、 脚本和 Flash 等等。
减少页面元素将会减少 HTTP 请求次数,这是快速显示页面的关键所在,所以要尽量减少页面元素,简化页面设计。
但是否存在其他方式,能做到既有丰富内容,又能获得快速响应时间呢?
以下是可以考虑的一些技术:
(1)Combined files
整合多个脚本文件为一个文件,可以减少 HTTP 请求次数。
样式表也可采用类似方法处理。
当页面之间脚本和样式表变化很大时,该方式将遇到很大的挑战,但如果做到的话,将能加快响应时间。
(2)CSS Sprites
CSS Sprites 可以用来减少图片的 HTTP 请求次数。
使用单个图片作为页面的背景图片,并使用 CSS 的background-image 和 background-position 属性来现实所需的部分图片。 
(3)Image maps 
组合多个图片到一张图片中。总文件大小变化不大,但减少了 HTTP 请求次数。
该方式只适合图片连续的情况;同时图片坐标的定义是烦人又容易出错的工作。 
(4)Inline images
使用data: URL scheme可以在页面中内嵌图片,但这将增大 HTML 文件的大小。
组合 inline images 到(缓存)样式表是既能较少 HTTP 请求,又能避免加大 HTML 文件大小的方法。
但是主要的浏览器不支持Inline images。

小结:减少 HTTP 请求次数是性能优化的起点,这最提高首次访问的效率起到很重要的作用。
美国 10 大网站每页平均有 7 个脚本文件和 2 个样式表。
据Tenni Theurer 的文章 Browser Cache Usage – Exposed!所述,40-60% 的日常访问是首次访问,因此为首次访问者加快页面访问速度是用户体验的关键。

法则 2. 使用 CDN(Content Delivery Network, 内容分发网络)
用户离 web server 的远近对响应时间也有很大影响。
从用户角度看,把内容部署到多个地理位置分散的服务器上将有效提高页面装载速度。
但是该从哪里开始 呢?
作为实现内容地理分布的第一步,不要试图重构 web 应用以适应分布架构。
改变架构将导致多个周期性任务,如同步 session 状态,在多个 server 之间复制数据库交易。这样缩短用户与内容距离的尝试可能被应用架构改动所延迟,或阻止。
与其花在重构系统这个困难的任务上,还不如先分布静态内容。
这不仅能大大减少响应时间,而且由于 CDN 的存在,分布静态内 容非常容易实现。 
CDN 是地理上分布的 web server 的集合,用于更高效地发布内容。
通常基于网络 远近来选择给具体用户服务的 web server。
一些大型网站拥有自己的 CDN,但是使用如 Akamai Technologies, Mirror Image Internet, 或 Limelight Networks 等 CDN 服务提供商的服务将是划算的。
在 Yahoo!把静态内容分布到 CDN 减少了用户影响时间 20%或更多。

法则 3. 增加 Expires Header
网页内容正变得越来越丰富,这意味着更多的脚本文件、样式表、图像文件和 Flash。
首次访问者将不得不面临多次 HTTP 请求,但通过使用 Expires header, 您可以在客户端缓存这些元素。这在后续访问中避免了不必要的 HTTP 请求。
Expires header 最常用于图像文件,但是它也应该用于脚本文件、样式表和 Flash。
浏览器(和代理)使用缓存来减少 HTTP 请求的次数和大小,使得网页加速装载。
Web server 通过 Expires header 告诉客户端一个元素可以缓存的时间长度。
如果服务器是 Apache 的话,您可以使用 ExpiresDefault 基于当期日期来设置 过期日期,如:ExpiresDefault “access plus 10 years” 设置过期时间为从请求时间开始计算的 10 年。
请记住,如果使用超长的过期时间,则当内容改变时,您必须修改文件名称。
在 Yahoo!我们经常把改名作为 release 的一个步骤:版本号内嵌在文件名中,如yahoo_2.0.6.js。
除了Expires参数,还可以修改其它与缓存有关的Header参数:Cache-Control、Pragma、Last-Modified。总之,能够让浏览器缓存的数据一定要缓存。

法则 4. 压缩页面元素
通过压缩 HTTP 响应内容可减少页面响应时间。
从 HTTP/1.1 开始,web 客户端在 HTTP 请求中通过 Accept-Encoding 头来表明支持的压缩类型,如:Accept-Encoding: gzip, deflate.。
如果 Web server 检查到 Accept-Encoding 头,它会使用客户端支持的方法来压缩 HTTP 响应,会设置 Content-Encoding 头,如:Content-Encoding: gzip。
Gzip 是目前最流行及有效的压缩方法。 其他的方式如 deflate,但它效果较差,也不够流行。
通过 Gzip,内容一般可减少 70%。如果是 Apache,在 1.3 版本下需 使用 mod_gzip 模块,而在 2.x 版本下,则需使用 mod_deflate。
Web server 根据文件类型来决定是否压缩。大部分网站对 HTML 文件进行压缩。但对脚本文件和样式表进行压缩也是值得的。实际上,对包括 XML 和 JSON 在内的任务文本信息进行压缩都是值得的。
图像文件和 PDF 文件不应该被压缩,因为它们本来就是压缩格式保存的。对它们进行压缩,不但浪费 CPU,而且还可能增加文件的大小。
因此,对尽量多的文件类型进行压缩是一种减少页面大小和提高用户体验的简便方法。

法则 5. 把样式表放在头上
我们发现把样式表移到 HEAD 部分可以提高界面加载速度,因此这使得页面元素可以顺序显示。
在很多浏览器下,如 IE,把样式表放在 document 的底部的问题在于它禁止了网页内容的顺序显示。
浏览器阻止显示以免重画页面元素,那用户只能看到空白页 了。
Firefox 不会阻止显示,但这意味着当样式表下载后,有些页面元素可能需 要重画,这导致闪烁问题。
HTML 规范明确要求样式表被定义在 HEAD 中,因此为了避免空白屏幕或闪烁问题,最好的办法是遵循 HTML 规范,把样式表放在 HEAD 中。

法则 6. 把执行脚本文件放在底部
与样式文件一样,我们需要注意脚本文件的位置。
我们需尽量把它们放在页面的底部,这样一方面能顺序显示,另一方面可达到最大的并行下载。 浏览器会阻塞显示直到样式表下载完毕,因此我们需要把样式表放在 HEAD 部分。
而对于脚本来说,脚本后面内容的顺序显示将被阻塞,因此把脚本尽量放在底部意味着更多内容能被快速显示。
脚本引起的第二个问题是它阻塞并行下载数量。HTTP/1.1 规范建议浏览器每个主机的并行下载数不超过 2 个。
因此如果您把图像文件分布到多台机器的话,您可以达到超过2个的并行下载。
但是当脚本文件下载时,浏览器不会启动其他的并行下载,甚至其他主机的下载也不启动。
在某些情况下,不是很容易就能把脚本移到底部的,如脚本使用 document.write 方法来插入页面内容。 同时可能还存在域的问题。
不过在很多情 况下,还是有一些方法的。一个备选方法是使用延迟脚本(deferred script)。DEFER 属性表明脚本未包含 document.write,指示浏览器刻继续显示。
不幸的是,Firefox 不支持 DEFER 属性。IE 中,脚本可能被延迟执行,但不一定得到需要的长时间延迟。不过,从另外角度来说,如果脚本能被延迟执行,那它就可以被放在底部了。

笔者注: 这里所说的“把脚本放在底部”指的是执行脚本,一般的Javascript函数定义脚本还是要放在外部。
这样做的原因是为了实现最大的下载并行,页面加载初期做的事,最好只有下载,HTML的下载,CSS的下载,JS的下载,等下载完成后再去实现页面渲染,JS脚本运行。
如果你的页面在加载过程中需要运行了一部分脚本,那么就不能放在底部,这其实是一种不好的实现,最好不要在页面加载时执行脚本。

法则 7. 避免 CSS 表达式
CSS 表达式是功能强大的,但同时也是危险的,它可以用于动态设置 CSS 属性的方式。
IE 从版本 5 开始支持 CSS 表达式,如 backgourd-color: expression((new Date()).getHours()%2?”#B8D4FF”:”#F08A00”),即背景色每个小时切换一次。
CSS 表达式的问题是其执行次数超过大部分人的期望。不仅页面显示和 resize 时计算表达式,而且当页面滚屏,甚至当鼠标在页面上移动时都会重新计算表达式。
一种减少 CSS 表达式执行次数的方法是一次性表达式,即当第一次执行时就以明确的数值代替表达式。
如果必须动态设置的话,可使用事件处理函数代替。如果您必须使用 CSS 表达式的话,请记住它们可能被执行上千次,从而影响页面性能。

法则 8. 把 JavaScript 和 CSS 放到外部文件中
上述很多性能优化法则都基于外部文件进行优化。
现在,我们必须问一个问题: JavaScript 和 CSS 应该包括在外部文件,还是在页面文件中? 在现实世界中,使用外部文件会加快页面显示速度,因为外部文件会被浏览器缓存。
如果内置 JavaScript 和 CSS 在页面中虽然会减少 HTTP 请求次数,但增大了页面的大小。 另外一方面,使用外部文件,会被浏览器缓存,则页面大小会减小,同时又不增加 HTTP 请求次数。
因此,一般来说,外部文件是更可行的方式。
唯一的例外是内嵌方式对主页更有效,如 Yahoo!和 My Yahoo!都使用内嵌方式。
一般来说,在一个 session 中,主页访问此时较少,因此内嵌方式可以取得更快的用户响应时间。

法则 9. 减少 DNS 查询次数
DNS 用于映射主机名和 IP 地址,一般一次解析需要 20~120 毫秒。
为达到更高的 性能,DNS 解析通常被多级别地缓存,如由 ISP 或局域网维护的 caching server,本地机器操作系统的缓存(如 windows 上的 DNS Client Service),IE 浏览器的缺省 DNS 缓存时间为 30 分钟,Firefox 的缺省缓冲时间是 1 分钟。
IE 减少主机名可减少 DNS 查询的次数,但可能造成并行下载数的减少。
避免 DNS 查询可减少响应时间,而减少并行下载数可能增加响应时间。
一个可行的折中是把 内容分布到至少 2 个,最多 4 个不同的主机名上。

法则 10. 最小化 JavaScript 代码
最小化 JavaScript 代码指在 JS 代码中删除不必要的字符,从而降低下载时间。
两个流行的工具是 JSMin 和 YUI Compressor。 混淆是最小化于源码的备选方式。
像最小化一样,它通过删除注释和空格来减少源码大小,同时它还可以对代码进行混淆处理。 作为混淆的一部分,函数名和变 量名被替换成短的字符串,这使得代码更紧凑,同时也更难读,使得难于被反向工程。
Dojo Compressor (ShrinkSafe)是最常见的混淆工具。 最小化是安全的、直白的过程,而混淆则更复杂,而且容易产生问题。
从对美国 10 大网站的调查来看,通过最小化,文件可减少 21%,而混淆则可减少 25%。
除了最小化外部脚本文件外,内嵌的脚本代码也应该被最小化。
即使脚本根据法则 4 被压缩后传输,最小化脚本刻减少文件大小 5% 或更高。

法则 11. 避免重定向
重定向功能是通过 301 和 302 这两个 HTTP 状态码完成的,如: HTTP/1.1 301 Moved Permanently Location: http://example.com/newuri Content-Type: text/html 浏览器自动重定向请求到 Location 指定的 URL 上,重定向的主要问题是降低了用户体验。
一种最耗费资源、经常发生而很容易被忽视的重定向是 URL 的最后缺少/,如访问 http://astrology.yahoo.com/astrology 将被重定向到
http://astrology.yahoo.com/astrology/。
在 Apache 下,可以通过 Alias,mod_rewrite 或 DirectorySlash 等方式来解决该问题。

法则 12. 删除重复的脚本文件
在一个页面中包含重复的 JS 脚本文件会影响性能,即它会建立不必要的 HTTP 请求和额外的 JS 执行。 不必要的 HTTP 请求会发生在 IE 中,而 Firefox 不会产生多余的 HTTP 请求。 额外的 JS 执行,不管在 IE 下,还是在 Firefox 下,都会发生。
一个避免重复的脚本文件的方式是使用模板系统来建立脚本管理模块。
除了防止重复的脚本文件外,该模块还可以实现依赖性检查和增加版本号到脚本文件名中,从而实现超长的过期时间。

法则 13. 配置 ETags
ETags 是用于确定浏览器缓存中元素是否与 Web server 中的元素相匹配的机制,它是比 last-modified date 更灵活的元素验证机制。
ETag 是用于唯一表示元素 版本的字符串,它需被包括在引号中。
Web server 首先在 response 中指定 ETag: HTTP/1.1 200 OK < 03:03:59 2006 Dec 12> 10c24bc-4ab-457e1c1f” Content-Length: 12195 后来,如果浏览器需要验证某元素,它使用 If-None-Match 头回传 ETag 给 Web server,如果 ETag 匹配,则服务器返回 304 代码,从而节省了下载时间: GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com < 03:03:59 2006 Dec 12> 10c24bc-4ab-457e1c1f” HTTP/1.1 304 Not Modified ETags 的问题在于它们是基于服务器唯一性的某些属性构造的,如 Apache1.3 和 2.x,其格式是 inode-size-timestamp,而在 IIS5.0 和 6.0 下,其格式是 Filetimestamp:ChangeNumber。这样同一个元素在不同的 web server 上,其 ETag 是不一样的。
这样在多 Web server 的环境下,浏览器先从 server1 请求某元素,后来向 server2 验证该元素,由于 ETag 不同,所以缓存失效,必须重新下载。
因此,如果您未用到 ETags 系统提供的灵活的验证机制,最好删除 ETag。
删除 ETag 会减少 http response 及后续请求的 HTTP 头的大小。
微软支持文章描述了 如何删除 ETags,而在 Apache 下,只要在配置文件中设置 FileETag none 即可。

法则 14. 缓存 Ajax
性能优化法则同样适用于 web 2.0 应用。
提高 Ajax 的性能最重要的方式是使得其 response 可缓存,就象“法则 3 增加 Expires Header”讨论的那样。
以下其他法则同样适用于 Ajax,当然法则 3 是最有效的方式。

补充法则 1. 能用GET请求实现的,绝不用POST请求实现。
根据HTTP1.1协议,使用HTTP Pipelining技术特性,将多个HTTP请求整批提交的技术,而在传送过程中不需先等待服务端的回应。
管线化机制须通过永久连接(persistent connection)完成,仅HTTP/1.1支持此技术(HTTP/1.0不支持),并且只有GET和HEAD要求可以进行管线化,而POST则有所限制。
此外,初次创建连接时也不应启动管线机制,因为对方(服务器)不一定支持HTTP/1.1版本的协议。
浏览器将HTTP要求大批提交可大幅缩短页面的加载时间,特别是在传输延迟较高的情况下(如卫星连接)。此技术之关键在于多个HTTP的要求消息可以同时塞入一个TCP分组中,所以只提交一个分组即可同时发出多个要求,借此可减少网络上多余的分组并降低线路负载。

补充法则 2. 能在浏览器端的运算,决不放在服务器端来处理。
采取浏览器插件技术突破浏览器功能限制,将原本在服务器端运算的迁到浏览器端。
可以考虑的技术有:ActiveX、Applet、Flash。
当然还有最值得的推荐的下一代网页技术:HTML5。

参考文献:
1. http://developer.yahoo.com/performance/rules.html
2. http://blog.csdn.net/bobiy45785/article/details/7227728
3. http://blog.bingo929.com/css-sprites-css-techniques-tools-tutorials.html
4. http://ce.sysu.edu.cn/hope2008/beautydesign/ShowArticle.asp?ArticleID=11496
5. http://alistapart.com/article/sprites
6. http://www.infoq.com/cn/articles/etags

2014年1月19日星期日

Linux_008:Linux目录功能详解 (摘录+整理)

1. /
This is the root directory. The mothership. The home field. The one and only top directory for your whole computer. Everything, and I mean EVERYTHING starts here. When you type ‘/home’ what you’re really saying is “start at / and then go to the home directory.”
根目录。对你的电脑来说,有且只有一个根目录。所有的东西,我是说所有的东西都是从这里开始。
举个例子:当你在终端里输入“/home”,你其实是在告诉电脑,先从/(根目录)开始,再进入到home目录。
 
2. /root
This is where the root user lives. The root user is the god of your system. Root can do anything, up to and including removing your entire filesystem. So be careful using root.
系统管理员(root user)的目录。对于系统来说,系统管理员就好比是上帝,它能对系统做任何事情,甚至包括删除你的文件。因此,请小心使用root帐号。

3. /bin
Here’s where your standard linux utilities(read programs) live — things like “ls” and “vi” and “more”. Generally this directory is included in your path. What this means is that if you type ‘ls’, /bin is one of the places your shell will look to see if ‘ls’ means anything.
这里存放了标准的(或者说是缺省的)linux的工具,比如像“ls”、“vi”还有“more”等等。通常来说,这个目录已经包含在你的“path”系 统变量里面了。
什么意思呢?就是:当你在终端里输入ls,系统就会去/bin目录下面查找是不是有ls这个程序。

4. /etc
Here’s where the administrative and system configuration stuff lives. For instance, if you have samba installed, and you want to modify the samba configuration files, you’d find them in /etc/samba.
这里主要存放了系统配置方面的文件。举个例子:你安装了samba这个套件,当你想要修改samba配置文件的时候,你会发现它们(配置文件)就在/etc/samba目录下。

5./dev
Here’s where files that control peripherals live. Talking to a printer? Your computer is doing it from here. Same goes for disk drives, usb devices, and other such stuff.
这里主要存放与设备(包括外设)有关的文件(unix和linux系统均把设备当成文件)。
想连线打印机吗?系统就是从这个目录开始工作的。
另外还有一些包括磁盘驱动、USB驱动等都放在这个目录。
 
6. /home
Here’s where your data is stored. Config files specific to users, your Desktop folder(whick makes your desktop what it is), and any data related to your user. Each user will have their own /home/username folder, with the exception of the root user.
这里主要存放你的个人数据。
具体每个用户的设置文件,用户的桌面文件夹,还有用户的数据都放在这里。
每个用户都有自己的用户目录,位置为:/home/用户名。当然,root用户除外。

7./tmp
This is the Temporary folder. Think of it as a scratch directory for your Linux system. Files that won’t be needed by programs once their used once or twice are put here. Many Linux systems are set to automatically wipe the /tmp folder at certain intervals, so don’t put things you want to keep here.
这是临时目录。对于某些程序来说,有些文件被用了一次两次之后,就不会再被用到,像这样的文件就放在这里。有些linux系统会定期自动对这个目录进行清理,因此,千万不要把重要的数据放在这里。

8. /usr
Here’s where you’ll find extra utilities that don’t fit under /bin or /etc. Things like games, printer utilities, and whatnot. /usr is divided into sections like /usr/bin for programs, /usr/share for shared data like sound files or icons, /usr/lib for libraries whick cannot be directly run but are essential for running other programs.Your package manager takes care of the things in /usr for you.
在这个目录下,你可以找到那些不适合放在/bin或/etc目录下的额外的工具,比如命令、帮助文件等。
比如像游戏阿,一些打印工具拉等等。
你的软件包管理器(应该是“新立得”吧)会自动帮你管理好/usr目录的。
/usr是系统存放程序的目录,这个目录下有很多的文件和目录。当我们安装一个Linux发行版官方提供的软件包时,大多安装在这里。
如果有涉及服务器配置文件的,会把配置文件安装在/etc目录中。
(1)/usr/bin 用于存放程序。
(2)/usr/share 用于存放一些共享的数据,比如音乐文件或者图标等等。
(3)usr/lib 用于存放那些不能直接运行的,但却是许多程序运行所必需的一些函数库文件。
(4)/usr/share 系统共用的东西存放地,比如 /usr/share/fonts 是字体目录,/usr/share/doc和/usr/share/man帮助文件。
(5)/usr/bin 或 /usr/local/bin 或/usr/X11R6/bin 普通用户可执行文件目录。
(6)/usr/sbin 或 /usr/local/sbin 或 /usr/X11R6/sbin  超级权限用户root的可执行命令目录。
(7)/usr/include 程序的头文件存放目录。

9./opt
Here’s where optional stuff is put. Trying out the latest Firefox beta? Install it to /opt where you can delete it without affecting other settings. Programs in here usually live inside a single folder whick contains all of their data, libraries, etc.
这里主要存放那些可选的程序。
你想尝试最新的firefox测试版吗?那就装到/opt目录下吧,这样,当你尝试完,想删掉firefox的时候,你就可以直接删除它,而不影响系统其他任何设置。
安装到/opt目录下的程序,它所有的数据、库文件等等都是放在同个目录下面。
举个例子:刚才装的测试版firefox,就可以装到/opt/firefox_beta目录,/opt/firefox_beta目录下面就包含了运 行firefox所需要的所有文件、库、数据等等。
要删除firefox的时候,你只需删除/opt/firefox_beta目录即可,非常简单。
/opt 表示的是可选择的意思,有些软件包也会被安装在这里,也就是自定义软件包,比如在Fedora Core 5.0中,OpenOffice就是安装在这里。
有些我们自己编译的软件包,就可以安装在这个目录中;通过源码包安装的软件,可以通过 ./configure --prefix=/opt/目录。

关于/opt目录的一个小技巧
在Linux中,/opt目录是存放某些大型软件或者某些特殊软件的目录,比如谷歌浏览器(Google Chrome)默认就是安装在/opt中。
但是我们一般不会把opt单独分在一个区,因为/opt中大多数时候是空的,即使安装了软件也不会太多,而且有 些软件的容量还比较大,这样就会占用/的容量,我们可以在其它你愿意的地方建立一个目录来将/opt“转移”到别处,比如我的的/usr是单独分在一个区,容量有50G,这么大的空间不要浪费了不是?
而且/usr本来就是安装软件的地方,所以我可以/usr下建立一个叫opt的文件夹,然后右键点击这个 /usr下的opt,选择“创建链接”,得到一个名为“到 opt 的链接”文件,然后把这个文件剪切到/下,将原来的/opt删除,再将“到 opt 的链接”改名为opt就可以了,以后我们安装在/opt的软件实际上是安装到了/usr/opt下(实际上是一个符号链接)。

10./usr/local
This is where most manually installed(ie. outside of your package manager) software goes. It has the same structure as /usr. It is a good idea to leave /usr to your package manager and put any custom scripts and things into /usr/local, since nothing important normally lives in /usr/local.
这里主要存放那些手动安装的软件,即不是通过“新立得”或apt-get安装的软件。
它和/usr目录具有相类似的目录结构。
让软件包管理器来管理/usr目录,而把自定义的脚本(scripts)放到/usr/local目录下面,我想这应该是个不错的主意。
/usr/local 这个目录一般是用来存放用户自编译安装软件的存放目录;一般是通过源码包安装的软件,如果没有特别指定安装目录的话,一般是安装在这个目录中。

11./media
Some distros use this folder to mount things like usb disks, cd or dvd drives and other filesystems.
有些linux的发行版使用这个目录来挂载那些usb接口的移动硬盘(包括U盘)、CD/DVD驱动器等等。

12. /boot 
Linux的内核及引导系统程序所需要的文件目录,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,GRUB或LILO系统引导管理器也位于这个目录。
/lost+found 在ext2或ext3文件系统中,当系统意外崩溃或机器意外关机,而产生一些文件碎片放在这里。当系统启动的过程中fsck工具会检查这里,并修复已经损 坏的文件系统。
有时系统发生问题,有很多的文件被移到这个目录中,可能会用手工的方式来修复,或移到文件到原来的位置上。

13./mnt
这个目录一般是用于存放挂载储存设备的挂载目录的,比如有cdrom等目录。
可以参看/etc/fstab的定义。
有时我们可以把让系统开机自动挂载文件系统,把挂载点放在这里也是可以的。
主要看/etc/fstab中怎么定义了;比如光驱可以挂载到/mnt/cdrom。

14./sbin
大多是涉及系统管理的命令的存放,是超级权限用户root的可执行命令存放地,普通用户无权限执行这个目录下的命令,这个目录和/usr/sbin; /usr/X11R6/sbin或/usr/local/sbin目录是相似的;我们记住就行了,凡是目录sbin中包含的都是root权限才能执行的。

15./var
/var 这个目录的内容是经常变动的,看名字就知道,我们可以理解为vary的缩写。
/var/log 系统日志存放,分析日志要看这个目录的东西。
/var/www 定义Apache服务器站点存放目录。
/var/lib 用来存放一些库文件,比如MySQL的,以及MySQL数据库的的存放地。
/var/spool 打印机、邮件、代理服务器等假脱机目录;

16./proc 
操作系统运行时,进程信息及内核信息(比如cpu、硬盘分区、内存信息等)存放在这里。
/proc目录伪装的文件系统proc的挂载目录,proc并不是真正的文件系统,它的定义可以参见 /etc/fstab。

参考文献:
1. http://www.jb51.net/LINUXjishu/32180.html
2. http://firedragonpzy.iteye.com/blog/1331476

Linux_007:使用手动分区安装CentOS6.5

使用U盘安装CentOS6.5过程比较顺利,这里只重点介绍如何手动分区。

1. 选择创建自定义布局

2. 选择源驱动器,我这里是/dev/sda,点击删除按钮,删除硬盘上原有的分区。
这里的源驱动器,就是你要安装CentOS的硬盘,不要选错了,否则数据将全被删除。
删除完毕后,硬盘状态会显示为空闲状态。

3. 选择源驱动器,我这里是/dev/sda,点击创建,选择标准分区。

(1)创建 /boot 分区
挂载点:/boot
文件系统类型:ext4
允许的驱动器:只勾选自己电脑磁盘,我这里是/dev/sda
大小:100 M
其它大小选项:固定大小
勾上强制成为主分区

(2)创建 swap 分区
文件系统类型:swap
允许的驱动器:只勾选自己电脑磁盘,我这里是/dev/sda
大小:2048 M
其它大小选项:固定大小

(3)创建 /home 分区
挂载点:/home
文件系统类型:ext4
允许的驱动器:只勾选自己电脑磁盘,我这里是/dev/sda
大小:5000 M
其它大小选项:固定大小

(4)创建 / 分区
挂载点:/
文件系统类型:ext4
允许的驱动器:只勾选自己电脑磁盘,我这里是/dev/sda
大小:
其它大小选项:使用全部可用空间

4. 安装引导程序,点击更改设备。
注意,默认情况下,CentOS把引导程序安装到U盘,你需要更改为你的硬盘,我这里是/dev/sda

5. 修改BIOS驱动器顺序
第1 BIOS 驱动器:选择本地磁盘驱动器
第2 BIOS 驱动器:选择 U 盘驱动器

6. 安装完成后使用 fdisk -l 查看/dev/sda的分区
Disk /dev/sda: 20.5 GB, 20520493056 bytes
255 heads, 63 sectors/track, 2494 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xcc40cda0

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      102400   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              13         274     2097152   82  Linux swap / Solaris
Partition 2 does not end on cylinder boundary.
/dev/sda3             274        1858    12719104   83  Linux
/dev/sda4            1858        2495     5119864    5  Extended
/dev/sda5            1858        2495     5117952   83  Linux

说明:我这里只是简要介绍如何手动分区,因此只分了4个区,主要是我个人使用,这样划分就可以了,但不作为服务器分区方案推荐。

7. 服务器分区方案
以80G SCSI硬盘为服务器做的分区为例,可以参考如下划分:
(1)/ :1G
(2)swap:内存的1-2倍
(3)/boot:100M
(4)/opt:1G
(5)/tmp:4G
(6)/home:10G
(7)/usr/local:20G
(8)/var:剩余全部空间

参考文献:
1. http://blog.sina.com.cn/s/blog_51c1ed0501018lf2.html
2. http://www.cnblogs.com/davidgu/archive/2013/01/25/2876966.html
3. http://firedragonpzy.iteye.com/blog/1331476
4. http://www.jb51.net/LINUXjishu/32180.html


Cloud_019:多租户技术介绍 (摘录+整理)

多租户技术(multi-tenancy)或称多重租赁技术,是一种软件架构技术,它是在探讨与实现如何于多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。
多租户技术也是云计算的一个重要特性,在IaaS层(虚拟化)、PaaS层(应用服务器、Java虚拟机)、SaaS层(数据库、业务逻辑、工作流程、用户界面)都有体现。

下图是Gartner的多租户技术堆栈:

(1)不共享资源。每个租户都有自己一套完整的应用程序、中间件、操作系统和基础架构(硬件)。每个租户与其他租户完全隔离,惟一的例外是它能够在相同的物理数据中心中运行。
(2)共享硬件。租户开始共享一个数据中心的基础架构。例如,租户可以共享数据中心中的服务器(比如,Intel、Power)、存储(SONAS、NetApp)和网络(Juniper、Cisco)。
(3)共享操作系统。租户现在共享基础架构和操作系统。KVM 与 VMware 之类的管理程序通常用于硬件虚拟化,以便实现在硬件上运行多个操作系统。租户之间仍然保持相当程度的隔离,因为每个租户可以拥有各自版本的应用服务器、数据库服务器和及应用程序。这个级别的共享还叫做基础架构即服务 (IaaS)。
(4)共享中间件。租户现在开始共享一系列运行在共享的操作系统和基础架构之上的中间件服务;例如,安全服务、门户、数据库服务、监测服务,等等。各种应用程序都能够构建在这些共享的中间件组件之上。这一级别的共享还叫做平台即服务(PaaS)。
(5)共享应用程序。租户现在与其他租户共享相同的应用程序。基于这种共享,租户之间还可以共享相同的中间件,包括用于实现该应用程序的版本。虽然租户之间共享相同的底层资源,但他们彼此之间仍然是独立的。一个租户看不到其他租户的资产(比如存储在数据库服务器或者文件服务器中的数据)。这一级别的共享还叫做软件即服务(SaaS)。

通常,多租户所指的级别越高,创建新租户时所需做的工作越少,因为已经共享了更多的底层堆栈。
对于任何计划向越来越多租户提供的业务来说,在扩大规模时不需要增加大量技术和业务资源,这是首要考虑的问题。
对于厂商和租户来说,共享相同的代码库能够缩短实现价值的时间,并能使新的创意在几周之内(而不是几月或几年之内)完成部署。

可以看出多租户技术堆栈包括四层:基础架构层、数据中心层、应用平台层、应用程序层。
租户间的共享资源越多,资源资源利用率也越高,单位资源成本越低,租户间的隔离性越差。

各云计算厂商根据自己的技术优势,在单位资源成本和租户间的隔离性之间找到了各自的最佳平衡点。
可以看出,各大云计算的多租户解决方案基本集中在“Share Hardware”和"Share Everything"这两个级别。

以微软的Windows Azure和SalesForce的force.com为例,前者是“Share Hardware”,后者是"Share Everything"。
1. 基础架构层
即通常所说的IaaS层,为租户提供虚拟化、服务级别协议(SLA)、安全接入的身份管理、容错、灾难恢复、按需使用与计费关键特性。

2. 数据中心层
数据层有三种多租户架构:
(1)独立数据库
一个租户独享一个数据库实例,它提供了最强的分离度,租户的数据彼此物理不可见,备份与恢复都很灵活。
(2)共享数据库、独立 Schema
每个租户关联到同一个数据库的不同的Schema,租户间数据彼此逻辑不可见,上层应用程序的实现和独立数据库一样简单,但备份恢复稍显复杂。
(3)共享数据库、共享 Schema、共享数据表
租户数据在数据表级别实现共享,它提供了最低的成本,但引入了额外的编程复杂性(程序的数据访问需要用 tenantId 来区分不同租户),备份与恢复也更复杂。


目前,Hibernate 和 EclipseLink 已提供了全部或部分的多租户数据层的解决方案。

3. 应用平台层
传统JavaEE Web 应用是多用户,应用本身的实例是一个,多个应用运行在应用服务器上,一个JVM(不考虑集群的情况下),见下图:

其特点如下:
(1)Web 应用彼此的运行时内存空间不是独立的。
(2)对加载的类无法完全彼此分开。
(3)当需要水平扩展时,可以做集群和负载平衡,但需要解决多个JVM之间Session复制问题。

而多租户则在同一个应用实例上做了复制,是多个应用实例(彼此内容相同),一个实例服务于一个租户。
可以想象,如果使用传统的JavaEE来解决对多租户场景,需要为每一个应用启动一个JVM,每个 JVM 彼此独立,消耗各自的资源。但是这样资源消耗太大,有些伤不起。

一家名叫Waratek的厂商提出了自己的解决方案,它提出了一个新概念:Java 虚拟容器(Java Virtual Container,JVC),见下图:
多个应用程序可以同时运行在单个的 JVM 上,每个应用有自己的 JVC。
关于JVC的具体特性自己去Google一下这家公司吧,不过尚不清楚这一技术会不会成为JVM的新标准。

除了要应用实例的隔离以外,为了支持多租户,应用平台层还需要提供如下特性:
(1)共享LDAP:对用户和组织信息进行管理。
(2)单点登录:允许租户登录一次,就可以访问其所有的系统,而不必在每个系统中都登录一次。
(3)共享企业服务总线:每个租户对应自己的消息队列,以及消息路由规则。
(4)租户特定报告:供全面的查询和报告功能,使得用户能够创建报告,并分析数据,制定出更好的商业决策。
(5)租户特定日志文件: 租户共享相同的中间件,所以需要着重考虑如何将各个租户的日志文件分开,让每个租户仅能访问由其自身执行所生成的日志消息。

4. 应用程序层
为了支持多租户,应用程序层需要提供如下特性:
(1)统一用户界面
(2)支持用户定制界面
当然,要做到这两点的前提是租户的需求要有共性,SalesForce的force.com就是面向特定领域(CRM)的特定客户群,这些客户的需求共性明显,因此force.com可以做到这两点。

参考文献:
1. http://www.ibm.com/developerworks/cn/java/j-lo-dataMultitenant/index.html
2. http://www.ibm.com/developerworks/cn/java/j-lo-mutiltenancy/index.html
3. http://www.docin.com/p-442836132.html
4. http://zh.wikipedia.org/wiki/%E5%A4%9A%E7%A7%9F%E6%88%B6%E6%8A%80%E8%A1%93
5. http://www.docin.com/p-503913757.html
6. http://www.ibm.com/developerworks/cn/cloud/library/cl-tenantconversion/
7. http://blog.sina.com.cn/s/blog_493a84550101332d.html

2014年1月17日星期五

Linux_006:Windows 7 + CentOS6.5双系统启动配置

本以为这个问题很简单,实际安装配置过程还是遇到一点小波折,于是记录下来以备忘。

安装过程如下:

1. 先在一块物理硬盘上安装Windows 7。
过程从略。

2. 再在另一块物理硬盘上安装CentOS 6.5。
过程从略。

3. 修改BIOS,将启动的第1顺序硬盘指向安装了CentOS 6.5的硬盘。

4. 修改/boot/grub/menu.lst文件
默认情况下,CentOS 6.5识别不出Windows系统,因此修改如下:
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Windows 7
        rootnoverify (hd1,0)
        chainloader +1
title CentOS (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=VolGroup/lv_swap crashkernel=128M LANG=zh_CN.UTF-8 rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-431.el6.x86_64.img

注意,这里比较关键的地方是rootnoverify (hd1,0),其中的(hd1,0)表示第二块硬盘的第一个分区。
那么为什么是hd1呢?

分析过程如下:
我的机器有3块硬盘,根据物理连线顺序,第1块是空闲的硬盘,第2块是安装了CentOS 6.5的硬盘,第3块是安装了Windows 7的硬盘。
关于这一点的确认,可以使用Windows中自带的磁盘管理工具看一下自己机器的硬盘:


或者在Linux下运行fdisk命令查看
[maping@localhost ~]$ sudo fdisk -l

Disk /dev/sdb: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xef5bbf6a

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sdb2              64       38914   312057856   8e  Linux LVM

Disk /dev/sdc: 500.1 GB, 500107862016 bytes
183 heads, 16 sectors/track, 333597 cylinders
Units = cylinders of 2928 * 512 = 1499136 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe057b8a1

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *           1       82189   120324688    7  HPFS/NTFS
/dev/sdc2           82190      333596   368059848    f  W95 Ext'd (LBA)
/dev/sdc5           82190      164378   120324688    7  HPFS/NTFS
/dev/sdc6          164379      246567   120324688    7  HPFS/NTFS
/dev/sdc7          246568      333596   127410448    7  HPFS/NTFS

Disk /dev/sda: 20.5 GB, 20520493056 bytes
255 heads, 63 sectors/track, 2494 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xcc40cda0

   Device Boot      Start         End      Blocks   Id  System

Disk /dev/mapper/VolGroup-lv_root: 53.7 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/mapper/VolGroup-lv_swap: 7331 MB, 7331643392 bytes
255 heads, 63 sectors/track, 891 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/mapper/VolGroup-lv_home: 258.5 GB, 258524315648 bytes
255 heads, 63 sectors/track, 31430 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

那么,如此说来,Windows 7的启动硬盘设置应该是hd2,而CentOS 6.5启动硬盘设置应该是hd1。
为什么实际却是Windows 7的启动硬盘设置是hd1,而CentOS 6.5启动硬盘设置是hd0呢?

我想了一下,应该与BIOS中启动的硬盘顺序有关, 因为启动的第1顺序硬盘指向安装了CentOS 6.5,所以CentOS 6.5启动硬盘设置是hd0,以此类推,Windows 7的启动硬盘设置是hd1。

最后解释一下,因为我常用的工作平台是Windows 7,所以我把CentOS 6.5和 Windows 7启动选项交换了一下,将Windows 7作为默认启动系统。

2014年1月15日星期三

Linux_005:关于分区的那点事儿 (摘录+整理)

1. 物理硬盘的分区
主引导区(Master Boot Recorder):存放的是硬盘本身的信息,包括引导信息和分区表。
一块硬盘最多可以分成4个区,分区的类型有两种:主分区和扩展分区。
所谓主分区,就是用来计算机用来进行启动操作系统的,因此每一个操作系统的启动,或者称作是引导程序,比如Linux的bootloader引导程序都应该存放在主分区上。
这是主分区与扩展分区、以及逻辑分区的最大区别。
由于一块硬盘最多有1个扩展分区,因此一块硬盘要么划分成4个主分区,要么划分成3个主分区+1个扩展分区。
那你一定奇怪了,难道我不能把一块硬盘分成4个以上的区来使用吗?
回答是可以的,答案就在扩展分区。
因为扩展分区不能直接使用,必须将其划分为逻辑分区才行,这样就可以使用4个以上的分区了。
使用Windows中自带的磁盘管理工具看一下自己机器的硬盘:
可以看出,有3个物理硬盘,其中
(1)磁盘0,即硬盘1,有1个扩展分区,扩展分区被划分为1个逻辑分区。
(2)磁盘1,即硬盘2,有2个主分区。
(3)磁盘2,即硬盘3,有1个主分区和1个扩展分区,扩展分区被划分为3个逻辑分区。

2. Linux的硬盘分区
Linux规定了主分区(或者扩展分区)占用1-16数字的前4个数字。
Linux还为不同的硬盘规定了不同的设备名称。
对于IDE硬盘,对应于主板的四个IDE接口,设备名依次为:/dev/hda,/dev/hdb,/dev/hdc,/dev/hdd
对于SCSI硬盘,对应于主板的四个IDE接口,设备名依次为:/dev/sda,/dev/sdb,/dev/sdc,/dev/sdd
以第1个IDE硬盘为例说明,主分区(或者扩展分区)占用了 hda1、hda2、hda3、hda4,而逻辑分区占用了hda5-hda16 等 12 个号码。
因此,Linux下面每块硬盘总共最多有16个分区。

3. Linux的磁盘分区
在Windows操作系统中,是先使用盘符(比如C盘、D盘)将物理地址分开,再在各个分区上建立目录。
而Linux操作系统中正好相反,是先有目录,再将目录映射到物理地址上。
在Linux操作系统中,所有路径都是从根目录开始,安装Linux时,默认分为3个区,分别是boot分区、swap分区和根分区,这三个分区分别对应的盘符是hda1、hda2、hda3.
无论是Windows操作系统,还是Linux操作系统,每个分区均可以有不同的文件系统,如FAT32、NTFS、ext3等等。

Windows中自带的磁盘管理工具看不出硬盘2的系统,使用DiskTool可以看出这是一个Linux系统,有2个分区,应该就是/boot分区和/分区。


(1)boot 分区
该分区对应于/boot目录,约100MB。该分区存放Linux的Grub(bootloader)和内核源码。
用户可通过访问/boot目录来访问该分区。换句话说,用户对/boot目录的操作就是操作该分区。
建立一个100M的/boot主分区是为了避免将系统内核文件放到1024磁道以外,如果将/boot做为root分区的一个子目录,内核文件就会安装在root分区的任何地方,因为硬盘的大小超过了8G,所以在启动时就有可能出现问题。
这样就算工作分区出了问题,只要这个分区没有问题,同样可以启动。
因此最好的办法就是专门为根文件分一个区,大小一般最多64M,我为了保险给了100M。

(2)swap 分区
该分区没有对应的目录,故用户无法访问。或者说swap分区只能由系统访问,其大小为物理内存的2倍。
Linux下的swap分区即为虚拟内存。虚拟内存用于当系统内存空间不足时,先将临时数据存放在swap分区,等待一段时间后,然后再将数据调入到内存中执行。所以说,虚拟内存只是暂时存放数据,在该空间内并没有执行。

(3)根 分区
在Linux操作系统中,除/boot目录外的其它所有目录都对应于该分区。因此,用户可通过访问除/boot目录外的其它所有目录来访问该分区。
/小一点无所谓,据说至少2G,我也没有试验过。

(4)/home
/和/home基本上最好是要单独挂载两个分区,因为home可以看成是windows中的my document,自己个人资料多的话home要大一些。
接下来创建/home的挂载分区。考虑到我的工作文档比较多,源代码和程序也经常放到这里,所以给了10G。

(5)/user
然后创建一个尽量大的分区,给/usr,因为这里存放有大部分的系统软件,包括X Server等图形界面程序。我分了20G。

(6)/tmp
其他的诸如/tmp和/var由于活动文件特别 多,为了避免他们的文件碎片对其他区的影响,最好他们挂一个区。

(7)/var
其他的诸如/tmp和/var由于活动文件特别 多,为了避免他们的文件碎片对其他区的影响,最好他们挂一个区。

(8)/opt
最后/opt主要安装大型软件,如果有多余的分区就给他挂一个吧。

参考文献:
1. http://baike.baidu.com/view/8103329.htm
2. http://www.enet.com.cn/article/2008/0303/A20080303171898.shtml
3. http://www.liusuping.com/ubuntu-linux/linux-disk-basic.html
4. http://os.51cto.com/art/201003/186904.htm
5. http://www.zzbaike.com/wiki/CentOS/%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%96%B9%E5%BC%8F%E5%AE%89%E8%A3%85CentOS_5

Linux_004:下载MySQL时,应该选择哪个的Linux版本?

下载MySQL时,有很多种Linugx版本,见下图:


应该选择哪个Linux版本的MySQL呢?
可以参考Linux发行版来决定下载哪个Linux,见下图:

比如:我使用的是CentOS,虽然没有专门为CentOS的MySQL版本,但是CentOS是基于Red Hat的,因此应该选择Red Hat Enterprise Linux / Oracle Linux。

参考文献:
1. http://zh.wikipedia.org/wiki/Linux%E5%8F%91%E8%A1%8C%E7%89%88%E5%88%97%E8%A1%A8
2. http://os.51cto.com/art/201307/404309_all.htm

Linux_003:在CentOS6.5上安装GlassFish4.0

操作系统:CentOS6.5
下载地址:http://www.centos.org/download/
GlassFish版本:4.0
安装介质:glassfish-4.0.zip
下载地址:https://glassfish.java.net/download.html

1. 以当前用户下载安装介质,我这里是maping,查看文件属性:ls -l
-rw-rw-r--. 1 maping maping 102178360 1月  13 19:55 glassfish-4.0.zip

2. 解压glassfish压缩包: unzip glassfish-4.0.zip
如果提示无法找到unzip,运行apt-get install unzip下载unzip。

3. 查看解压后目录:ls -l
drwxr-xr-x. 8 maping maping      4096 5月  14 2013 glassfish4

4. 进入目录: cd glassfish4/glassfish/bin

5. 启动GlassFish: ./asadmin start-domain domain1

6. 停止GlassFish: ./asadmin stop-domain domain1

7. 访问GlassFish控制台:http://localhost:4848
在本机访问GlassFish控制台不需要输入口令,直接进入,然后你可以在控制台修改管理员口令。

上面的安装方法是安装到某个用户下,我这里是maping,一般用于测试环境。
比较正式的做法是创建glassfish用户,把GlassFish安装到此用户下,一般用于生产环境。

1. 切换到root用户:su root

2. 增加用户glassfish:adduser glassfish

3. 为用户glassfish设置密码:passwd glassfish

4. 增加组glassfishadm:groupadd glassfishadm 

5. 将glassfish加入glassfishadm组:usermod -a -G glassfishadm glassfish
查看/home/glassfish目录属性:ls -l
drwx------.  4 glassfish glassfish  4096 1月  13 23:38 glassfish

6. 把glassfishadmin组的目录也设为/home/glassfish:chgrp -R glassfishadm /home/glassfish
再次查看/home/glassfish目录属性:ls -l
drwx------.  4 glassfish glassfishadm  4096 1月  13 23:38 glassfish

7. 切换到glassfish用户:su glassfish

8. 下载glassfish: wget http://download.java.net/glassfish/4.0/release/glassfish-4.0.zip  

9. 把glassfish-4.0.zip 复制到/home/glassfish目录下,查看文件属性:ls -l
-rw-rw-r--. 1 glassfish glassfish 102178360 1月  14 00:39 glassfish-4.0.zip

10. 解压glassfish压缩包: unzip glassfish-4.0.zip
查看解压后目录:ls -l
drwxr-xr-x. 8 glassfish glassfish      4096 5月  14 2013 glassfish4

11. 切换到root用户: su root

12. 修改/home/glassfish目录的组为glassfishadm:chgrp -R glassfishadm /home/glassfish
再次查看解压后目录:ls -l
drwxr-xr-x. 8 glassfish glassfishadm      4096 5月  14 2013 glassfish4

13. 运行下列命令修改目录权限,确保程序可以在glassfish用户下运行
 chown -R glassfish /home/glassfish/glassfish4
 chmod -R ug+rwx /home/glassfish/glassfish4/bin/
 chmod -R ug+rwx /home/glassfish/glassfish4/glassfish/bin/
 chmod -R o-rwx /home/glassfish/bin/
 chmod -R o-rwx /home/glassfish/glassfish4/bin/

14. 切换到glassfish用户:su glassfish,以glassfish用户身份启动、停止GlassFish

参考文献:
1. http://www.nabisoft.com/tutorials/glassfish/installing-glassfish-311-on-ubuntu
2. http://www.cnblogs.com/xd502djj/archive/2011/11/23/2260094.html
3. http://blog.csdn.net/csfreebird/article/details/7649571

Linux_002:在CentOS6.5上安装JDK1.7

操作系统:CentOS6.5
下载地址:http://www.centos.org/download/
JDK版本: 1.7.0_45
安装介质:jdk-7u45-linux-x64.rpm
下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

1. 以当前用户下载安装介质,我这里是maping,查看文件属性:ls -l
-rw-rw-r--. 1 maping maping 122585894 1月  13 23:47 jdk-7u45-linux-x64.rpm

2. 切换到root用户:su root

3. 更改rpm安装文件操作权限: chmod 755 jdk-7u45-linux-x64.rpm

4. 再次查看文件属性:ls -l
-rwxr-xr-x. 1 maping maping 122585894 1月  13 23:47 jdk-7u45-linux-x64.rpm
属主有读取,写入和执行的权限,同组人和其他人只有读取和执行的权限。

5. 开始安装:rpm -ivh jdk-7u45-linux-x64.rpm

6. 安装后,会在/usr目录下,发现一个java目录,查看其目录属性:ls -l
drwxr-xr-x. 8 root root 4096 1月  13 19:31 jdk1.7.0_45

7. 设置环境变量,修改/etc/profile文件,在文件最后增加如下内容:
#Set Java Environment
export JAVA_HOME=/usr/java/jdk1.7.0_45
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH

注意,修改/etc/profile文件将对所有用户的shell都生效。
如果,你想只针对某个用户设置JDK环境,应该修改该用户主目录下的.bashrc文件,注意该文件是隐含文件。

8. 使修改的配置立即生效:source /etc/profile
注意,source /etc/profile 只对当前的Shell有效。

9. 查看JDK版本信息:java -version
如果显示出1.7.0_45 即说明安装成功。

10. 重启机器:reboot

11. 使用另一个用户,我这里是maping,再次验证JDK环境是否安装正确:
运行echo $JAVA_HOME 或 env | grep JAVA_HOME

12. 如果java -version显示的不是刚安装设置的JDK,需要修改系统默认JDK版本
CentOS默认自带OpenJDK,如果显示的是OpenJDK,需要修改系统默认JDK版本。
切换到root用户。
(1)修改软连接指向
# cd /usr/bin
# ln -s -f /usr/java/jdk1.7.0_45/jre/bin/java
# ln -s -f /usr/java/jdk1.7.0_45/bin/javac
注意,上面两个命令的这种写法,实际上是分别省略了 /usr/bin/java 和 /usr/bin/javac。
也就是说,执行完上面两个命令后,/usr/bin/java 指向 /usr/java/jdk1.7.0_45/jre/bin/java,/usr/bin/javac 指向 /usr/java/jdk1.7.0_45/bin/javac。
(2)删除旧的Java环境,也可以不做此步
# rm -f /usr/bin/java
# rm -f /usr/bin/javac
# rm -f /etc/alternatives/java
# rm -f /etc/alternatives/javac

参考文献:
1. http://linux.chinaunix.net/techdoc/develop/2007/01/20/948630.shtml

Tools_025:推荐两个好用的JSON小工具

最近在写有关JSON的代码,朋友推荐了两个好用的JSON小工具,不敢独享。

1. 格式化的JSON数据
JSON是非结构化数据,人眼看起来比较费劲,有了这个眼睛和心情都舒服多啦。
http://json.parser.online.fr/

2. 发送JSON请求,查看JSON响应
Firefox有一个很不错的插件:HttpRequester,可以查看各种HTTP请求。

下载地址:https://addons.mozilla.org/en-US/firefox/addon/httprequester/



感谢刘兵的热心推荐!