客户端和服务器程序套接字链接过程,在文章尾部。

CentOS6中httpd-2.2配置(1)

启动http服务

配置好yum源后,# yum install httpd

# service httpd start-----启动服务

在/var/www/html/下创建index.html,做一个简易页面

[root@yph6 html]# cat index.html 

<h1>hello,world</h1>

浏览器地址栏输入172.16.59.2就可该页面

注意:SElinux最好关闭,否则很可能不成功

 

httpd-2.2的常用配置

 

主配置文件:/etc/httpd/conf/httpd.conf

### Section 1: Global Environment  全局配置段

### Section 2: 'Main' server configuration  中心主机配置段,

### Section 3: Virtual Hosts  虚拟主机配置段

 

配置格式:

directive  value

directive:不区分字符大小写;

value:为路径时,是否区分字符大小写,取决于文件系统;

 

常用配置

 

备份下配置文件

/etc/httpd/conf/httpd.conf

[root@yph6 conf]# cp -pv httpd.conf{,.bak}

`httpd.conf' -> `httpd.conf.bak'

[root@yph6 conf]# ls

httpd.conf  httpd.conf.bak  magic

 

 

1、修改监听的IP和PORT

Listen  [IP:]PORT

 

(1) IP为0.0.0.0;表示主机可使用的所有IP

(2) Listen可同时监听多个端口;

Listen 80

Listen 172.16.59: 8080

(3) 修改监听socket,重启服务进程方可生效;

 

[root@yph6 conf]# vim httpd.conf

 

在编辑模式下输入/Listen,查找Listen字符串,会看到下面几行

# prevent Apache from glomming onto all bound IP addresses (0.0.0.0) ------监听地址为0.0.0.0表示监听所有该主机可以使用的IP

#

#Listen 12.34.56.78:80

Listen 80  -----监听0.0.0.0的80端口,即主机说有可用ip的80端口

 

[root@yph6 ~]# ss -tunl    ------ 80前面没有ip表示被所有ip监听

Netid     State      Recv-Q Send-Q         Local Address:Port                Peer Address:Port 

tcp      LISTEN        0       128                 :::80                                        :::*        

udp   UNCONN      0        0                 172.16.59.2:53                           *:*    

 

 

[root@yph6 ~]# netstat -tunlp | grep 80    -----会发现是httpd在监听80

tcp        0      0 :::80               :::*                   LISTEN      3202/httpd         

 

修改监听端口为8080,修改后如下:

#Listen 12.34.56.78:80

Listen 8080

 

重启服务,并发现httpd监听在8080端口

[root@yph6 conf]# service httpd restart

Stopping httpd:                                            [  OK  ]

Starting httpd:                                            [  OK  ]

[root@yph6 conf]# netstat -tnlp

tcp        0      0 :::8080                :::*                   LISTEN      3370/httpd   

 

浏览器地址栏输入172.16.59.2就不能看到之前定义的页面了,输入172.16.59.2:8080才可以

 

 

2、持久连续

Persistent Connection:tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行;

 

非持久链接:短连接

一个进程请求一个资源后必须断开重连后再请求另一个资源,因为可能有好多请求进程在排队,先打发你走,每人轮流一遍,再来第二轮,防止你一直请求让其它人一直进不来

 

保持链接:长连接,keep=alive,时间,数量

限定每个进程链接10秒后断开或请求10个资源后自动断开

保持链接的副作用:对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常 响应;

为了减少副作用:使用较短的持久连接时长,以及较少的请求数量;

 

 

在非保持链接下的请求演示:

在vim中输入/KeepAlive,看到是关闭保持链接的

KeepAlive  Off

 

换另一台主机请求:

[root@yph6 ~]# yum install telnet -y

[root@yph6 ~]# telnet 172.16.59.2  80 ---请求访问apache主机的80端口;端口不一定是80,端口不对会被拒绝

Trying 172.16.59.2...

Connected to 172.16.59.2.

Escape character is '^]'.

GET /index.html HTTP/1.1 ----http协议版本为1.1

