httpd详解

    httpd是一款高效的服务器应用程序,是http协议的一种实现。在探讨httpd之前,我们来大概了解一下http协议吧,http协议实现了客户端和web服务器之间的通信,它是一种应用层协议。

http协议特性:

1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

http协议工作流程:

一次完整的http请求处理过程:
    (1) 建立或处理连接:接收请求或拒绝请求
    (2) 接收请求:接收来自于网络的请求报文中对某资源的一次请求的过程;
        并发访问响应模型(Web I/O):
            1单进程I/O结构:启动一个进程处理用户请求,而且一次只处理一个;多个请求被串行响应;
            2多进程I/O结构:并行启动多个进程,每个进程响应一个请求;
            3复用I/O结构:一个进程响应n个请求;
                多线程模型:一个进程生成N个线程,每个线程响应一个用户请求;
                事件驱动:event-driven
            4复用的多进程I/O结构:启动多个(m)进程,每个进程响应n个请求;
    (3) 处理请求:对请求报文进行解析,并获取请求的资源及请求方法等相关信息
        元数据:请求报文首部
        <method> <URL> <VERSION>
        Host: www.magedu.com   请求的主机名称
        Connection:
    (4) 访问资源:获取请求报文中请求的资源
        web服务器,即存放了web资源的服务器,负责向请求者提供对方请求的静态资源,或动态运行后生成的资源;这些资源放置于本地文件系统某路径下,此路径通常称为DocRoot
        web服务器资源路径映射方式:
            (a) docroot
            (b) alias
            (c) 虚拟主机docroot
            (d) 用户家目录docroot
    例如:url与Docroot映射方式:/var/www/html/images/1.jpg --->http://www.lee.com/images/1.jpg       

    (5) 构建响应报文
        资源的MIME类型:
            显式分类
            魔法分类
            协商分类
        URL重定向:
            web服务构建的响应并非客户端请求的资源,而是资源另外一个访问路径;
    (6) 发送响应报文
    (7) 记录日

我们访问某站点,一定会在浏览器里输入站点的url地址,我们来分析一下url的格式

URL组成格式:基本语法:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
    params参数示例:根据用户请求url传递的参数判定返回的内容(有过滤作用),例如负载均衡集群里可以通过设置params中"user=某用户"实现定向同一个用户请求到特特定服务器

wKiom1YWbGjjEWTzAAGRSs0_XhQ031.jpg

    http://www.magedu.com/bbs/hello;gender=f
    query示例:指定查询条件(类似于mysql里WHERE子句),比如要与数据库等存储交互时用到
    http://www.magedu.com/bbs/item.php?username=tom&title=abc

wKioL1YWbMnx7WgCAAGXP3N3gGI897.jpg
    frag示例:用于定位而直接跳转到你感兴趣的地方
    https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html-single/Installation_Guide/index.html#ch-Boot-x86

wKioL1X9b1bxLpj-AAJpldFjZqk190.jpg

相对url:同站引用(相对于当前位置定位资源,不完整的url)

绝对url:跨站引用


http报文格式:
1.request报文
    <method> <request-URL> <version>
    <headers>
    <entity-body>
2.response报文
    <version> <status> <reason-phrase>
    <headers>
    <entity-body>
解析:
    1.method: 请求方法,标明客户端希望服务器对资源执行的动作
    GET、HEAD、POST
    2.version:HTTP/<major>.<minor> http协议的版本
    3.status:
    三位数字,如200,301, 302, 404, 502; 标记请求处理过程中发生的情况;
    4.reason-phrase:
    状态码所标记的状态的简要描述;
    5.headers:
    每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟上一个可选空格,接着是一个值;
    6.entity-body:请求时附加的数据或响应时附加的数据----请求的资源;
