美文网首页
第十周《Centos7系统下实现httpd....》

第十周《Centos7系统下实现httpd....》

作者: N32_Diamond | 来源:发表于2018-10-19 12:13 被阅读0次

    一、Centos7系统下实现httpd-2.2的安装,并分别实现prefork、worker、event等几种工作方式

    #准备安装环境
    [root@wujunjie ~]# yum groupinstall "Development Tools" "ServerPlatform Development" -y
    #下载并解压安装包
    [root@wujunjie apache]# tar -xf httpd-2.2.32.tar.gz
    [root@wujunjie apache]# ls
    httpd-2.2.32  httpd-2.2.32.tar.gz
    #编译安装httpd_2.2.32
    [root@wujunjie httpd-2.2.32]# ./configure -prefix=/usr/local/httpd -with-mpm=prefork
    [root@wujunjie httpd-2.2.32]# make
    [root@wujunjie httpd-2.2.32]# make install
    #设定环境变量
    [root@wujunjie conf]# PATH="$PATH:/usr/local/httpd/bin"
    [root@wujunjie conf]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/httpd/bin
    [root@wujunjie conf]# vim /etc/profile.d/httpd.sh 
    export PATH="$PATH:/usr/local/httpd/bin"
    [root@wujunjie conf]# source /etc/profile.d/httpd.sh    #把httpd的命令添加到系统环境中
    #调整权限
    [root@wujunjie conf]# useradd -M -s /sbin/nologin httpd
    [root@wujunjie conf]# chown -R httpd:httpd /usr/local/httpd/
    #编辑unit文件使用systemctl 管理启动httpd
    [root@wujunjie conf]# vim /usr/lib/systemd/system/httpd.service
    [Unit]
    Description=The httpd service
    After=network.target
    [Service]
    Type=forking
    ExecStart=/usr/local/httpd/bin/apachectl start
    ExecStop=/usr/local/httpd/bin/apachectl stop
    ExecRestart=/usr/local/httpd/bin/apachectl restart
    PrivateTmp=true
    [Install]
    WantedBy=multi-user.target
    #启动服务
    [root@wujunjie conf]# systemctl daemon-reload 
    [root@wujunjie conf]# systemctl start httpd.service
    [root@wujunjie conf]# ps aux |grep httpd
    root      55254  0.0  0.1  49364  1964 ?        Ss   16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55255  0.0  0.2  51448  2040 ?        S    16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55256  0.0  0.1  51448  1344 ?        S    16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55257  0.0  0.1  51448  1344 ?        S    16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55258  0.0  0.1  51448  1344 ?        S    16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55259  0.0  0.1  51448  1344 ?        S    16:51   0:00 /usr/local/httpd/bin/httpd -k start
    daemon    55285  0.0  0.1  51448  1344 ?        S    16:52   0:00 /usr/local/httpd/bin/httpd -k start
    root      55308  0.0  0.0 112648   956 pts/2    R+   16:53   0:00 grep --color=auto httpd
    [root@wujunjie conf]# httpd -M|grep mpm
    Syntax OK
     mpm_prefork_module (static)
    
    • 1、prefork
      prefork是一个两级进程模型,非线程的模式,其实通过由父进程管理创建子进程,子进程响应的相应的请求的方式来运行的。以prefork模式运行的httpd,在启动之际就预派生fork了一些子进程,然后等待请求。每个子进程只有一个线程,在一个时间点内只能处理一个请求。
      优点:成熟、稳定、兼容所有新老模块。进程之间完全独立,无须担心线程安全的问题。
      缺点:一个进程相对会占用更多的系统资源,消耗更多的内存。不适合处理高并发请求,因其会把请求放进队列中,一直等到有可用进程才会处理相应的请求。
    • 2、worker
      worker是一个三级结构、多进程多线程的模式,其在启动时也预先fork了几个子进程,每个子进程能够生产若干个服务线程和若干个监听线程,每个服务线程处理一个请求,监听线程负责接入请求并将其传递给服务线程处理和应答。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此内存的占用会减少些,在高并发的场景下表现比prefork模式好。
      优点:占用内存少,高并发性能更优秀。
      缺点:当一个线程出现问题的时候会导致同一进程下的线程也会出现问题。在keep-alive长连接的方式下,某个线程会被一直占用,即使中间没有请求,也需要等待到超时才会被释放。
    • 3、event
      event模式是最新的运行模式,在httpd-2.4中已经是稳定可用的模式。其运行原理与worker类似,区别在于,event模式解决了在keep-alive模式下,线程被长期占用直到超时,从而导致资源浪费的问题。
      在event模块中,有一个专门的线程来管理这些keep-alive类型的线程,当接收到真实的请求时,会将请求传递给服务线程,执行完毕后,会将对应的服务线程释放,这样就能实现线程的异步非阻塞。
    在编译安装的时候对应做模式变更即可,默认为prefork模式
    ./configure -prefix=/usr/local/httpd -with-mpm=worker
    ./configure -prefix=/usr/local/httpd -with-mpm=event
    

    二、简述request报文请求方法和状态响应码

    http事务就是http协议的一次请求和响应的过程;http请求是由请求者发出的request报文定义的,响应是由response报文定义的,而请求报文和响应报文都有固定的格式;
    报文语法格式:

    request报文
      <method> <request-URL> <version>
      <headers>
    
      <entity-body>
    
    response报文
      <version> <status> <reason-phrase>
      <headers>
    
      <entity-body>
    
    展开说明:
    method: 请求方法(标明客户端希望服务器对资源执行的动作)

    如下为常用method的解释:

    • 请求方法 解释
      GET:从服务器获取一个资源
      HEAD:只从服务器获取文档的响应首部
      POST:向服务器发送要处理的数据
      PUT:将请求的主体部分存储在服务器上
      DELETE:请求删除服务器上指定的文档
      TRACE:追踪请求到达服务器中间经过的代理服务器
      OPTIONS:请求服务器返回对指定资源支持使用的请求方法
    version:HTTPD的版本号

    HTTP/<major>.<minor>,由主版本和次版本号组成

    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:首部(每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟上一个可选空格,接着是一个值)

    首部的分类:通用首部,请求首部,响应首部,实体首部,扩展首部等等,
    格式为:Name: Value,常见的首部格式如下:
    1.通用首部:
    Date: 报文的创建时间
    Connection:连接状态,如keep-alive, close
    Via:显示报文经过的中间节点
    Cache-Control:控制缓存
    Pragma: no-cache.相当于Cache-Control: no-cache

    2.请求首部:
    Accept:通过服务器自己可接受的媒体类型;
    Accept-Charset:浏览器指明自己接收的字符集
    Accept-Encoding:接受编码格式,如gzip
    Accept-Language:接受的语言
    Client-IP: 客户端ip地址
    Host: 请求的服务器名称和端口号
    Referer:包含当前正在请求的资源的上一级资源;
    User-Agent:客户端代理

    • 条件式请求首部:
      Expect:服务器指明该实体什么时候过期.
      If-Modified-Since:自从指定的时间之后,请求的资源是否发生过修改
      If-Unmodified-Since:自从指定的时间之后,请求的资源是否没有修改
      If-None-Match:本地缓存中存储的文档的ETag标签是否与服务器文档的
      If-Match:Etag没改变,才执行请求

    • 安全请求首部:
      Authorization:向服务器发送认证信息,如账号和密码
      Cookie: 客户端向服务器发送cookie

    • 代理请求首部:
      Proxy-Authorization: 向代理服务器认证
      3.响应首部:

    • 信息性首部:
      Age:响应持续时长,即资源的有效期;
      Server:服务器程序软件名称和版本;

    • 协商首部:某资源有多种表示方法时使用
      Accept-Ranges:服务器可接受的请求范围类型;
      Vary:服务器查看的其它首部列表;值会发生变化时就放在此首部;

    • 安全响应首部:
      Set-Cookie:向客户端设置cookie;用来标识客户端身份;
      Set-Cookie2: 向客户端设置cookie版本2的信息;
      WWW-Authenticate:来自服务器的对客户端的质询认证表单;当客户端请求资源时,资源要求认证;
      4.实体首部:提供实体内容的大量信息;

    • 跟内容格式相关:
      Allow: 列出对此实体可使用的请求方法;
      Location:告诉客户端真正的实体位于何处,在重定向时使用,响应码为301或302;
      Content-Encoding: 内容的编码格式;
      Content-Language: 内容使用的语言;
      Content-Length: 主体的长度;
      Content-Location: 实体真正所处位置;
      Content-Type:主体的对象类型;如多媒体的类型等;
      Content-Range:在整个资源中此实体表示的字节范围;

    • 跟缓存相关:
      ETag:资源实体的扩展标签;基于标签做请求时使用;
      Expires:实体内容的过期时间;
      Last-Modified:最后一次修改的时间;此时间只是推算出来的,可能不准确;

    三、详细描述httpd虚拟主机、站点访问控制、基于用户的访问控制、持久链接等应用配置实例

    虚拟主机

    有三种实现方案:
    基于ip:为每个虚拟主机准备至少一个ip地址;
    基于port:为每个虚拟主机使用至少一个独立的port;
    基于FQDN主机名:为每个虚拟主机使用至少一个FQDN;

    • 注意点:
      1.一般虚拟主机不要与中心主机混用;要使用虚拟主机,得先禁用"main"主机,禁用方法: 注释中心主机的DocumentRoot指令即可.
      2.配置VirtualHost,在httpd2.2中,NameVirtualHost这一项需启用,2.2以上版本不需要.
    • 基于IP地址
    [root@localhost ~]#ip addr add 192.168.32.150/24 dev ens33
    [root@localhost logs]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 00:0c:29:82:eb:87 brd ff:ff:ff:ff:ff:ff
        inet 192.168.32.132/24 brd 192.168.32.255 scope global dynamic ens33
           valid_lft 650sec preferred_lft 650sec
        inet 192.168.32.150/24 scope global secondary ens33
           valid_lft forever preferred_lft forever
        inet6 fe80::ccba:631a:dc48:5172/64 scope link 
           valid_lft forever preferred_lft forever
    #创建2个虚拟主机的目录
    [root@localhost ~]# mkdir /var/www/html/{ilinux,iunix}
    #编辑虚拟httpd站点主页面
    [root@localhost ~]# vim /var/www/html/ilinux/index.html
    <h1>ilinux</h1>
    [root@localhost ~]# vim /var/www/html/iunix/index.html
    <h1>iunix</h1>
    #编辑httpd虚拟主机配置文件
    [root@localhost ~]# vim /etc/httpd/conf.d/virtualhost.conf
    <VirtualHost 192.168.32.132:80>
            Servername www.ilinux.io
            DocumentRoot "/var/www/html/ilinux"
         <Directory "/var/www/html/ilinux">
            Options None
            AllowOverride None
            Require all granted
         </Directory>
            Customlog "logs/ilinux_access_log" combined
    </VirtualHost>
    
    <VirtualHost 192.168.32.150:80>
            Servername www.iunix.io
            DocumentRoot "/var/www/html/iunix"
         <Directory "/var/www/html/iunix">
            Options None
            AllowOverride None
            Require all granted
         </Directory>
            Customlog "logs/unix_access_log" combined
    </VirtualHost>
    #检查配置文件语法
        httpd -t
    Syntax OK
    #重启HTTPD服务
    systemctl restart httpd.service
    #测试对应结果
    [root@localhost ~]# curl http://192.168.32.132
    <h1>ilinux</h1>
    [root@localhost ~]# curl http://192.168.32.150
    <h1>iunix</h1>
    
    • 基于端口号
    #修改虚拟主机配置文件并监听8080端口
    [root@localhost ~]# vim /etc/httpd/conf.d/virtualhost.conf
    <VirtualHost 192.168.32.132:80>
            Servername www.ilinux.io
            DocumentRoot "/var/www/html/ilinux"
         <Directory "/var/www/html/ilinux">
            Options None
            AllowOverride None
            Require all granted
         </Directory>
            Customlog "logs/ilinux_access_log" combined
    </VirtualHost>
    
    LISTEN 8080
    <VirtualHost 192.168.32.150:8080>
            Servername www.iunix.io
            DocumentRoot "/var/www/html/iunix"
         <Directory "/var/www/html/iunix">
            Options None
            AllowOverride None
            Require all granted
         </Directory>
            Customlog "logs/unix_access_log" combined
    </VirtualHost>
    #检查配置文件语法
        httpd -t
    Syntax OK
    #重启HTTPD服务
    systemctl restart httpd.service
    #测试对应结果
    [root@localhost ~]# curl http://192.168.32.132:80
    <h1>ilinux</h1>
    [root@localhost ~]# curl http://192.168.32.150:8080
    <h1>iunix</h1>
    
    • 基于主机域名
    #更改本地hosts文件对应关系或自建DNS做对应修改
    
    [root@localhost ~]# vim /etc/hosts
    
    192.168.32.132 www.ilinux.io
    
    192.168.32.150 [www.iunix.io](http://www.iunix.io)
    
    #基于上诉配置直接检验
    
    [root@localhost ~]# curl www.iunix.io:8080
    
    <h1>iunix</h1>
    
    [root@localhost ~]# curl www.ilinux.io
    
    <h1>ilinux</h1>
    
    站点路径访问控制

    可基于来源地址或者基于账号两种访问控制机制;定义的方式有两种:
    文件系统路径:<Directory ""> ... </Directory>
    URL路径:<Location ""> ... </Location>

    • <Directory>中“基于源地址”实现访问控制:
      (1) Options后跟1个或多个以空白字符分隔的“选项”列表;
      Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户;作为下载站点时才使用;否则,不使用此选项;
      FollowSymLinks:允许跟踪符号链接文件所指向的源文件;
      None:都禁止;
      All:都允许;
      Includes:允许启用服务器包含;
      SymLinksifOwnerMatch:比FollowSymLinks在限制上更为严格的机制;表示只有原文件的属主和链接文件的属主相同时,才允许跟踪;
      ExecCGI:允许执行cgi脚本;
      MultiViews:允许执行内容协商;非常消耗资源且不太安全;
      (2) AllowOverride:与访问控制相关的哪些指令可以放在.htaccess文件(每个目录即网站目录下都可以有一个,指令放在此文件中表示当前目录下的配置文件都无效,所在目录下的这个隐藏文件生效)中;
      All: 所有指令都可放在这个隐藏文件中;
      None:这个隐藏文件中什么指令都不放;或给个指定列表,文件信息、根认证相关的信息,限制可放进这个隐藏文件中;会使网站资源解析时性能影响非常大;
      (3) http-2.2中基于IP地址的访问控制是利用Allow和Deny来实现的;order:定义生效次序;写在后面的表示默认法则;如:
          <Directory  "/PATH/TO/FILE">
              Options Indexes FollowSymLinks
              AllowOverride None
              Order allow, deny
              Allow  from  IP | NetAddr
              Deny  from  IP | NetAddr
          </Directory>
    

    httpd-2.4中基于Ip地址访问的控制是利用Require实现,如:

          <Directory  "/PATH/TO/FILE">
             AllowOverride none
             Options none
             <RequireAll>
                Require ip IP | NetAddr #允许访问的IP或网段
                Require not ip IP | NetAddr #拒绝访问的Ip或网段
             </RequireAll>
          </Directory>
    
    实例:
    #修改上诉虚拟主机配置文件
    [root@localhost ~]# vim /etc/httpd/conf.d/virtualhost.conf
    <VirtualHost 192.168.32.132:80>
     Servername www.ilinux.io
     DocumentRoot "/var/www/html/ilinux"
     <Directory "/var/www/html/ilinux">
     Options None
     AllowOverride None
     Require all granted
     </Directory>
     Customlog "logs/ilinux_access_log" combined
    </VirtualHost>
    LISTEN 8080
    <VirtualHost 192.168.32.150:8080>
     Servername www.iunix.io
     DocumentRoot "/var/www/html/iunix"
     <Directory "/var/www/html/iunix">
     Options None
     AllowOverride None
     <RequireAll>
     require all granted
     require not ip 192.168.32.129
     </RequireAll>
     </Directory>
     Customlog "logs/unix_access_log" combined
    </VirtualHost>
    #重启服务
    [root@localhost ~]# systemctl restart httpd.service
    ##在主机192.168.32.129上检测
    [root@wujunjie6 ~]# curl http://192.168.32.132   #可以访问
    <h1>ilinux</h1>
    [root@wujunjie6 ~]# curl [http://192.168.32.150:8080](http://192.168.32.150:8080)    #报错
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
     <title>Apache HTTP Server Test Page powered by CentOS</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    …………………………………….
    
    基于用户的访问控制:

    对于网站中的一些资源,需要只对特定的用户开放,可以通过用户的访问控制来实现.有质询和认证两种方式.
    质询:服务器用401响应码拒绝客户端请求,并说明要求客户端提供账号和密码
    认证:客户端用户填入账号和密码后再次发送请求报文,认证通过时,则服务器发送响应的资源.有basic基本认证和digest摘要认证两种.这里以basic认证做实验.
    basic认证的配置格式如下:

    <Directory "/somepath/to/file">  # 需要访问控制的文件路径
        Options None
        AllowOverride None
        AuthType Basic   # 认证方式
        AuthName "String“   #认证提示信息
        AuthUserFile  "/PATH/TO/HTTPD_USER_PASSWD_FILE"   #认证用户的文件路径
        Require  user  username1  username2 ...   #允许访问的用户
    </Directory>
    #  Require  valid-user  表示允许所有AuthUserFile 文件中所以的账号
    #  AuthGroupFile "/PATH/TO/HTTPD_GROUP_FILE"  基于用户组做访问控制
    #  Require  group  grpname1  grpname2 ... 同上
    
    登陆使用的账号为虚拟账号而非系统的账号,而且httpd是明文传输的,所以使用htpasswd命令来创建账号文件格式如下:
    htpasswd  [options]   /PATH/TO/HTTPD_PASSWD_FILE  username 
            -c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用
            -m:md5格式加密
            -s: sha格式加密
            -D:删除指定用户
    
    实例
    #创建密码账户和允许访问的用户
    [root@localhost ~]# htpasswd -c /tmp/text.users tom
    [root@localhost ~]# htpasswd -m /tmp/text.users wuwuwu
    [root@localhost tmp]# htpasswd -m /tmp/text.users jjj
    #把存放密码的文件移动到httpd目录下,且保存为隐藏文件
    [root@localhost ~]# mv /tmp/text.users /etc/httpd/conf.d/.htpasswd
    #创建站点主页面
    [root@localhost ~]# mkdir /var/www/html/text
    [root@localhost ~]# echo "1212121" > /var/www/html/text/index.html
    #创建模块化文件并且做对应配置
    [root@www ~]# vim /etc/httpd/conf.d/text.conf
    <Directory "var/www/html/text">
            Options None
            AllowOverride None
            AuthType Basic
            AuthName "please enter the user"
            AuthUserFile "/etc/httpd/conf.d/.htpasswd"
            Require user tom wuwuwu jjj
    </Directory>
    #测试语法错误并重启
    [root@localhost ~]# httpd -t
    Syntax OK
    [root@localhost ~]# systemctl restart httpd.service
    
    验证
    持久连接相关:

    Persistent Connection:tcp连接建立后,每个资源获取完成后不全断开连接,而是继续等待其他资源请求的进行;但是总归要断开,如何断开?可以通过对连接数量和时间限制来控制;比如:限制100个连接,超过100个后会断开最先的连接;限制连接60秒后没有进行任何操作则断开;

    • 副作用:对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常响应;
    • 折衷的改进办法:使用较短的持久连接时长,以及较少的请求数量;
    • 持久连接的相关参数:
    KeepAlive Off|On                           #关闭或打开持久连接
    MaxKeepAliveRequserts 100         #最大持久连接请求数量
    KeepAliveTimeout 15                    #连接时长,单位秒;httpd-2.4支持毫秒
    
    • 测试:
    telnet WEB_SERVER_IP PORT
    GET  /URL  HTTP/1.1
    Host:WEB_SERVER_IP
    
    实例:
    [root@wujunjie6 ~]# vim /etc/httpd/conf.d/keepalive.conf
    keepalive  On
    KeepAliveTimeout  15
    MaxKeepAliveRequests  100
    [root@wujunjie6 ~]# netstat -tnl|grep 23     #监听23端口
    tcp        0      0 :::23                       :::*                        LISTEN    
    [root@wujunjie6 ~]# telnet 192.168.32.129 80
    Trying 192.168.32.129...
    Connected to 192.168.32.129.
    Escape character is '^]'.
    GET /index.html HTTP/1.1
    Host:192.168.32.129
    
    HTTP/1.1 200 OK
    Date: Thu, 18 Oct 2018 08:32:38 GMT
    Server: Apache/2.2.15 (CentOS)
    Last-Modified: Thu, 18 Oct 2018 07:21:11 GMT
    ETag: "2009e1-8-5787ba1a3e6d8"
    Accept-Ranges: bytes
    Content-Length: 8
    Content-Type: text/html; charset=UTF-8
    
    2112312
    
    Connection closed by foreign host.   #这里不会立刻断开,会等到最大连接数或连接时长到达才会断开
    

    相关文章

      网友评论

          本文标题:第十周《Centos7系统下实现httpd....》

          本文链接:https://www.haomeiwen.com/subject/aplyzftx.html