Host: 172.16.59.2  ------指明要请求的主机。然后连按两次回车

 

<title>hello,fuck</title>  -----------请求到的资源

Connection closed by foreign host. -------链接被自动断开

 

保持链接下的配置

把KeepAlive  Off 改为KeepAlive  On

[root@yph6 conf]# service httpd restart ---重载服务

换台主机用telnet测试,发现请求完成后没有断开,而是过了几秒后断开,因为有时间限制。

 

在往下面几行定义的是单次请求数量和时间限制,数量和时间是或关系,任何一项超标就会断开。

MaxKeepAliveRequests 100  单次请求数量超过100个就自动断开

KeepAliveTimeout 15   单次请求时间超过15秒就自动断开

 

 

 

3、MPM多路处理模块

 

httpd-2.2不支持同时编译多个MPM模块,所以只能编译选定要使用的那个;CentOS 6的rpm包为此专门提供了三个应用程序文件,httpd(prefork), httpd.worker, httpd.event,分别用于实现对不同的MPM机制的支持;

 

确认现在使用的是哪下程序文件的方法:

# ps  aux  | grep httpd

root       3636  0.0  0.8 185928  3936 ?        Ss   14:16   0:00 /usr/sbin/httpd

apache   3639  0.0  0.6 186060  3148 ?        S    14:16   0:00 /usr/sbin/httpd

默认使用的为/usr/sbin/httpd,其为prefork的MPM模块 ;

 

查看httpd程序的模块列表

查看静态编译的模块:

# httpd  -l

[root@yph6 conf]# httpd -l

Compiled in modules:

  core.c

  prefork.c  ------说明用的是为prefork模块

  http_core.c

  mod_so.c

 

查看静态编译及动态装卸载的模块:

# httpd  -M

[root@yph6 conf]# httpd -M

so_module (static)

auth_basic_module (shared)

 

更换使用httpd模块,以支持其它MPM机制;

脚本文件:/etc/sysconfig/httpd

HTTPD=/usr/sbin/httpd.worker ---把这一行取消注释,表示启用worker模块

默认这一行被注释掉的,所以默认为prefork;HTTPD=/usr/sbin/httpd.event 表示启用event模块,不过httpd-2.2对event支持不够友好,所以最好不要在此用event。

修改完成后重启服务进程方可生效,#service httpd restart

 

[root@yph6 conf]# ps aux | grep httpd   ----------编程worker模块了

apache     3816  0.0  0.6 530396  3352 ?        Sl   15:14   0:00 /usr/sbin/httpd.worker

apache     3818  0.0  0.6 595932  3360 ?        Sl   15:14   0:00 /usr/sbin/httpd.worker

 

MPM的配置

[root@yph6 conf]# vim /etc/httpd/conf/httpd.conf

 编辑模式下输入/IfModule查找

 

prefork的配置

<IfModule prefork.c>

StartServers       8   ----服务刚启动时就启动的子进程数

MinSpareServers    5  -----最小空闲进程

MaxSpareServers   20

ServerLimit      256   -----最大在线进程数量,要大于等于下者

MaxClients       256 -----最大允许多少进程响应用户请求

MaxRequestsPerChild  4000 ---每个进程处理累计4000个请求后就杀死该进程

</IfModule>

 

worker的配置:

<IfModule worker.c>

StartServers         4----服务刚启动时就启动的子进程数

MaxClients         300

MinSpareThreads     25  ---最小空闲线程数

MaxSpareThreads     75 -----最大允许多少进程响应用户请求

ThreadsPerChild     25   ----每个进程可生成多少个线程

MaxRequestsPerChild  0  不限制数量

</IfModule>

 

bug:启动4个进程,每个进程25个线程,一共100个线程,但最多允许75个线程,脑残设定

[root@yph6 conf]# ps aux | grep worker  ----一共3个worker进程,第一个不是,是主控进程

root       3813  0.0  0.8 186136  4140 ?        Ss   15:13   0:00 /usr/sbin/httpd.worker