详解:
    1.method(方法):
        GET:从服务器获取一个资源;
        HEAD:只从服务器获取文档的响应首部;
        POST:向服务器发送要处理的数据;
        PUT:将请求的主体部分存储在服务器上;
        DELETE:请求删除服务器上指定的文档;
        TRACE:追踪请求到达服务器中间经过的代理服务器;
        OPTIONS:请求服务器返回对指定资源支持使用的请求方法;
    协议查看或分析的工具:
        tcpdump, tshark, wireshark
    2.status(状态码):
        1xx:100-101, 信息提示;
        2xx:200-206, 成功
        3xx:300-305, 重定向
        4xx:400-415, 错误类信息,客户端错误
        5xx:500-505, 错误类信息,服务器端错误
    常用的状态码:
        200: 成功,请求的所有数据通过响应报文的entity-body部分发送;OK
        301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently
        302: 与301相似,但在响应报文中通过Location指明资源现在所处临时新位置; Found
        304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;Not Modified
        401: 需要输入账号和密码认证方能访问资源;Unauthorized
        403: 请求被禁止;Forbidden
        404: 服务器无法找到客户端请求的资源;Not Found
        500: 服务器内部错误;Internal Server Error
        502: 代理服务器从后端服务器收到了一条伪响应;Bad Gateway
    headers:(列举了部分headers类型,再往下的首部分类中解释了这些headers)
        格式:Name: Value
        Cache-Control:public, max-age=600
        Connection:keep-alive
        Content-Type:image/png
        Date:Tue, 28 Apr 2015 01:43:54 GMT
        ETag:"5af34e-ce6-504ea605b2e40"
        Last-Modified:Wed, 08 Oct 2014 14:46:09 GMT
        Accept:image/webp,*/*;q=0.8
        Accept-Encoding:gzip, deflate, sdch
        Accept-Language:zh-CN,zh;q=0.8
        Cache-Control:max-age=0
        Connection:keep-alive
        Host:access.redhat.com
        If-Modified-Since:Wed, 08 Oct 2014 14:46:09 GMT
        If-None-Match:"5af34e-ce6-504ea605b2e40"
        Referer:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html-single/Installation_Guide/index.html
        User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36

首部的分类:
        通用首部
        请求首部
        响应首部
        实体首部(作用域body)
        扩展首部

1.通用首部:
        Date: 报文的创建时间
        Connection:连接状态,如keep-alive, close
        Via:显示报文经过的中间节点
        Cache-Control:控制缓存
        Pragma:缓存相关
2.请求首部:
        Accept:通过服务器自己可接受的媒体类型;
        Accept-Charset:
        Accept-Encoding:接受编码格式,如gzip
        Accept-Language:接受的语言
        Client-IP: 客户端ip
        Host: 请求的服务器名称和端口号,虚拟主机解析时用到
        Referer:包含当前正在请求的资源的上一级资源;(从哪跳转来的)
        User-Agent:客户端代理,就是浏览器类型
3.条件式请求首部:
        Expect:通知服务器我能接受的媒体类型(MIME类型)
        If-Modified-Since:自从指定的时间之后,请求的资源是否发生过修改;使用缓存
        If-Unmodified-Since:与上面一条相反,覆盖缓存
        If-None-Match:本地缓存中存储的文档的ETag(扩展标签)是否与服务器文档的Etag不匹配;
        If-Match:和上一条相反,返回缓存就可以了,上一条必须覆盖原先缓存
4.安全请求首部:
        Authorization:向服务器发送认证信息,如账号和密码;
        Cookie: 客户端向服务器发送cookie
        Cookie2:
5.代理请求首部:
        Proxy-Authorization: 向代理服务器认证
6.响应首部:
    信息性:
        Age:响应持续时长
        Server:服务器程序软件名称和版本
7.协商首部:某资源有多种表示方法时使用
        Accept-Ranges:服务器可接受的请求范围类型
        Vary:服务器查看的其它首部列表;
8.安全响应首部:
        Set-Cookie:向客户端设置cookie;
        Set-Cookie2: 向客户端设置第二版cookie
        WWW-Authenticate:来自服务器的对客户端的质询认证表单
9.实体首部:描述主体的长度和内容,或者资源自身
    Allow: 列出对此实体可使用的请求方法
    Location:告诉客户端真正的实体位于何处
        Content-Encoding:
        Content-Language:
        Content-Length: 主体的长度
        Content-Location: 实体真正所处位置;
        Content-Type:主体的对象类型
10.缓存相关:
    ETag:实体的扩展标签;
    Expires:实体的过期时间;
    Last-Modified:最后一次修改的时间

http协议是无状态的,也就是说服务器无法持续追踪定位访问者来源

使用cookie:客户端第一次访问某个服务器时,每个服务器为了识别客户端,会发送一个唯一的标示数据给客户端,客户端浏览器保存这个数据到本地磁盘中,今后客户端访问这个服务器时会携带这个信息说明自己的身份,实现了服务器可以追踪客户端,胖cookie记录的用户个人信息很多,异常不安全,可适当使用轻cookie-----session。

session:我们需要跟踪客户端的同时又不能允许客户端缓存这些信息(不安全,可能我们输入了账号密码,不能让别人看见),就像淘宝的购物车,部分用户访问的行为会保存于服务器上,session是关联于cookie的

火狐浏览器F12键可以输出http报文信息:

wKiom1X9enbzt73HAAQUv-UROIw040.jpg

有了这些基础概念,我们来了解一下httpd:

实验过程中关闭selinux和iptables(iptables -F)

1.httpd的配置文件

程序环境
    配置文件:
    /etc/httpd/conf/httpd.conf
    /etc/httpd/conf.d/*.conf

wKiom1X9I3GQuuJJAABbOHrSwQM717.jpg

    服务脚本:
    /etc/rc.d/init.d/httpd
    MPM配置文件:/etc/sysconfig/httpd
    主程序文件:
    /usr/sbin/httpd
    /usr/sbin/httpd.event
    /usr/sbin/httpd.worker
    日志文件目录:
    /var/log/httpd
    access_log: 访问日志
    error_log:错误日志
    站点文档目录:
    /var/www/html
    模块文件路径:
    usr/lib64/httpd/modules


    配置格式:directive value-------指令 值  格式
    directive: 不区分字符大小写;
    value: 为路径时,取决于文件系统;

  1. 配置监听的端口:(端口,套接字等相关概念请看上一篇博客) 

省略ip表示监听本机所有IP; Listen可重复出现多次;

wKioL1X9KBXzbc3vAAC160JQ1EQ789.jpg

修改完成后重读配置文件service httpd restart

查看监听的端口:发现tcp80和8080都监听了

wKiom1X9JlKREG-3AADs8FQpaUs225.jpg

2.非持久连接:每请求一个资源都需要建立一次tcp/ip会话,浪费带宽

持久连接:连接建立,每个资源获取完成后tcp/ip会话不会断开连接,而是继续等待其它的请求完成;

副作用:对并发访问量较大的服务器,持久连接功能会使用有些请求得不到响应;
折衷:使用较短的持久连接时间;
httpd-2.4 支持毫秒级持久时间;

KeepAlive On|Off  持久连接开关
MaxKeepAliveRequests #  持久连接最大请求资源数量
KeepAliveTimeout # 持久连接超时时间

wKioL1X9KWqCxs29AAEosh2JrJk127.jpg

使用telnet测试http会话:因为开启了长连接,所以请求完没断开连接,可以继续请求资源

wKioL1X9LHbDHDcGAAFL3eqk_W4446.jpg

3.MPM:多道处理模块

prefork:多进程模型,每个进程响应一个请求;
    一个主进程:负责生成n个子进程,子进程也称为工作进程,每个子进程处理一个用户请求;即便没有用户请求,也会预先生成多个空闲进程,随时等待请求到达;最大不会超过1024个;
worker:多线程模型,每个线程响应一个请求;
    一个主进程:生成多个子进程,每个子进程负责生个多个线程,每个线程响应一个请求;
    m进程,n线程:m*n                    
event:事件驱动模型,每个线程响应n个请求;
    一个主进程:生成m个子进程,每个进程直接n个请求;
    m*n

它把服务进程从连接中分离出来,在开启KeepAlive场合下相对worker模式能够承受的了更高的并发负载

httpd-2.2不支持同时编译多个模块,所以只能编译时选定一个;rpm安装的包提供三个二进制程序文件,分别用于实现对不同MPM机制的支持;确认方法:

wKiom1X9K6yBVxo5AABS1k7ZaJw284.jpg

更改默认使用的MPM:/etc/sysconfig/httpd文件

wKiom1X9LWWg5PvJAAEC6EYa6fQ642.jpg

发现了httpd.worker和httpd.event程序,默认启动的是httpd,也就是prefork模型

wKioL1X9L6DhDU9vAADQ7A8Vtxg382.jpg

httpd.conf配置文件中定义的MPM属性:

对于prefork模型:

StartServers       8    启动httpd时启动多少个主控进程生成的子进程进程
MinSpareServers    5    最小空闲进程数
MaxSpareServers   20    最大空闲进程数
ServerLimit      256    限定最多允许并发进来的活动用户连接个数,在线进程数量最大值
MaxClients       256    最多允许启动多少个进程
MaxRequestsPerChild  4000 一个进程最多响应多少个请求,多于4000就杀死这个进程

wKioL1X9MYDyf103AAE-_SPdPTk878.jpg

对于worker模型:

StartServers         4  启动httpd时启动多少子进程
MaxClients         300  最多允许启动多少个线程(最大并发请求数)
MinSpareThreads     25  最小的空闲线程数
MaxSpareThreads     75  最大的空闲线程数
ThreadsPerChild     25  允许每个进程最多生成多少个线程
MaxRequestsPerChild  0  设置一个独立的子进程将能处理的请求数量

wKiom1X9L0XxBAF2AAErWmArCOc220.jpg

300*86400/50=40W+,全负荷全天处理总的请求数/每个连接请求的资源数=pv

4.查看httpd的模块:

静态编译进httpd的模块

wKioL1X9Lo_T_Wl7AAAvFk8rYWQ313.jpg

event程序的:

wKiom1X9Lb3CXeaKAAAyYN7NPnc639.jpg

查看静态编译及动态装载的已在当前服务上被装载了的模块

wKiom1X9LK3wgD4eAAC7xugCx68247.jpg

5.pv和uv:

PV(访问量):PV反映的是浏览某网站的页面数,只算页面入口的访问量,就是说PV与来访者的数量成正比,但PV并不是页面的来访者数量,而是网站被访问的页面数量。

UV(独立访客):可以理解成访问某网站的电脑的数量。网站判断来访电脑的身份是通过来访电脑的cookies实现的。如果更换了IP后但不清除cookies,再访问相同网站,该网站的统计中UV数是不变的。

一台服务器:每个进程5秒响应1个请求,1024个进程5秒可以响应1024个请求,一分钟就是1024*12个,一天就是1024*12*1440(分钟)~=17000k个
但是每个网站有多个页面,每个页面又有N个资源,每个资源就是一个请求,假设每个页面包含100个资源,1700k/100=17k个,所以单台服务器一天最多也就17k个
带宽大小~=每个请求大小*并发数

6.DSO机制:

配置指令实现模块加载
    LoadModule <mod_name> <mod_path>
模块路径可使用相对地址
    相对于ServerRoot(/etc/httpd)指向的路径而言;
    /etc/httpd/modules/

wKiom1X9MvmhXl2HAAHUvHTV7ao473.jpg

7.定义'Main' server的文档页面路径
文档路径映射:
    DocumentRoot指向的路径为URL路径的起始位置;
    DocumentRoot "/var/www/html"
    /var/www/html/test/index.html --> http://HOST:PORT/test/index.html

8.站点访问控制
    可基于两种类型的路径指明对哪些资源进行访问控制
    文件系统路径:
        <Directory ""> </Direcotry>
        <File ""> </File>
        <FileMatch ""> </FileMatch>
    URL路径:
        <Location ""> </Location>

        可以限定对于那种方法进行控制,下面列举了http协议中的方法类型

    访问控制机制:
        基于来源地址;
        基于账号;


9.Directory中一些安全机制:
(1) Options
    所有可用特性:Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    None, All
    Indexes: 索引;允许显示索引,如果输入的url下找不到可用网页,是否显示所有目录,不安全,生产环境应            该关闭,但是下载站常用    

    FollowSymlinks:允许跟踪符号链接文件;

    SymLinksifOwnerMatch允许符号链接,但是检查进程属主是否有权限

    MultiViews根据客户端浏览器语言环境判断显示网页应该哪种语言,性能差,不建议打开  

    AllowOverride 访问控制是否允许当前配置覆盖指定网页目录.htaccess定义的访问控制机制

    每目录的访问控制:(会极大影响服务器性能)

wKiom1X9acSyn7PTAAAOKC9whWo763.jpg   

    定义不允许别人访问以.ht开头的文件

wKioL1X9a__wvD2PAAAhyfKkbXc853.jpg

(2) 基于来源地址的访问控制机制

<Directory>
            Options Indexes FollowSymLinks
            Order
            Allow from
            Deny from
</Directory>
<Location>中也可以定义

    Order:检查次序
    Order allow,deny

    Deny from

    Order deny,allow
    Allow from
    来源地址:
    IP ADDR
    NetAddr:
    172.16
    172.16.0.0
    172.16.0.0/16
    172.16.0.0/255.255.0.0

10.定义默认主页面
    DirecotryIndex index.html index.html.var

11.日志设定
    错误日志:
    ErrorLog logs/error_log
    LogLevel warn
    debug, info, notice, warn, error, crit, alert, emerg
    访问日志:
    CustomLog logs/access_log combined
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
        %h:客户端IP地址;
        %l: Remote logname (from identd, if supplied). -表示为空;
        %u: Remote user,  (from auth; may be bogus if return status (%s) is 401);
        %t:Time the request was received (standard english format),服务器收到请求的时间;
        %r:First line of request,请求报文的首行信息(method url version);
        %>s: 响应状态码;
        %b: 响应报文的大小,单位是字节,不包括响应报文首部;
        %{Referer}i:请求报文当中"referer"首部的值;当前资源的访问入口,即从哪个页面中的超链接跳转而来;
        %{User-Agent}i:请求报文当中"User-Agent"首部的值;即发出请求用到的应用程序;
        详情:http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats

wKioL1X9O5bx-EpMAAEaTb6tAjQ901.jpg

12.路径别名

    DocumentRoot "/www/htocs"
        http://www.magedu.com/download/bash-4.4.2-3.el6.x86_64.rpm
        --> /var/www/htdocs/download/bash-4.4.2-3.el6.x86_64.rpm
    Alias /URL/ "/PATH/TO/SOMEDIR/"   

    示例: 

    Alias /bbs/ "/forum/htdocs/bbs/"

    http://www.magedu.com/bbs/index.html  --> /forum/htdocs/bbs/

13.设定默认字符集
    AddDefaultCharset UTF-8
    GBK, GB2312, GB18030

14.基于用户的访问控制:

基于用户访问控制:
            认证方式:basic, digest
                AuthType Basic
                AuthName ""
                AuthUserFile
                AuthGroupFile
                Require user指定账号文件中某个用户可登陆,其他不允许登录
                Require group
                Require valid-user所有账号文件中的用户都可登录

配置实验:

在/var/www/html/下面创建admin目录作为安全域,下面存放index.html

http.conf配置:

wKiom1X9VGDwRARFAABk7c4U48w303.jpg

生成账户密码文件:

htpasswd [options] passwordfile username
    -c: 自动创建passwordfile,因此,仅应该在添加第一个用户时使用;
    -m: md5加密用户密码;
    -s: sha1加密用户密码;
    -D: 删除指定用户

注意添加第二个用户不用-c选项

wKiom1X9VGHgjbkDAADtV8KhfI4687.jpg

重启httpd服务通过并客户端访问就要求认证了:

wKioL1X9VpyRT9_XAADvVxRSs4I710.jpg

基于组进行认证:

生成组文件:

wKioL1X9WuTDyeGZAAAn9TSOO9Q677.jpg

httpd.conf配置:

wKioL1X9WbXA__R0AACByF3Z2iM127.jpg

重载httpd服务即可生效


你可能感兴趣的:(IO,httpd,mpm)