WEB服务--apache
HTTP
HTTP协议(HyperText Transfer Protocol,超文本传输协议)
HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于分布式、协作式和超媒体信息系统 的应用层协议。HTTP是万维网的数据通信的基础设计HTTP最初的目的是为了提供一种远距离共享知识的方式,借助多文档进行关联实现超文本
HTTP协议版本
HTTP1.0和HTTP1.1的区别
主要区别主要体现在:
1、缓存处理。在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
2、带宽优化及网络连接的使用。HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
3、错误通知的管理。在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
4、Host头处理。在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
5、长连接。HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
HTTP2.0和HTTP1.X相比的新特性
1、新的二进制格式(Binary Format)。HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
2、多路复用(MultiPlexing)。即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
3、header压缩。如HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
4、服务端推送(server push)。同SPDY一样,HTTP2.0也具有server push功能。
HTTPS与HTTP的一些区别
1、HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
2、HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
3、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
HTTP通信过程
- 用户访问一个域名,经过DNS服务解析得到服务器ip
- 客户端与服务器端通过TCP三次握手建立连接
- 客户端向服务端发送请求报文
- 服务端根据请求报文返回响应报文,并根据请求报文或者响应报文头部信息确定是否断开连接,或者保持长连接
请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求体4个部分组成。
请求行由三部分组成:请求方法,请求URL(不包括域名),HTTP协议版本,最常用的是GET和POST
请求头部由关键字/值对组成,每行一对
User-Agent : 产生请求的浏览器类型
Accept : 客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型
Content-Type:发送端发送的实体数据的数据类型。比如,Content-Type:text/html(application/json)表示发送的是html类型。
Host : 请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
请求头之后是一个空行,通知服务器以下不再有请求头
请求体,发送请求时携带数据
GET没有请求数据,POST有。
与请求数据相关的最常使用的请求头是 Content-Type 和 Content-Length 。
响应报文
一个HTTP请求报文由状态行(status-line)、响应头部(header)、空行和响应体体4个部分组成。
状态行由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述
常见响应状态码
1xx:指示信息,表示请求已接收,继续处理
2xx:成功,表示请求已被成功接受,处理。
200 OK:客户端请求成功
204 No Content:无内容。服务器成功处理,但未返回内容。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。
206 Partial Content:服务器已经完成了部分GET请求(客户端进行了范围请求)。响应报文中包含Content-Range指定范围的实体内容
3xx:重定向
301 Moved Permanently:永久重定向,表示请求的资源已经永久的搬到了其他位置。
302 Found:临时重定向,表示请求的资源临时搬到了其他位置
303 See Other:临时重定向,应使用GET定向获取请求资源。303功能与302一样,区别只是303明确客户端应该使用GET访问
307 Temporary Redirect:临时重定向,和302有着相同含义。POST不会变成GET
4xx:客户端错误
400 Bad Request:客户端请求有语法错误,服务器无法理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务
404 Not Found:请求资源不存在。比如,输入了错误的url
415 Unsupported media type:不支持的媒体类型
5xx:服务器端错误,服务器未能实现合法的请求。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,
apache
apache特性:
高度模块化:core + modules DSO:Dynamic Shared Object
动态加载/卸载 MPM:multi-processing module 多路处理模块
MPM multi-processing module 工作模式
prefork:多进程I/O模型,每个进程响应一个请求,CentOS 7 httpd默认模型
一个主进程:生成和回收n个子进程,创建套接字,不响应请求
多个子进程:工作 work进程,每个子进程处理一个请求;系统初始时,预先生成多个空闲进程,等待请求
Prefork MPM预派生模式,有一个主控制进程,然后生成多个子进程,每个子进程有一个独立的线程响应用户请求,相对比较占用内存,但是比较稳定,可以设置最大和最小进程数,是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:慢,占用资源,不适用于高并发场景
worker:复用的多进程I/O模型,多进程多线程,IIS使用此模型
一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n
worker MPM是一种多进程和多线程混合的模型,有一个控制进程,启动多个子进程,每个子进程里面包含固定的线程,使用线程程来处理请求,当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,由于其使用了线程处理请求,因此可以承受更高的并发。
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keep-alive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)
event:事件驱动模型(worker模型的变种),CentOS8 默认模型
一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n,有专门的监控线程来管理这些keep-alive类型的线程,当有真实请求时,将请求传递给服务线程,执行完毕后,又允许释放。这样增强了高并发场景下的请求处理能力
event MPM是Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型. 属于事件驱动模型(epoll),每个进程响应多个请求,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
event只在有数据发送的时候才开始建立连接,连接请求才会触发工作线程,即使用了TCP的一个选项,叫做延迟接受连接TCP_DEFER_ACCEPT,加了这个选项后,若客户端只进行TCP连接,不发送请求,则不会触发Accept操作,也就不会触发工作线程去干活,进行了简单的防攻击(TCP连接)
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控
httpd安装
包安装
使用yum工具安装
yum -y install httpd
编译安装
ansible-playbook实现安装httpd
---
- hosts: all
remote_user: root
tasks:
- name: install package
yum: name=gcc,make,pcre-devel,openssl-devel,expat-devel,bzip2 state=installed
- name: unarchive apr
unarchive: src=/data/apr-1.7.0.tar.bz2 dest=/data/ copy=yes
- name: unarchive apr-util
unarchive: src=/data/apr-util-1.6.1.tar.bz2 dest=/data/ copy=yes
- name: unarchive httpd2.4
unarchive: src=/data/httpd-2.4.46.tar.bz2 dest=/data/ copy=yes
- name: configuer apr
shell: chdir=/data/apr-1.7.0 ./configure --prefix=/app/apr && make && make install
- name: configuer apr-util
shell: chdir=/data/apr-util-1.6.1 ./configure --prefix=/app/apr-util --with-apr=/app/apr && make && make install
- name: configuer httpd
shell: chdir=/data/httpd-2.4.46 ./configure --prefix=/app/http2.4 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/app/apr --with-apr-util=/app/apr-util --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork && make && make install
- name: create group
group: name=apache system=yes
- name: create user
user: name=apache group=apache system=yes shell=/sbin/nologin create_home=no
- name: change user
shell: grep -E "^User apache" /app/http2.4/conf/httpd.conf || sed -r -e "s/^User.*/User apache/" -e "s/^Group.*/Group apache/" /app/http2.4/conf/httpd.conf
- name: source PATH
shell: echo "PATH=/app/http2.4/bin:$PATH" > /etc/profile.d/httpd.sh && source /etc/profile.d/httpd.sh
- name: man
shell: echo "MANDATORY_MANPATH /app/http2.4/man " >> /etc/man_db.conf
- name: unit file
template: src=httpd.service.j2 dest=/usr/lib/systemd/system/httpd.service
- name: system-daemon
shell: systemctl daemon-reload
- name: start httpd
service: name=httpd state=started
相关文件
配置文件:
/etc/httpd/conf/httpd.conf 主配置文件
/etc/httpd/conf.d/*.conf 子配置文件
/etc/httpd/conf.d/conf.modules.d/ 模块加载的配置文件
检查配置语法:httpd -t 或 apache2 -t
配置文件组成:
Global Environment
Main server configuration
virtual host
格式:
directive value
directive 不区分字符大小写
value 为路径时,是否区分大小写,取决于文件系统
模块文件路径:
/etc/httpd/modules
/usr/lib64/httpd/modules
vim /usr/lib/systemd/system/httpd24.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
#EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/apps/httpd24/bin/apachectl start
#ExecStart=/apps/httpd24/bin/httpd $OPTIONS -k start
ExecReload=/apps/httpd24/bin/apachectl graceful
#ExecReload=/apps/httpd24/bin/httpd $OPTIONS -k graceful
ExecStop=/apps/httpd24/bin/apachectl stop
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
web服务
apache常用配置
-
监听端口
Listen [IP:]PORT 说明: (1) 省略IP表示为本机所有IP (2) Listen指令至少一个,可重复出现多次 Listen 10.0.0.28:8080 Lsten 80 [root@localhost data]# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 10.0.0.28:8080 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* ESTAB 0 52 10.0.0.28:22 10.0.0.1:64094 LISTEN 0 128 *:80 *:* LISTEN 0 128 [::]:22 [::]:* root@ubuntu:~# curl 10.0.0.28 10.0.0.28 root@ubuntu:~# curl 10.0.0.28:8080 10.0.0.28
-
文件包含
Include file-path|directory-path|wildcard IncludeOptional file-path|directory-path|wildcard 说明: Include和IncludeOptional功能相同,都可以包括其它配置文件 但是当无匹配文件时,include会报错,IncludeOptional会忽略错误
-
隐藏信息
ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full 建议使用:ServerTokens Prod 禁止错误网页版本泄露 ServerSignature On | Off | EMail 默认值Off,如果ServerTokens 使用默认值,并且ServerSignature选项为on,当客户请求的网页并不存 在时,服务器将产生错误文档,错误文档的最后一行将包含服务器名字、Apache版本等信息,如果不对 外显示这些信息,就可将这个参数设置为Off, 如果设置为Email,将显示ServerAdmin 的Email提示 [root@localhost data]# vim /etc/httpd/conf/httpd.conf ServerTokens Prod root@ubuntu:~# curl 10.0.0.28/aaa -I HTTP/1.1 404 Not Found Date: Sat, 02 Jul 2022 16:22:17 GMT Server: Apache Content-Type: text/html; charset=iso-8859-1
-
持久连接
KeepAlive On|Off KeepAliveTimeout 15 #连接持续15s,可以以ms为单位,默认值为5s MaxKeepAliveRequests 500 #持久连接最大接收的请求数,默认值100 断开条件: 时间限制:以秒为单位, 默认5s,httpd-2.4 支持毫秒级 请求数量: 请求数达到指定值,也会断开 例: keepalive on keepalivetimeout 10
-
DSO (Dynamic Shared Object)
Dynamic Shared Object,加载动态模块配置,不需重启即生效 动态模块所在路径: /usr/lib64/httpd/modules/ 主配置 /etc/httpd/conf/httpd.conf 文件中指定加载模块配置文件 ServerRoot "/etc/httpd" Include conf.modules.d/*.conf 配置指定实现模块加载格式: LoadModule <mod_name> <mod_path>
-
MPM
httpd 支持三种MPM工作模式:prefork, worker, event #启用要启用的MPM相关的LoadModule指令即可,其它未启用的两项需要在行首加#注释 [root@localhost data]# cat /etc/httpd/conf.modules.d/00-mpm.conf # Select the MPM module which should be used by uncommenting exactly # one of the following LoadModule lines. See the httpd.conf(5) man # page for more information on changing the MPM. # prefork MPM: Implements a non-threaded, pre-forking web server # See: http://httpd.apache.org/docs/2.4/mod/prefork.html # # NOTE: If enabling prefork, the httpd_graceful_shutdown SELinux # boolean should be enabled, to allow graceful stop/shutdown. # #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # worker MPM: Multi-Processing Module implementing a hybrid # multi-threaded multi-process web server # See: http://httpd.apache.org/docs/2.4/mod/worker.html # #LoadModule mpm_worker_module modules/mod_mpm_worker.so # event MPM: A variant of the worker MPM with the goal of consuming # threads only for connections with active processing # See: http://httpd.apache.org/docs/2.4/mod/event.html # LoadModule mpm_event_module modules/mod_mpm_event.so prefork 模式相关的配置 StartServers 100 MinSpareServers 50 MaxSpareServers 80 ServerLimit 2560 #最多进程数,最大值 20000 MaxRequestWorkers 2560 #最大的并发连接数,默认256 MaxConnectionsPerChild 4000 #子进程最多能处理的请求数量。在处理MaxRequestsPerChild 个请求之后,子进程将会被父进程终止,这时候子进程占用的内存就会释放(为0时永远不释放) MaxRequestsPerChild 4000 #从 httpd.2.3.9开始被MaxConnectionsPerChild代替 worker和event 模式相关的配置 ServerLimit 16 #最多worker进程数 Upper limit on configurable number of processes StartServers 10 #Number of child server processes created at startup MaxRequestWorkers 150 #Maximum number of connections that will be processed simultaneously MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 #Number of threads created by each child process
-
主目录
[root@localhost html]# cat /etc/httpd/conf.d/data.conf DocumentRoot "/data/html" <directory /data/html> Require all granted </directory> [root@localhost html]# cat /data/html/index.html 10.0.0.28 /data/html [root@localhost html]# cat /etc/httpd/conf.d/data.conf DocumentRoot "/data/html" <directory /data/html> DirectoryIndex index.php index.html #主页面 Require all granted </directory>
-
访问控制
基于客户端 IP 地址实现访问控制 白名单 [root@localhost www]# cat /etc/httpd/conf.d/data.conf DocumentRoot "/data/html" <directory /data/html> DirectoryIndex index.php index.html <requireany> #Require all granted Require all denied require ip 10.0.0.100 </requireany> </directory> 黑名单 [root@localhost www]# cat /etc/httpd/conf.d/data.conf DocumentRoot "/data/html" <directory /data/html> DirectoryIndex index.php index.html <requireany> Require all granted require not ip 10.0.0.100 </requireany> </directory> 基于用户账号进行认证 定义安全域,用户认证后才能访问的路径 DocumentRoot "/data/html" <directory /data/html/admin> options none allowoverride none authtype basic authname "string" authuserfile "/data/admin" require valid-user </directory> 生成验证用户文件 htpasswd -cb /data/admin zhansan 123456 setfacl -m u:apache:r /data/admin #保证apache有读权限 htpasswd选项: -c 自动创建文件,仅应该在文件不存在时使用 -b 非交互方式创建用户,命令后面可以接密码 -p 明文密码 -d CRYPT格式加密,默认 -m md5格式加密 -s sha格式加密 -D 删除指定用户 多人时可用AuthGroupFile "/etc/httpd/conf.d/.httpgroup",组文件中每行一个成员 注意:与ip控制不可同时使用
-
日志
错误日志 /var/log/httpd/error_log LogLevel warn #LogLevel 可选值: debug, info, notice, warn,error, crit, alert, emerg 定义级别 ErrorLog logs/error_log #位置 访问日志 /var/log/httpd/access_log 定义日志格式: LogFormat format nickname 使用日志格式: CustomLog file nickname %h #客户端IP地址 %l #远程用户,启用mod_ident才有效,通常为减号"-” %u #验证(basic,digest)远程用户,非登录访问时,为一个减号"-” %t #服务器收到请求时的时间 %r #First line of request,即表示请求报文的首行;记录了此次请求的"方法”,"URL”以及协议版本 %>s #响应状态码 %b #响应报文的大小,单位是字节;不包括响应报文http首部 %{Referer}i #请求报文中首部"referer”的值;即从哪个页面中的超链接跳转至当前页面的 %{User-Agent}i #请求报文中首部"User-Agent”的值;即发出请求的应用程序 %{VARNAME}i #The contents of VARNAME: header line(s) in the request sent to the server 范例: LogFormat "%h %l %u %t \"%r\" " test CustomLog "logs/access_log" test 10.0.0.17 - - [03/Jul/2022:01:38:46 +0800] "GET / HTTP/1.1" 10.0.0.100 - - [03/Jul/2022:01:38:50 +0800] "GET / HTTP/1.1"
-
状态页
[root@localhost data]# vim /etc/httpd/conf.d/status.conf LoadModule status_module modules/mod_status.so <location "/status"> <requireany> require all denied require ip 10.0.0.1 </requireany> sethandler server-status </location> 需加载mod_status.so模块,添加访问控制
-
压缩
使用mod_deflate模块压缩页面优化传输速度 LoadModule deflate_module modules/mod_deflate.so SetOutputFilter #可选项 SetOutputFilter DEFLATE # 指定对哪种MIME类型进行压缩,必须指定项 AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE text/css #压缩级别 (Highest 9 - Lowest 1) DeflateCompressionLevel 9 #排除特定旧版本的浏览器,不支持压缩 #Netscape 4.x 只压缩text/html BrowserMatch ^Mozilla/4 gzip-only-text/html #Netscape 4.06-08 三个版本 不压缩 BrowserMatch ^Mozilla/4\.0[678] no-gzip #Internet Explorer标识本身为"Mozilla / 4”,但实际上是能够处理请求的压缩。如果用户代理首部匹 配字符串"MSIE”("B”为单词边界”),就关闭之前定义的限制 BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
虚拟主机
httpd 支持在一台物理主机上实现多个网站,即多虚拟主机
多虚拟主机有三种实现方案:
-
基于ip:为每个虚拟主机准备至少一个ip地址
[root@localhost html]# vim /etc/httpd/conf.d/v_host.conf <virtualhost 10.0.0.8:80> documentroot /data/html/web1 customlog logs/web1_access.log combined <directory /data/html/web1> require all granted </directory> </virtualhost> <virtualhost 10.0.0.18:80> documentroot /data/html/web2 customlog logs/web2_access.log combined <directory /data/html/web2> require all granted </directory> </virtualhost> <virtualhost 10.0.0.28:80> documentroot /data/html/web3 customlog logs/web3_access.log combined <directory /data/html/web3> require all granted </directory> </virtualhost> root@ubuntu:~# curl 10.0.0.8 web1 root@ubuntu:~# curl 10.0.0.18 web2 root@ubuntu:~# curl 10.0.0.28 web3
-
基于port:为每个虚拟主机使用至少一个独立的port
[root@localhost html]# vim /etc/httpd/conf.d/v_host.conf listen 8001 listen 8002 listen 8003 <virtualhost *:8001> documentroot /data/html/web1 customlog logs/web1_access.log combined <directory /data/html/web1> require all granted </directory> </virtualhost> <virtualhost *:8002> documentroot /data/html/web2 customlog logs/web2_access.log combined <directory /data/html/web2> require all granted </directory> </virtualhost> <virtualhost *:8003> documentroot /data/html/web3 customlog logs/web3_access.log combined <directory /data/html/web3> require all granted </directory> </virtualhost> root@ubuntu:~# curl 10.0.0.28:8001 web1 root@ubuntu:~# curl 10.0.0.28:8002 web2 root@ubuntu:~# curl 10.0.0.28:8003 web3
-
基于FQDN:为每个虚拟主机使用至少一个FQDN
[root@localhost html]# vim /etc/httpd/conf.d/v_host.conf <virtualhost *:80> servername www.web1.com documentroot /data/html/web1 customlog logs/web1_access.log combined <directory /data/html/web1> require all granted </directory> </virtualhost> <virtualhost *:80> servername www.web2.com documentroot /data/html/web2 customlog logs/web2_access.log combined <directory /data/html/web2> require all granted </directory> </virtualhost> <virtualhost *:80> servername www.web3.com documentroot /data/html/web3 customlog logs/web3_access.log combined <directory /data/html/web3> require all granted </directory> </virtualhost> root@ubuntu:~# curl www.web1.com web1 root@ubuntu:~# curl www.web2.com web2 root@ubuntu:~# curl www.web3.com web3
https
HTTPS 会话的简化过程
-
客户端发送可供选择的加密方式,并向服务器请求证书
-
服务器端发送证书以及选定的加密方式给客户端
-
客户端取得证书并进行证书验证,如果信任给其发证书的CA
(a) 验证证书来源的合法性;用CA的公钥解密证书上数字签名
(b) 验证证书的内容的合法性:完整性验证
(c) 检查证书的有效期限
(d) 检查证书是否被吊销
(e) 证书中拥有者的名字,与访问的目标主机要一致 -
客户端生成临时会话密钥(对称密钥),并使用服务器端的公钥加密此数据发送给服务器,完成密钥交换
-
服务用此密钥加密用户请求的资源,响应给客户端
注意:SSL是基于IP地址实现,单IP的httpd主机,仅可以使用一个https虚拟主机https实现
yum -y install mod_ssl cd /etc/pki/tls/certs make https.crt mv https.* /data/ vim /etc/httpd/conf.d/ssl.conf SSLCertificateFile /data/https.crt SSLCertificateKeyFile /data/https.key systemctl restart httpd [root@centos7 data]# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* ESTAB 0 52 10.0.0.17:22 10.0.0.1:61836 LISTEN 0 128 [::]:22 [::]:* LISTEN 0 100 [::1]:25 [::]:* LISTEN 0 128 [::]:443 [::]:* LISTEN 0 128 [::]:80 [::]:*
重定向
URL重定向,即将httpd 请求的URL转发至另一个的URL
Redirect [status] URL-path URL
status状态: permanent: 返回永久重定向状态码 301,此重定向信息进行缓存
temp:返回临时重定向状态码302. 此为默认值
http实现重定向https
#注意: RewriteEngine指令需要开启mod_rewrite.so模块
[root@centos8 ~]#vim /etc/httpd/conf.d/test.conf
RewriteEngine on
RewriteRule ^(/.*)$ https://%{HTTP_HOST}$1 [redirect=302]
cookie和session
cookie和session的相同和不同:
cookie通常是在服务器生成,但也可以在客户端生成,session是在服务器端生成的
session 将数据信息保存在服务器端,可以是内存,文件,数据库等多种形式,cookie 将数据保存在客户端的内存或文件中单个cookie保存的数据不能超过4K,每个站点cookie个数有限制,比如IE8为50个、Firefox为50个、Opera为30个;session存储在服务器,没有容量限制
cookie存放在用户本地,可以被轻松访问和修改,安全性不高;session存储于服务器,比较安全
cookie有会话cookie和持久cookie,生命周期为浏览器会话期的会话cookie保存在缓存,关闭浏览器窗口就消失,持久cookie被保存在硬盘,知道超过设定的过期时间;随着服务端session存储压力增大,会根据需要定期清理session数据
session中有众多数据,只将sessionID这一项可以通过cookie发送至客户端进行保留,客户端下次访问时,在请求报文中的cookie会自动携带sessionID,从而和服务器上的的session进行关联
cookie缺点:
1、使用cookie来传递信息,随着cookie个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如cookie占用200字节,如果一天的PV有几个亿,那么它要占用多少带宽?
2、cookie并不安全,因为cookie是存放在客户端的,所以这些cookie可以被访问到,设置可以通过插件添加、修改cookie。所以从这个角度来说,我们要使用sesssion,session是将数据保存在服务端的,只是通过cookie传递一个sessionId而已,所以session更适合存储用户隐私和重要的数据
session 缺点:
1、不容易在多台服务器之间共享,可以使用session绑定,session复制,session共享解决
2、session存放在服务器中,所以session如果太多会非常消耗服务器的性能cookie和session各有优缺点,在大型互联网系统中,单独使用cookie和session都是不可行的
LAMP
cgi和fastcgi
CGI(Common Gateway Interface)公共网关接口,CGI是一种协议。准确地说,CGI是应用程序(如PHP)与Web服务器交互的一个标准接口、协议。
cgi特点:
- CGI程序运行在独立的进程,而且每个Web请求都创建一个进程,在结束时销毁。这种“每个请求一个新进程”使得CGI效率较差,难以扩展;
- 在高负载情况下,用于进程创建和销毁的操作系统开销变得很大;
- 由于进程地址空间无法共享,CGI进程模型限制了重用方法,如重用数据库链接等;
FastCGI快速通用网关接口(Fast Common GateWay Interface)与CGI一样,也是一种让应用程序与Web服务器通信的协议。FastCGI是CGI的增强版本。
fastcgi特点:
- Web服务器启动时载入FastCGI进程管理器(如PHP-FPM);
- FastCGI进程管理器自身初始化,启动多个CGI解释器进程并等待来自Web服务器的连接;
- 当客户端请求到达Web服务器时,FastCGI进程管理器选择并连接到一个CGI解释器。Web服务器把环境变量和这个页面请求通过一个socket或TCP connection传递给FastCGI子进程;
- FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。
PHP
php 的配置文件:/etc/php.ini, /etc/php.d/*.ini
配置文件在php解释器启动时被读取
对配置文件的修改生效方法
Modules:重启httpd服务
FastCGI:重启php-fpm服务
/etc/php.ini配置文件格式:
[foo]:Section Header
directive = value
注释符:
以#开头,纯粹的注释信息
以 ; 开头,用于注释可启用的directive
提示:较新的版本中,已经完全使用 “ ; ” 进行注释
php常见设置:
expose_php= On #响应报文显示首部字段x-powered-by: PHP/x.y.z,暴露php版本,建议为off
max_execution_time= 30 #最长执行时间30s
memory_limit=128M #生产不够,可调大
display_errors=off #调试使用,不要打开,否则可能暴露重要信息
display_startup_errors=off #建议关闭
post_max_size=8M #最大上传数据大小,生产可能调大,比下面项大
upload_max_filesize =2M #最大上传文件,生产可能要调大
max_file_uploads = 20 #同时上传最多文件数
date.timezone =Asia/Shanghai #指定时区
short_open_tag=on #开启短标签,如: <? phpinfo();?>
实现 opcache 加速
[root@centos8 ~]#dnf install php-opcache
[root@centos8 ~]#cat /etc/php.ini
[opcache]
zend_extension=opcache.so
opcache.enable=1
centos8
[root@centos8 ~]#dnf -y install httpd php php-mysqlnd mariadb-server php-opcache
php-json
[root@centos8 ~]#grep opcache /etc/php.d/10-opcache.ini
zend_extension=opcache
opcache.enable=1
...省略...
#加速前,默认启用,先禁用加速
php-fpm
php-fpm 主要配置文件:
/etc/php-fpm.conf
/etc/php-fpm.d/*.con
PHP-FPM常见配置
daemonize = no #是否将程序运行在后台
listen = 127.0.0.1:9000 #FPM 监听地址
listen = /var/run/php.sock #UDF模式使用,指定生成的unix socket文件的路径
#注意:Unix Domain Socket (UDS) support added in httpd-2.4.7
#http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
listen.owner = apache #UDF模式使用,指定生成的unix socket文件的所有者
listen.group = apache #UDF模式使用,指定生成的unix socket文件的所属组
listen.mode= 0666 #UDF模式使用,,指定生成的unix socket文件的权限
listen.acl_users = apache,nginx #指定用户访问unix socket文件,listen.owner 和listen.group将无效
listen.backlog = -1 #等待队列的长度 -1表示无限制
listen.allowed_clients = 127.0.0.1 #仅允许哪些WEB主机访问
pm = dynamic|static #static 固定数量的子进程,dynamic子进程数据以动态模式管理
pm.max_childen=500 #静态方式下开启的php-fpm进程数量,在动态方式下限定php-fpm的最大进程数
pm.start_servers=100 #动态模式下初始进程数,必须大于等于pm.min_spare_servers和小于等于pm.max_children的值
pm.min_spare_servers=100 #最小空闲进程数
pm.max_spare_servers=200 #最大空闲进程数
pm.max_requests = 500000 #进程累计请求回收值,会重新生成进程
pm.status_path = /pm_status #状态访问URL
ping.path = /ping #ping访问活动地址
ping.response = pong #ping返回值
php_value[session.save_handler] = files #以文件存放session,也可以支持redis等
php_value[session.save_path] = /var/lib/php/session #设置session存放位置
access.log log/access.log #访问日志
access.format "%R - %u %t \"%m %r\" %s" #访问日志格式
error_log log/php-fpm.log #错误日志
request_slowlog_timeout mixed #当一个请求该设置的超时时间后,就会将对应的 PHP 调用堆栈信息完整写入到慢日志中。设置为 '0' 表示 'Off'。可用单位:s(秒),m(分),h(小时)或者d(天)。默认单位:s(秒)。默认值:0(关闭)
slowlog log/php-fpm.log.slow #慢请求的记录日志
确保运行php-fpm进程的用户对session目录有读写权限
mkdir /var/lib/php/session
chown apache.apache /var/lib/php/session
启用日志
[root@centos8 ~]#vim /etc/php-fpm.d/www.conf
access.log = /var/log/php-fpm/access.log
systemctl start php-fpm
注意:在HTTPD服务器上必须启用proxy_fcgi_module模块,才能充当php-fpm客户端
#centos8默认支持fastcgi模块,安装php-fpm包时,会自动生成/etc/httpd/conf.d/php.conf文件实
现支持UDS
#如果想实现支持端口的fastcgi,可以创建/etc/httpd/conf.d/fcgi.conf,注意: 需要删除上面的php.conf文件
DirectoryIndex index.php
ProxyRequests Off
ProxyPassMatch ^/(.*\.php)$ fcgi://php-fpm服务器IP:9000/var/www/html/$1
ProxyPassMatch ^/(fpm_status|ping) fcgi://127.0.0.1:9000
#以上开启FCGI反向代理,“^/”此处的”/“相对于后面的/var/www/html而言,后面的$1是指前面
的/(.*.php)
#如果php-fpm和httpd在同一台主机,也可以用 UDS(unix domain socket)方式
#参看:http://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html
ProxyPassMatch ^/(.*\.php)$
unix:/var/run/php.sock|fcgi://localhost/apps/httpd/htdocs/$1
编译安装基于fastcgi的LAMP
#!/bin/bash
rpm -q gcc make pcre-devel openssl-devel expat-devel bzip2 >/dev/null || yum -y install gcc make pcre-devel openssl-devel expat-devel bzip2 libxml2-devel bzip2-devel libmcrypt-devel sqlite-devel oniguruma-devel
tar -xvf apr-1.7.0.tar.bz2 -C /usr/local/src
tar -xvf apr-util-1.6.1.tar.bz2 -C /usr/local/src
tar -xvf httpd-2.4.46.tar.bz2 -C /usr/local/src
mv /usr/local/src/apr-1.7.0 /usr/local/src/httpd-2.4.46/srclib/apr
mv /usr/local/src/apr-util-1.6.1 /usr/local/src/httpd-2.4.46/srclib/apr-util
[ -d /app ] || mkdir /app
cd /usr/local/src/httpd-2.4.46
./configure --prefix=/app/http2.4 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-include-apr --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
make && make install
id apache > /dev/null || useradd -s /sbin/nologin -r apache
grep -E "^User apache" /app/http2.4/conf/httpd.conf || sed -ri -e "s/^User.*/User apache/" -e "s/^Group.*/Group apache/" /app/http2.4/conf/httpd.conf
echo "PATH=/app/http2.4/bin:$PATH" > /etc/profile.d/httpd.sh && source /etc/profile.d/httpd.sh
echo "MANDATORY_MANPATH /app/http2.4/man" >> /etc/man_db.conf
cat > /usr/lib/systemd/system/httpd.service <<EOF
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
ExecStart=/app/http2.4/bin/apachectl start
ExecReload=/app/http2.4/bin/apachectl graceful
ExecStop=/app/http2.4/bin/apachectl stop
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
tar -xvf php-7.4.30
cd php-7.4.30
./configure --prefix=/app/php --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-openssl --with-zlib --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-mbstring --enable-xml --enable-sockets --enable-fpm --enable-maintainer-zts --disable-fileinfo && make && make install
echo PATH=/app/php/bin:$PATH >> /etc/profile.d/httpd.sh && source /etc/profile.d/httpd.sh
cp php.ini-production /etc/php.ini
cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
cd /app/php/etc
cp php-fpm.conf.default php-fpm.conf
cd php-fpm.d/
cp www.conf.default www.conf
grep "^user = apache" /app/php/etc/php-fpm.d/www.conf || sed -ri "s/^user.*/user = apache/" /app/php/etc/php-fpm.d/www.conf
grep "^group = apache" /app/php/etc/php-fpm.d/www.conf || sed -ri "s/^group.*/group = apache/" /app/php/etc/php-fpm.d/www.conf
mkdir /etc/php.d/
cat > /etc/php.d/opcache.ini <<EOF
[opcache]
zend_extension=opcache.so
opcache.enable=1
EOF
sed -ri "s#.*(LoadModule proxy_module modules/mod_proxy.so)#\1#" /app/http2.4/conf/httpd.conf
sed -ri "s#.*(LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so)#\1#" /app/http2.4/conf/httpd.conf
sed -ri "s#.*(DirectoryIndex index.html)#\1 index.php#" /app/http2.4/conf/httpd.conf
cat >> /app/http2.4/conf/httpd.conf <<EOF
AddType application/x-httpd-php .php
#AddType application/x-httpd-php-source .phps
ProxyRequests Off
IncludeOptional /app/http2.4/conf.d/*.conf
EOF
systemctl daemon-reload && systemctl start php-fpm.service
systemctl daemon-reload && systemctl start httpd.service
chown -R apache:apache /data/wordpress/
chown -R apache:apache /data/discuz/
编译安装mariadb
yum -y install libaio
useradd -r -s /sbin/nologin mysql
tar -xvf mariadb-10.4.0-linux-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/mariadb-10.4.0-linux-x86_64 /usr/local/mysql
chown -R root:root /usr/local/mysql/
mkdir /data/mysql
chown -R mysql:mysql /data/mysql/
mkdir /etc/mysql
cp /usr/local/mysql/support-files/wsrep.cnf /etc/mysql/my.cnf
grep "datadir" /etc/mysql/my.cnf || sed -ri "/\[mysqld\]/a\datadir=/data/mysql\nskip_name_resolve=ON" /etc/mysql/my.cnf
cat > /etc/profile.d/mysql.sh<<EOF
PATH=/usr/local/mysql/bin/:$PATH
EOF
source /etc/profile.d/mysql.sh
cd /usr/local/mysql;scripts/mysql_install_db --user=mysql --datadir=/data/mysql
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
systemctl daemon-reload
systemctl start mysql.server
[root@localhost ~]# mysql -uroot -e "create database discuz"
[root@localhost ~]# mysql -uroot -e "grant all on discuz.* to discuz@'10.0.0.%' identified by '123456';"
[root@localhost ~]# mysql -uroot -e "create database wordpress"
[root@localhost ~]# mysql -uroot -e "grant all on wordpress.* to wordpress@'10.0.0.%' identified by '123456';"
测试
root@ubuntu:~# curl wordpress.magedu.org -I
HTTP/1.1 200 OK
Date: Sun, 03 Jul 2022 10:27:27 GMT
Server: Apache/2.4.46 (Unix)
X-Powered-By: PHP/7.4.30
Link: <http://10.0.0.17/index.php?rest_route=/>; rel="https://api.w.org/"
Content-Type: text/html; charset=UTF-8
root@ubuntu:~# curl discuz.magedu.org -I
HTTP/1.1 200 OK
Date: Sun, 03 Jul 2022 10:27:54 GMT
Server: Apache/2.4.46 (Unix)
X-Powered-By: PHP/7.4.30
Set-Cookie: us4i_2132_saltkey=Qt7w8xTe; expires=Tue, 02-Aug-2022 10:27:54 GMT; Max-Age=2592000; path=/; HttpOnly
Set-Cookie: us4i_2132_lastvisit=1656840474; expires=Tue, 02-Aug-2022 10:27:54 GMT; Max-Age=2592000; path=/
Set-Cookie: us4i_2132_sid=js81xP; expires=Mon, 04-Jul-2022 10:27:54 GMT; Max-Age=86400; path=/
Set-Cookie: us4i_2132_lastact=1656844074%09index.php%09; expires=Mon, 04-Jul-2022 10:27:54 GMT; Max-Age=86400; path=/
Set-Cookie: us4i_2132_onlineusernum=1; expires=Sun, 03-Jul-2022 10:32:54 GMT; Max-Age=300; path=/
Set-Cookie: us4i_2132_sid=js81xP; expires=Mon, 04-Jul-2022 10:27:54 GMT; Max-Age=86400; path=/
Content-Type: text/html; charset=utf-8
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律