apache     3816  0.0  0.6 530396  3352 ?        Sl   15:14   0:00 /usr/sbin/httpd.worker

apache     3818  0.0  0.6 595932  3360 ?        Sl   15:14   0:00 /usr/sbin/httpd.worker

apache     3819  0.0  0.6 530396  3360 ?        Sl   15:14   0:00 /usr/sbin/httpd.worker

 

 

[root@yph6 conf]# watch -n0.5 `ps aux | grep worker`

另一终端重启服务,看到watch监控时刚开始是4个进程,过一会又删掉一个进程。

 

PV:Page View 页面浏览总量量

UV: User View 用户访问总量,按ip区分

 

4、DSO

配置指定实现模块加载

LoadModule  <mod_name>  <mod_path>

 

模块文件路径可使用相对路径:

相对于ServerRoot(默认/etc/httpd)

 

例如:

[root@yph6 conf]# ll /etc/httpd

....................modules -> ../../usr/lib64/httpd/modules

 

# vim /etc/httpd/conf/httpd.conf

查找/LoadModule,会看到好多模块,不想启用的注释掉就行了

 

 

5、定义'Main' server的文档页面路径

中心主机是物理主机,一个中心主机只能提供一个网站,而虚拟主机能提供多个网站

[root@yph6 conf]# vim /etc/httpd/conf/httpd.conf

查找/DocumentRoot  会看到

DocumentRoot "/var/www/html",在此定义web服务器的根目录为/var/www/html,也可以手动改成其他的位置,

例如改成:DocumentRoot "/web/host1l"

[root@yph6 httpd]# service httpd restart----重启服务

 

[root@yph6 httpd]# mkdir -pv /web/host1

[root@yph6 httpd]# vim /web/host1/index.html ---创建web的主页

内容为<h1>/web/host1</h1>

 

然后在浏览器中输入http://172.16.59.2/就可以访问刚才创建的了

 

<Directory "/var/www/html">  做安全访问控制的,httpd2.2不用改;httpd2.4必须改,否则改上述路径会失败。

 

 

6、定义站点主页面

vim /etc/httpd/conf/httpd.conf

查找:

DirectoryIndex  index.html  index.html.var 定义网站主页面,默认定义了这两个,先找第一个,找不到再找第二个,两个都找不到时,详解见下一条。



7、站点访问控制常见机制

 

可基于两种机制指明对哪些资源进行何种访问控制

 

文件系统路径: 例如 /web/host1/index.html

<Directory  ""> ----引号里面的路径文件都受访问控制

...

</Directory>

 

<File  "">  ----对单个文件做访问控制

...

</File>

 

<FileMatch  "PATTERN">  -----被模式匹配到的所有文件都要受访问控制

...

</FileMatch>

 

URL路径:例如 /index.html

<Location  "">

...

</Location>

 

<LocationMatch "">

...

</LocationMatch>

 

 

<Directory>中“基于源地址”实现访问控制:

(1) Options 定义此目录下资源的访问特性

Options后跟1个或多个以空格分隔的“选项”列表;常见的选项如下:

 

Indexes:指明的URL路径下不存在或者与定义的主页面资源不相符,把根目录下的文件列出来给用户选择,而不是返回404页面;对于下载页面可以用,其他网页最好别用,不安全。默认是启动这一项,一定要关掉。

 

FollowSymLinks:跟踪符号链接,允许打开符号链接指向的其他目录下的文件,即使这个文件并不在web服务器上,也不安全,建议关闭。

None:上两项都不允许,这样就安全多了。Options Indexes  FollowSymLinks改成Options None

All:所有都允许,有许多个,不止上述两个

 

Indexes测试

在文件中修改成如下:

<Directory "/web/host1">

Options Indexes  FollowSymLinks

</Directory>

 

然后重启服务:

[root@yph6 conf]# service httpd restart

[root@yph6 httpd]# mv /web/host1/index.html{,.bak}

[root@yph6 httpd]# ls /web/host1  

index.html.bak    ------------------现在即没有index.html又没有index.html.var

