HTTP Service 上篇
1、跨网络的主机通讯
Socket套接字套接字Socket是进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换.
在建立通信连接的每一端,进程间的传输要有两个标志:IP地址和端口号,合称为套接字地址 socket address
客户机套接字地址定义了一个唯一的客户进程
服务器套接字地址定义了一个唯一的服务器进程
1.1 Socket API封装了内核中所提供的socket通信相关的系统调用
Socket Domain:根据其所使用的地址
AF_INET:Address Family,IPv4
AF_INET6:IPv6
AF_UNIX:同一主机上不同进程之间通信时使用
Socket Type:根据使用的传输层协议
SOCK_STREAM:流,tcp套接字,可靠地传递、面向连接
SOCK_DGRAM:数据报,udp套接字,不可靠地传递、无连接
SOCK_RAW: 裸套接字,无须tcp或udp,APP直接通过IP包通信
套接字相关的系统调用:
socket() 创建一个套接字
bind() 绑定IP和端口
listen() 监听
accept() 接收请求
connect() 请求连接建立
write() 发送
read() 接收
close() 关闭连接
2、HTTP 超文本传输协议
2.1 浏览器访问网站的过程
2.2 HTTP协议通信过程
HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。(表面理解:不仅仅传输文本,还可以图片、视频等浏览器可解析的内容)
2.3 HTTP服务通信过程
结合图1简要描述:(结合python Socket编程)
客户端:
s=socket.socket(socket,AF_INET,socket.SOCK_STREAM) 创建新的套接字定义socket类型,tcp传输协议
s.connect((HOST,PORT)) 连接服务器的IP和端口
此时服务器端
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 创建新的套接字
sock.bind((HOST,PORT)) 绑定IP和port,HTTP的默认端口80
然后客户端
sock.connect((HOST,PORT)) 连接服务端
服务器端
通知应用程序有连接到来(连接成功)
客户端:发送HTTP请求(write)
sock.send(b'hello, tcpServer!') 客户端发送消息给服务器端
服务器端:开始读取HTTP请求报文(read)
recvmsg = clientsocket.recv(1024) 服务器端接受来自客户端的消息
服务器端:回应HTTP响应(write)
client_sock.send(b'tcpServer has received your message') 服务器回复客户端
客户端:处理服务器发来的回复(read)
recv=sock.recv(BUFFER) 客户端接收服务器端的消息
本次连接结束(断开):
服务端和客户端:
socket.close() 连接关闭
2.4 HTTP协议分层
2.5 HTTP相关技术和术语
2.5.1 WEB开发语言
http:Hyper Text Transfer Protocol 应用层协议,默认端口: 80/tcp
WEB前端开发语言:
html
css
javascript
html
Hyper Text Markup Language 超文本标记语言,编程语言,主要负责实现页面的结构CSSCascading Style Sheet 层叠样式表, 定义了如何显示(装扮) HTML 元素,比如:字体大小和颜色属性等。样式通常保存在外部的 .css 文件中。通过仅仅编辑一个简单的 CSS 文档,可以同时改变站点中所有页面的布局和外观。
Js
javascript,实现网页的动画效果
MIME:
Multipurpose Internet Mail Extensions 多用途互联网邮件扩展,对应文件 /etc/mime.types
MIME格式:major/minor
2.5.2 URI和URL
URI: Uniform Resource Identifier 统一资源标识,分为URL和URNURN: Uniform Resource Naming,统一资源命名
示例: P2P下载使用的磁力链接是URN的一种实现
magnet:?xt=urn:btih:660557A6890EF888666
URL: Uniform Resorce Locator,统一资源定位符,用于描述某服务器某特定资源位置
两者区别:URN如同一个人的名称,而URL代表一个人的住址。换言之,URN定义某事物的身份,而URL提供查找该事物的方法。URN仅用于命名,而不指定地址。
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
scheme: 访问服务器以获取资源时要使用哪种协议
user:用户,某些方案访问资源时需要的用户名
password:密码,用户对应的密码,中间用:分隔
Host:主机,资源宿主服务器的主机名或IP地址
port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号
path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔
params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔
query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔
frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔
2.5.3 网站访问量
网站访问量统计的重要指标
IP(独立IP):即Internet Protocol,指独立IP数。一天之内同一个IP按一次算
PV(访问量):客户每刷新一次便记录一次。
UV(独立访客):即Unique Visitor,访问网站的一台电脑为一个访客。
网站统计:http://www.alexa.cn/rank/
网站访问量
QPS:request per second,每秒请求数
PV,QPS和并发连接数换算公式
QPS= PV * 页面衍生连接次数/ 统计时间(86400)
并发连接数 =QPS * http平均响应时间
峰值时间:每天80%的访问集中在20%的时间里,这20%时间为峰值时间
峰值时间每秒请求数(QPS)=( 总PV数 *页面衍生连接次数)*80% ) / ( 每天秒数 * 20% )
2.6 HTTP工作机制
一次http事务包括:
http请求:http request
http响应:http response
HTTP连接请求
串行和并行连接
串行:每次连接只能发起一次请求,HTTP事务连接结束才能再次建立连接
并行连接:通过多条TCP连接发起并发的HTTP请求,执行多个HTTP事务
持久连接:keep-alive,HTTP事务完成以后,TCP连接仍保持连接状态,直到客户端或服务器决定将其关闭为止
管道化连接:以多条请求放入队列,共享TCP连接。并行处理请求,解决传输延时问题
2.7 HTTP 请求访问的完整过程
一次完整的http请求处理过程
2.7.1 建立连接:接收或拒绝连接请求
2.7.2 接收请求:接收客户端请求报文中对某资源的一次请求的过程
Web访问响应模型(Web I/O)
单进程I/O模型:启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应
多进程I/O模型:并行启动多个进程,每个进程响应一个连接请求
复用I/O结构:启动一个进程,同时响应N个连接请求
复用的多进程I/O模型:启动M个进程,每个进程响应N个连接请求,同时接收M*N个请求
2.7.3 处理请求
常用请求Method: GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS。
2.7.4 访问资源
服务器获取请求报文中请求存放了web资源的服务器,负责向请求者提供对方请求的静态资源,或动态运行后生成的资源。
2.7.5 构建响应报文
执行请求方法中描述的动作,并返回响应报文。
2.7.6 发送响应报文
Web服务器通过连接发送数据,向客户端回送响应数据。
2.7.7 记录日志
最后,当事务结束时,Web服务器会在日志文件中添加一个条目,来描述已执行的事务。
3、httpd 安装和组成
HTTP服务器市场占有率统计: http://www.netcraft.com
3.1 apache 介绍
apache特性:
高度模块化:core + modules
DSO:Dynamic Shared Object 动态加/卸载
MPM:multi-processing module 多路处理模块
apache 功能:
虚拟主机:IP、Port、FQDN
CGI:Common Gateway Interface,通用网关接口
反向代理
负载均衡
路径别名
丰富的用户认证机制:basic,digest
支持第三方模块
3.2 MPM: multi-processing module 工作模式
3.2.1 prefork:多进程I/O模型,每个进程响应一个请求,CentOS7 默认模型
一个主进程:生成和回收n个子进程,创建套接字,不响应请求。
多个子进程:工作work进程,每个子进程处理一个请求;系统初始时,预先生成多个空闲进程,等待请求。
Prefork MPM:一个主进程,生成多个子进程,每个子进程生成一个独立的线程来处理请求。
优点:稳定。
缺点:慢、占用资源、不适合高并发场景。
3.2.2 worker:复用的多进程I/O模型,多进程多线程,IIS使用此模型
一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n。
worker MPM:一个控制进程,生成多个子进程,每个子进程生成多个线程,使用线程处理请求。
优点:相比prefork 占用的内存较少,可以同时处理更多的请求。
缺点:使用keep-alive方式,某个线程被长期占用,即使无请求也要处于等待状态,直到超时才释放。
3.2.3 event:事件驱动模型(worker模型的变种),CentOS8 默认模型
相对于worker模型,多了监控线程,用于管理keep-alived线程,有请求分配给线程,没有就释放,增强了高并发场景下的请求处理能力。
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。
缺点:没有线程安全控制。
4、Httpd 安装和相关文件
4.1 rpm包安装httpd并启动httpd服务
1 [root@centos8 ~]#dnf -y install httpd 2 AppStream 3 63 MB/s | 5.2 MB 4 00:00 5 BaseOS 6 26 MB/s | 2.2 MB 7 00:00 8 EPEL 9 650 kB/s | 3.2 MB 10 00:05 11 extras 12 476 B/s | 2.1 kB 13 00:04 14 Dependencies resolved. 15 ================================================================================ 16 ========= 17 Package Arch Version Repository 18 Size 19 ================================================================================ 20 ========= 21 Installing: 22 httpd x86_64 2.4.37-11.module_el8.0.0+172+85fc1f40 AppStream 23 1.7 M 24 Installing dependencies: 25 apr x86_64 1.6.3-9.el8 AppStream 26 125 k 27 apr-util x86_64 1.6.1-6.el8 AppStream 28 105 k 29 centos-logos-httpd noarch 80.5-2.el8 AppStream 30 24 k 31 ...省略... 32 Install 9 Packages 33 Total size: 2.2 M 34 Installed size: 6.0 M 35 Is this ok [y/N]: y 36 Downloading Packages: 37 Running transaction check 38 Transaction check succeeded. 39 Running transaction test 40 Transaction test succeeded. 41 Running transaction 42 Preparing : 43 1/1 44 Installing : apr-1.6.3-9.el8.x86_64 45 1/9 46 Running scriptlet: apr-1.6.3-9.el8.x86_64 47 1/9 48 ...省略... 49 Complete! 50 [root@centos8 ~]#systemctl start httpd 51 [root@centos8 ~]#ss -ntl|grep :80 52 LISTEN 0 128 *:80 *:* *:*
4.2 httpd-2.4 相关文件
配置文件:
/etc/httpd/conf/httpd.conf 主配置文件
/etc/httpd/conf.d/*.conf 子配置文件
/etc/httpd/conf.d/conf.modules.d/ 模块加载的配置文件
服务单元文件:
/usr/lib/systemd/system/httpd.service
配置文件:/etc/sysconfig/httpd
服务控制和启动
systemctl enable|disable httpd.service
systemctl {start|stop|restart|status|reload} httpd.service
站点网页文档根目录:/var/www/html
模块文件路径:
/etc/httpd/modules
/usr/lib64/httpd/modules
主服务器程序文件: /usr/sbin/httpd
主进程文件: /etc/httpd/run/httpd.pid
日志文件目录:/var/log/httpd
access_log: 访问日志
error_log:错误日志
帮助文档包:httpd-manual
4.3 httpd配置文件的组成
主要组成
Global Environment
Main server configuration
virtual host
配置文件格式:
格式说明:
directive 不区分字符大小写
value 为路径时,是否区分大小写,取决于文件系统
配置官方帮助: http://httpd.apache.org/docs/2.4/
4.3 编译安装httpd-2.4
安装依赖包 gcc make pcre-devel openssl-devel expat-devel
下载源代码并解压缩: httpd-2.4.39.tar.bz2,apr-1.7.0.tar.bz2,apr-util-1.6.1.tar.bz2
[root@node-128 ~]# yum -y install gcc make pcre-devel openssl-devel expat-devel Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com base | 3.6 kB 00:00:00 epel | 5.3 kB 00:00:00 extras | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/2): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (2/2): epel/x86_64/primary_db | 6.9 MB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package expat-devel.x86_64 0:2.1.0-10.el7_3 will be installed ---------------------------省略-------------------------------------------------------------
一般情况下载的源码放在/usr/local/src中
[root@node-128 ~]# ls
anaconda-ks.cfg apr-1.7.0.tar.bz2 apr-util-1.6.1.tar.bz2 httpd-2.4.41.tar.gz
[root@node-128 ~]# mv apr-1.7.0.tar.bz2 apr-util-1.6.1.tar.bz2 httpd-2.4.41.tar.gz /usr/local/src/
4.3.1 将apr 和apr-util源码与httpd 源码合并
[root@node-128 src]# tar xvf apr-1.7.0.tar.bz2 apr-1.7.0/ apr-1.7.0/emacs-mode apr-1.7.0/passwd/ --------------------------------------省略-------------------------------------- [root@node-128 src]# tar xvf apr-util-1.6.1.tar.bz2 apr-util-1.6.1/ apr-util-1.6.1/strmatch/ --------------------------------------省略------------------------------------- [root@node-128 src]# ls apr-1.7.0 apr-util-1.6.1 httpd-2.4.41 apr-1.7.0.tar.bz2 apr-util-1.6.1.tar.bz2 httpd-2.4.41.tar.gz
修改名字apr、apr-util [root@node-128 src]# mv apr-1.7.0 httpd-2.4.41/srclib/apr [root@node-128 src]# mv apr-util-1.6.1 httpd-2.4.41/srclib/apr-util [root@node-128 src]# ls httpd-2.4.41/srclib/ apr apr-util Makefile.in
4.3.2 将三者一并编译并安装
[root@node-128 httpd-2.4.41]# ./configure \ > --prefix=/app/httpd24 \ > --enable-so \ > --enable-ssl \ > --enable-cgi \ > --enable-rewrite \ > --with-zlib \ > --with-pcre \ > --with-included-apr \ > --enable-modules=most \ > --enable-mpms-shared=all \ > --with-mpm=prefork make&&make install
4.3.3 编译安装后配置
http的相关配置文件在下面目录
Httpd编译过程:/app/httpd24/build/config.nice
自带的服务控制脚本:/app/httpd24/bin/apachectl
[root@node-128 httpd24]# ls bin cgi-bin error icons lib man modules build conf htdocs include logs manual
使用apachctl 命令
[root@node-128 httpd24]# echo 'PATH=/app/httpd24/bin:$PATH' > /etc/profile.d/httpd24.sh
[root@node-128 httpd24]# . /etc/profile.d/httpd24.sh
启动httpd服务
[root@node-128 httpd24]# apachectl start AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::d386:496:dd09:2c09%ens33. Set the 'ServerName' directive globally to suppress this message [root@node-128 httpd24]# ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:111 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::111 :::* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
开机自启动
[root@node-128 htdocs]# cd /etc/rc.d [root@node-128 rc.d]# ls init.d rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rc.local [root@node-128 rc.d]# chmod +x rc.local [root@node-128 build]# vim /etc/rc.local 追加 /app/httpd24/bin/apachectl start
创建service unit文件(CentOS 7 以上版本)
vim /usr/lib/systemd/system/httpd.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=/app/httpd24/bin/httpd $OPTIONS -k start ExecReload=/app/httpd24/bin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH {MAINPID} KillSignal=SIGCONT PrivateTmp=true [Install] WantedBy=multi-user.target
daemon-reload: 重新加载httpd服务的配置文件,归属于 systemctl 管理,要是新服务的服务程序配置文件生效,需重新加载。
[root@node-128 bin]# systemctl daemon-reload
[root@node-128 bin]# apachectl stop
[root@node-128 bin]# systemctl start httpd [root@node-128 bin]# ss -nlt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:111 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::111 :::* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node-128 bin]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. [root@node-128 bin]# systemctl status httpd ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2019-12-08 17:25:31 CST; 1min 59s ago Docs: man:httpd(8) man:apachectl(8) Main PID: 1480 (httpd) CGroup: /system.slice/httpd.service ├─1480 /app/httpd24/bin/httpd -k start ├─1482 /app/httpd24/bin/httpd -k start ├─1483 /app/httpd24/bin/httpd -k start ├─1484 /app/httpd24/bin/httpd -k start ├─1485 /app/httpd24/bin/httpd -k start └─1486 /app/httpd24/bin/httpd -k start Dec 08 17:25:21 node-128 systemd[1]: Starting The Apache HTTP Server... Dec 08 17:25:31 node-128 httpd[1479]: AH00558: httpd: Could not reliably determin...ge Dec 08 17:25:31 node-128 systemd[1]: Started The Apache HTTP Server. Hint: Some lines were ellipsized, use -l to show in full.