[root@yph6 httpd]# touch /web/host1/{a,b,c}  ------再创建几个文件,便于稍后查看

 

[root@yph6 httpd]# vim /etc/httpd/conf.d/welcome.conf  ---这个一定要改,否则跳转到apache官方指定页面去了

 把 Options -Indexes 改为   Options Indexes


在浏览器输入172.16.59.2会看到下列列表:

a            12-Jan-2016 17:28    0

b            12-Jan-2016 17:28    0

c            12-Jan-2016 17:28    0

index.html   12-Jan-2016 16:25    20


FollowSymLinks测试

[root@yph6 httpd]# ln -sv /etc/fstab /web/host1/test.html

`/web/host1/test.html' -> `/etc/fstab'

浏览器输入http://172.16.59.2/test.html就可以看到/etc/fstab文件的内容了,虽然这个文件并不在web服务器上。

 

 

(2)  AllowOverride

与访问控制相关的哪些指令可以放在.htaccess文件(网站中每个目录下都可以有一个这个文件)中;放入这个文件后,在当前配置文件httpd.conf配置的指令就无效,在这个.htaccess文件中配置的才有效。但是这样会降低服务器性能,所以用处不大。一般用法为AllowOverride None。

 

(3) order和allow、deny

控制谁可以访问指定页面的资源

order:定义生效次序;allow和deny它两个谁写在后面谁默认生效;

 

 

<Directory "/web/host1"> ------"/web/host1"表示针对这单个服务器,对其他服务器不做限制。

Order allow,deny   ----------deny在后,表示都拒绝访问,除了Allow from定义的ip

    Allow from 172.16.59.0

</Directory >

 

<Directory />   -------表示本主机的所有服务器都生效。

Order deny,allow   ---------allow在后,表示都允许访问,除了Deny from定义的ip

    Allow from 172.16.59.0

 

</Directory>

 

allow和deny ip的格式:

单个IP

网络地址NetAddr:以下写法效果都一样,看个人喜好

172.16

172.16.0.0

172.16.0.0/16

172.16.0.0/255.255.0.0

 

用linux主机访问web服务器:

curl http://172.16.59.2

 

8、定义路径别名

格式:

Alias  /URL/  "/PATH/TO/SOMEDIR/"

 

# vim /etc/httpd/conf/httpd.conf

在Alias /icons/ "/var/www/icons/"一行下面加一行:

Alias /download/ “/www/htdocs/”

在浏览器输入172.16.59.2/download/,会自动显示出/www/htdocs/目录下的页面,就算不存在download目录也可以

 

 

9、设定默认字符集

查找AddDefaultCharset,会看到下面一行:

AddDefaultCharset  UTF-8   ------表示用UTF-8字符标准

若改成下面的:

AddDefaultCharset  GBK UTF-8 ----以第一个为准,即是GBK标准

中文字符集包括:UTF-8 ,GBK, GB2312, GB18030

 

10、日志设定

错误日志:

# vim /etc/httpd/conf/httpd.conf

查找:/ErrorLog 若显示出的是后面的,想要看前面的,用#可以向上翻,找到上一个ErrorLog

ErrorLog logs/error_log  -----用的是相对路径,绝对路径是/etc/httpd/logs/error_log

 

LogLevel  warn ----定义日志级别

可用级别如下:

debug, info, notice, warn, error, crit, alert, emerg.

debug:最低,所有出错的统统记录下来

notice:开始需要引起注意了

crit:严重了

alert:红色警戒

emerg:十万火急,千钧一发

 

访问日志

查找:

CustomLog  logs/access_log  combined 

combined表示记录的格式,例如要记录访问时间,ip,浏览器类型等

 

除了combined还有三种类型common,referer,agent,如下:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

LogFormat "%h %l %u %t \"%r\" %>s %b" common

LogFormat "%{Referer}i -> %U" referer

LogFormat "%{User-agent}i" agent

combined混合了下面三种格式,是他们三个的总和;\是用来转义双引号的

 

日志格式类型官方文档说明:

http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats

 

%h:记录客户端IP地址;----------172.16.59.0

%l:Remote User, 通常为一个减号(“-”);登陆名,-

%u:Remote user (from auth; 非为登录访问时,其为一个减号;用户名,-

%t:服务器收到请求时的时间;--------------------[12/Jan/2016:19:14:06 +0800]

%r:First line of request,即表示请求报文的首行;记录了此次请求的“方法”,“URL”以及协议版本;---------------------------"GET /favicon.ico HTTP/1.1"

%>s:响应状态码;404页面,304等; -----------------404

%b:响应报文的大小,单位是字节;不包括响应报文的http首部;  ----------286

%{Referer}i:请求报文中首部“referer”的值;即从哪个页面中的超链接跳转至当前页面的;直接输入的用“-”表示。

%{User-Agent}i:请求报文中首部“User-Agent”的值;即发出请求的应用程序;浏览器程序及curl,爬虫等。

------------------------------"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"

 

[root@yph6 httpd]# tail -1 /var/log/httpd/access_log

172.16.59.0 - - [12/Jan/2016:19:14:06 +0800] "GET /favicon.ico HTTP/1.1" 404 286 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"

 

 

11、基于用户的访问控制

通过http协议认证的,可以设置必须登陆才能访问,但http协议认证密码是明文的,非常容易被破解;不像是京东是通过服务器数据库认证的

 

http认证方式:

basic:

digest:摘要认证(不过现在很少使用)

 

认证质询:

WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码;

认证:

Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源;

 

安全域:用户认证后能够访问的资源;应该通过名称对其进行标识,以便于告知用户认证的原因;

 

用户的账号和密码,由于不是登陆系统的账号称为虚拟账号

虚拟账号:仅用于访问某服务时用到的认证标识

 

账号密码存储位置:

文本文件;

SQL数据库;

ldap目录存储;轻量级目录服务访问协议

 

basic认证配置示例

(1) 定义安全域

<Directory "">

Options None

AllowOverride None

AuthType Basic  ------认证类型

AuthName "String“  ------给用户的提示信息

AuthUserFile  "/PATH/TO/HTTPD_USER_PASSWD_FILE"  -----认证账号密码存放的文件

Require  user  username1  username2 ...  -----账号密码文件中的这些用户才能登录

</Directory>

 

若要允许账号文件密码中的所有用户登录访问,则换成下面一行:

Require  valid-user   -----注意 容易写错,别忘记把Require后的user删掉

 

下面演示操作过程:

[root@yph6 httpd]# cd /web/host1

[root@yph6 host1]# mkdir admin

[root@yph6 host1]# vim admin/index.html ---新增一个目录并为之创建主页

<h1>admin page</h1>

 

[root@yph6 conf]# vim /etc/httpd/conf/httpd.conf

添加:

<Directory "/web/host1/admin">

        Options None

        AllowOverride None

        AuthType Basic

        AuthName "fuck you ,please enter your login name and passwd"

        AuthUserFile "/etc/httpd/conf/.htpasswd"

        Require user tom

</Directory>

 

创建用户账户和密码

[root@yph6 conf]# htpasswd -c -m /etc/httpd/conf/.htpasswd tom

[root@yph6 conf]# htpasswd  -m /etc/httpd/conf/.htpasswd jack

添加两个用户tom和jack,并为之设置密码。

-c表示创建此文件,如果文件存在会清空文件,所以第二次不能加-c

 

[root@yph6 conf]# httpd -t    -----测试语法错误

Syntax OK

[root@yph6 host1]# service httpd configtest -----也可测试语法

Syntax OK

 

[root@yph6 conf]# service httpd reload  ----重载配置文件

 

在浏览器中输入http://172.16.59.2/admin/,会提示你fuck you ,please enter your login name and passwd,登录tom用户后就能访问,但jack不能,因为没把jack加入列表;但是这个账号密码会保留一段时间,这短时间内不需重新输入密码。

 

(2) 提供账号和密码存储的命令

htpasswd  [options]   /PATH/TO/HTTPD_PASSWD_FILE  username

-c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用,如果文件存在会清空文件;

-m:md5格式加密

-s :sha格式加密

-D:删除指定用户

 

 

基于组账号进行认证

(1) 定义安全域

<Directory "/web/host1/admin">

        Options None

        AllowOverride None

        AuthType Basic

        AuthName "fuck you ,please enter your login name and passwd"

        AuthUserFile "/etc/httpd/conf/.htpasswd"

        AuthGroupFile "/etc/httpd/conf/.htgroup"  -------与基于用户演示,仅新增了这一行,和修改了下一行

        Require group mygrp       ------------修改最后一行

</Directory> 

 

(2)创建组文件

[root@yph6 host1]# vim /etc/httpd/conf/.htgroup  ----由于组不用加密,可以直接vim编辑

mygrp:tom obama   ----每行一个组

[root@yph6 host1]# htpasswd -m /etc/httpd/conf/.htpasswd obama -----刚才没添加obama,现在加上

 

[root@yph6 host1]# httpd -t  ------检测语法

Syntax OK

[root@yph6 host1]# service httpd reload  ----重载配置文件

 

再去浏览器测试就会发现只有组内的tom和obama可以登录,组外的jack无法登录。

 

 

 

12、虚拟主机:  --------至关重要

通常一个物理主机只能提供一个网站,但一个物理主机可以模拟多个虚拟主机,每个主机可以提供一个网站。对于访问量不是很大的服务器非常适合做虚拟主机。

一般虚拟机不要与中心主机混用;因此,要使用虚拟主机,得先禁用'main'主机;

禁用方法:注释中心主机的DocumentRoot指令即可;

 

如何在一台主机上标示不同网站呢?

站点标识方法: socket

IP相同,但端口不同; ----一旦你不使用80端口,用户不知道如何访问

IP不同,但端口均为默认端口;  -----公网IP收费的,许多IP话费很高的

FQDN,域名不同;

-------通过请求报文中的http首部实现,不是通过IP首部实现。粗略可以理解为这种socket由FQDN,IP和端口三个组成,域名不同套接字就不同了。

 

 

虚拟主机的配置方法,两条指令就可以了:

<VirtualHost  IP:PORT>

ServerName FQDN

DocumentRoot  ""

</VirtualHost>

 

其它可用指令:

ServerAlias:虚拟主机的别名;可多次使用;

ErrorLog:虚拟主机自己专用的错误日志

CustomLog:虚拟主机自己专用的访问日志

 

<Directory ""> ----基于文件路径做访问控制

...

</Directory>

Alias    --------路径别名

...

 

基于IP的多个虚拟主机配置

(1)配置IP,创建虚拟主机的根目录及html文件:

[root@yph6 host1]# ifdown eth1  -----关闭eth1网卡,给eht0再配2个IP地址,方便演示

[root@yph6 host1]# ifconfig eth0:0 172.16.59.4/16

[root@yph6 host1]# ifconfig eth0:1 172.16.59.5/16

 

[root@yph6 host1]# mkdir -pv /www/{a,b,c}.com/htdocs ---给三个主机web服务器创建根目录

 

[root@yph6 host1]# vim /www/a.com/htdocs/index.html -----分别给给三个虚拟主机web服务器创建主页面

<h1>a.com 172.16.59.2</h1>   -----------------------------文件的内容

[root@yph6 host1]# vim /www/b.com/htdocs/index.html

<h1>b.com 172.16.59.4</h1>

[root@yph6 host1]# vim /www/c.com/htdocs/index.html

<h1>c.com 172.16.59.5</h1>

 

 

(2)修改配置文件:

[root@yph6 host1]# vim /etc/httpd/conf/httpd.conf

注释掉下面这一行

#DocumentRoot "/web/host1"

[root@yph6 host1]# vim /etc/httpd/conf.d/vhosts.conf ------新建文件并添加下面内容添加

<VirtualHost 172.16.59.2:80>

        ServerName www.a.com

        DocumentRoot "/www/a.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.4:80>

        ServerName www.b.com

        DocumentRoot "/www/b.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.5:80>

        ServerName www.c.com

        DocumentRoot "/www/c.com/htdocs"

</VirtualHost>

 

[root@yph6 host1]# httpd -t  -----语法检测

Syntax OK

[root@yph6 host1]# service httpd reload  -----重载配置文件

 

(3)成败测试:

分别在浏览器中输入172.16.59.2,172.16.59.4,172.16.59.5就可以看到刚才定义的三个主页了,亲自试验成功。

不过成功之前历经波折,刚开始只有b.com,c.com可以正常访问,a.com还是跳转到原来的中心主机,怎么改都不行,DocumentRoot明明注释掉了,而且把中心主机的根目录都删掉了,怎么可能会访问到中心主机的主页呢!?非常诡异。后来回去睡一觉在开机就好了,想想可能是浏览器缓存,瞎猜的。不过重启后只有a.com 可以用,b.com和c.com不能访问,后来发现是后两者之前配置的ip是临时的,重启后需重新配置,这下就把问题解决了。

 

[root@yph6 ~]# vim /etc/httpd/conf/httpd.conf

把#ServerName www.example.com:80改成下面,并取消注释

ServerName localhost:80

不改的话语法检测时会有警告,虽然不是错误

 

 

基于端口的虚拟主机

把文件内容改成如下:

Listen 808 -------这两个端口默认未被监听,所以要加上

Listen 8080

<VirtualHost 172.16.59.2:80>

        ServerName www.a.com

        DocumentRoot "/www/a.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.2:808>

        ServerName www.b.com

        DocumentRoot "/www/b.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.2:8080>

        ServerName www.c.com

        DocumentRoot "/www/c.com/htdocs"

</VirtualHost>

 

[root@yph6 ~]# httpd -t

Syntax OK

[root@yph6 ~]# service httpd restart -----改端口后要重启,而不是重载

 

浏览器中分别输入http://172.16.59.2/,http://172.16.59.2:808/,http://172.16.59.2:8080/,就发现三个页面都可以访问了。

 

基于IP和端口是可以混合使用的。

 

 

基于FQDN的虚拟主机

把配置文件改成:

NameVirtualHost 172.16.59.2:80

<VirtualHost 172.16.59.2:80>

        ServerName www.a.com

        DocumentRoot "/www/a.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.2:80>

        ServerName www.b.com

        DocumentRoot "/www/b.com/htdocs"

</VirtualHost>

<VirtualHost 172.16.59.2:80>

        ServerName www.c.com

        DocumentRoot "/www/c.com/htdocs"

</VirtualHost>

 

语法检查及重启服务

[root@yph6 ~]# httpd -t

Syntax OK

[root@yph6 ~]# service httpd restart

 

修改hosts文件:

[root@yph6 ~]# vim /etc/hosts ------win7修改hosts文件方法与linux完全一样,也是下面两种形式

172.16.59.2 www.a.com www.b.com www.c.com

或者

172.16.59.2 www.a.com a.com

172.16.59.2 www.b.com b.com

172.16.59.2 www.c.com c.com

 

测试结果:

[root@yph6 ~]# curl www.a.com

<h1>a.com 172.16.59.2</h1>

[root@yph6 ~]# curl www.b.com

<h1>b.com 172.16.59.4</h1>

[root@yph6 ~]# curl www.c.com

<h1>c.com 172.16.59.5</h1>

 

 

13、status页面

此页面可以显示整个服务器的各进程的状态,一般此页面不允许外人看到的

[root@yph6 ~]# vim /etc/httpd/conf/httpd.conf

确保此模块是装载的,即这一行没被注释掉

LoadModule status_module modules/mod_status.so 

 

然后仍在此文件查找下面内容

#<Location /server-status>

#    SetHandler server-status

#    Order deny,allow

#    Deny from all

#    Allow from .example.com

#</Location>

然后修改成下面内容,取消注释

<Location /server-status>

SetHandler server-status

Order allow,deny

Allow from 172.16

</Location>

 

[root@yph6 ~]# httpd -t ----语法检测

Syntax OK

[root@yph6 ~]# !ser  -----表示引用上一个以ser开头的命令

service httpd restart-----重启

 

浏览器访问http://www.a.com/server-status会看到Apache Server Status for www.a.com页面。

 

__W__K__........................................................

................................................................

................................................................

................................................................

 

一共有8个进程,一个K状态,一个W状态,其余是空闲状态

Scoreboard Key:

"_" Waiting for Connection,  表示空闲状态

"S" Starting up,  正在创建

"R" Reading Request,正在读取请求

"W" Sending Reply, --表示正在发送响应的进程

"K" Keepalive (read), 正在读取

"D" DNS Lookup, 正在进行DNS查询

"C" Closing connection, 正在关闭链接

"L" Logging, 正在近路日志

"G" Gracefully finishing,正在优雅关闭,已经启动关闭模式,等待对方把进程完全关闭,然后自己才关闭

"I" Idle cleanup of worker, 空闲的清理线程

"." Open slot with no current process空闲位,每个空闲位都可启动一个进程

 

PID Key: 这8个进程的进程号,和所处状态

   4153 in state: _ ,   4154 in state: _ ,   4155 in state: W 

   4156 in state: _ ,   4157 in state: _ ,   4158 in state: K 

   4159 in state: _ ,   4160 in state: _ ,



客户端和服务器程序套接字链接过程:


wKioL1aWUvjyhXoRAABXJtZGCOk305.png



服务器:

socket:向内核或库发起socket库调用,创建套接字;

bind:套接字绑定端口,例如web服务器绑定80端口(IP+端口组成;会霸占一个端口,其他套接字就不能再用此端口)

listen:监听此套接字上,监听并不一定接待

accept:处于等待随时接客的状态,如果一直没有客户端请求,则一直等待接客(也叫阻塞或睡眠状态)一旦客户机的connect到达,就立即经过三牵手建立连接,

read:从套接字里读取客户的请求,看它想要什么

write:然后处理后,把客户想要的东西写入套接字

read:服务器读到了客户机的分手请求,心想你妹啊,分就分。

close:关闭服务,等待遇到新的另一半。

客户端:

connect:拿着服务器ip和端口,并连接服务器

write:在三牵手中的第三次牵手时,客户机把请求写入套接字,(把×××器的第一件事告诉它);一切皆文件,套接字也是文件,写入文件。

read:从套接字里拿走自己想要的,如果一件事办完后还想办第二件事,就继续write

close:客户端已经拿到自己想要的东西了,就应该把分手把服务器甩了,即关闭请求。经过四次分手。



TCP FSM:有限状态机状态转换

closed listen syn_sent syn_recv establish fin_wait1 close_wait fin_wait2 last_ack timewait closed

链接三牵手:每个连接都是单向的

一牵手:客户机的请求进程请求,服务器受到后,用自己的接收进程与之配对

二牵手:服务器的请求进程请求,客户机接收进程再与之配对

三牵手:服务器与之应答,告诉客户机连接建立完成,确立恋爱关系


四次分手图例:
wKiom1aWUsbRxUZGAAEe19rUVi0383.jpg


断开四分手:

一分手:客户机说要分手,要关闭一牵手时的请求进程

二分手:服务器同意,关闭与之配置的进程

三分手:服务器说要关闭二牵手时的请求进程

四分手:客户机同意并关闭与之配对的进程

 

四分手:

a:客户机提出分手

b:服务器同意分手

c:客户机收到服务器的同意回答

d:服务器把之前的信件都还给客户端

e:客户机收到还回来的信件

f:客户端把服务器的信件还给服务器

g:服务器收到信件,分手完成

 

fin_wait1:a-c

fin_wait2:c-e

time_wait:e-f,应为报文传输时间的二倍

close_wait:b-d

last_ack:d-g

closed:g--重回单身时代,listen