一、Nginx概述
1.1 Nginx概述
Nginx:
Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。
对HTTP并发连接的处理能力高,单台物理服务器可支持30000~50000个并发请求。
Apache:
Apache是以进程为基础的结构,进程要比线程消耗更多的系统开支,不太适用于多处理器环境,因此,在一个apache Web站点扩容时,通常是增加服务器或扩充群集节点而不是增加处理器。
1.2 Nginx和Apache的差异
Nginx | Apache |
---|---|
nginx是一个基于事件的web服务器 | apache是一个基于流程的服务器 |
所有请求都由一个线程处理 | 单个线程处理单个请求 |
nginx避免子进程的概念 | apache是基于子进程的 |
nginx类似于速度 | apache类似于功率 |
nginx在内存消耗和连接方面比较好 | apache在内存消耗和连接上没有提高 |
nginx在负载均衡方面表现较好 | 当流量到达进程极限时,apache将拒绝新的连接。 |
nginx不支持IBMI和openvms一样的os | apache支持更多的os |
nginx只具有核心功能 | apache提供了比nginx更多的功能 |
nginx的性能和可伸缩性不依赖于硬件 | apache依赖于cpu和内存等硬件组件 |
Nginx支持热部署 | Apache不支持热部署 |
Apache: 创建多个进程或线程,而每个进程或线程都会为其分配cpu和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会榨干服务器资源。
Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量),不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx 支持更高的并发。
1.3 Nginx和Apache的优缺点比较
(1)nginx相对于apache的优点∶
轻量级,nginx比apache 占用更少的内存及资源;
静态处理,Nginx 静态处理性能比 Apache 高 ;
Nginx可以实现无缓存的反向代理加速,提高网站运行速度;
Nginx的性能和可伸缩性不依赖于硬件,Apache依赖于硬件;
Nginx支持热部署,启动速度迅速,可以在不间断服务的情况下,对软件版本或者配置进行升级;
nginx是异步进程,多个连接可以对应一个进程 ;apache是同步多进程,一个连接对应一个进程;
Nginx高度模块化,编写模块相对简单,且组件比Apache少
高并发下nginx 能保持低资源低消耗高性能;
Nginx 配置简洁, Apache配置复杂
(2)apache相对于nginx的优点∶
- Rewrite比nginx的rewrite强大 (rewrite的主要功能就是实现统一资源定位符URL的跳转)
- 模块多,基本想到的都可以找到
- 少bug, nginx的bug相对较多
- 超稳定
- Nginx处理动态请求是弱项,动态请求要Apache去做。
总结:一般来说,需要性能的web服务,用Nginx. 如果不需要性能只求稳定,那就Apache。Nginx处理动态请求是弱项,一般动态请求要Apache去做,Nginx只适处理静态网页或反向代理。
1.4 Nginx的进程
Apache和Nginx的默认端口都是80,如果其中一个已经启动了,那么再启动另一个会报错。如果想要同时使用,可以修改其中一个的端口号。
Nginx有两个进程:
master process:主进程(守护进程),用来管理工作进程。(只有一个)
worker process:工作进程,用来处理用户的请求
经典问题1:Nginx 是如何实现高并发的?
异步,非阻塞,使用了epoll 和大量的底层代码优化。如果一个server采用一个进程负责一个request的方式,那么进程数就是并发数。正常情况下,会有很多进程一直在等待中。
而nginx采用一个master进程,多个woker进程的模式。
master进程主要负责收集、分发请求。每当一个请求过来时,master就拉起一个worker进程负责处理这个请求。同时master进程也负责监控woker的状态,保证高可靠性
woker进程一般设置为跟cpu核心数一致。nginx的woker进程在同一时间可以处理的请求数只受内存限制,可以处理多个请求。
同步,异步,阻塞,非阻塞的概念补充
同步和异步
同步:一个服务的完成需要依赖其他服务时,只有等待被依赖的服务完成后,才算完成,这是一种可靠的服务序列。要么成功都成功,失败都失败,服务的状态可以保持一致
异步:一个服务的完成需要依赖其他服务时,只通知其他依赖服务开始执行,而不需要等待被依赖的服务完成,此时该服务就算完成了。被依赖的服务是否最终完成无法确定,因此它是一个不可靠的服务序列。
阻塞与非阻塞
阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务,函数只有在得到结果之后才会返回。
非阻塞:非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
经典问题2:Nginx为什么不使用多线程?
Apache: 创建多个进程或线程,而每个进程或线程都会为其分配 cpu 和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会耗光服务器资源。Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量)(epoll),不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx支持更高的并发。
二、编译安装nginx服务
2.1 关闭防
火墙,将nginx所需压缩包上传到/opt目录下
2.2 安装依赖包
nginx的配置及运行需要pcre、zlib等软件包的支持,因此需要安装这些软件的开发包,以便提供相应的库和头文件。
yum install -y pcre-devel zlib-devel gcc gcc-c++ make
2.3 创建运行用户和组,便于管理
nginx服务程序默认以nobody身份运行,建议为其创建专门的用户账号,以便更准确地控制其访问权限。
useradd -M -s /sbin/nologin nginx
2.4 解压软件包,编译安装nginx
应为httpd服务的端口也是80 ,所以可以先把httpd服务停掉,防止端口冲突
#解压软件包
[root@yuji ~]# cd /opt
[root@yuji opt]# ls
nginx-1.12.2.tar.gz rh
[root@yuji opt]# tar zxf nginx-1.12.2.tar.gz
[root@yuji opt]# ls
nginx-1.12.2 nginx-1.12.2.tar.gz rh
#切换到源码目录,运行configure脚本,指定安装路径和安装模块等。
[root@yuji opt]# cd nginx-1.12.2/
[root@yuji nginx-1.12.2]# ./configure \
--prefix=/usr/local/nginx \ #指定nginx的安装路径
--user=nginx \ #指定用户名(运行用户)
--group=nginx \ #指定组名
--with-http_stub_status_module #启用http_stub_status_module模块以支持状态统计
#开2核同时编译,之后安装
[root@yuji nginx-1.12.2]# make -j 2 && make install
2.5 将nginx的操作指令放入环境变量PATH的目录下
将nginx的可执行文件做个软链接,放入环境变量PATH的目录下,让系统识别nginx的操作指令
[root@yuji ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
2.6 检查、启动、重启、停止nginx服务
2.6.1 检查配置文件是否配置正确,并启动nginx服务
nginx -t
启动nginx服务
/usr/local/sbin/nginx
#快捷运行
nginx
启动nginx后 查看端口
2.6.2 停止nginx服务
cat /usr/local/nginx/logs/nginx.pid #先查看nginx的PID号
kill -3 <PID号>
kill -s QUIT <PID号>
killall -3 nginx
killall -s QUIT nginx
除此之外:还有多种方式可以查看nginx进程号
cat /usr/local/nginx/logs/nginx.pid //查看nginx主进程的PID
pgrep nginx -l //查看nginx的主进程号和工作进程号
lsof -i :80 //查看nginx的主进程号和工作进程号
ss -ntap | grep nginx //查看nginx的主进程号和工作进程号
netstat -ntap | grep nginx //查看nginx主进程的PID
2.6.3 重载nginx服务
kill -1 <PID号>
kill -s HUP <PID号>
killall -1 nginx
killall -s HUP nginx
三 日志分割,重新打开日志文件
nignx服务日志目录 /usr/local/nginx/logs
root@localhost logs]#ls
access.log error.log nginx.pid
[root@localhost logs]#mv access.log access.`date +%F`.log
[root@localhost logs]#ls
access.2022-09-27.log error.log nginx.pid
[root@localhost logs]#kill -USR1 8468
[root@localhost logs]#ls
access.2022-09-27.log access.log error.log nginx.pid
四 平滑升级
引入新的升级安装包:
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module \
--with-http_ssl_module
编译安装新的nginx升级软件包
#编译安装
make
#将老版本的nginx进行备份,防止升级失败,还原
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_old
#将新的运行文件放入安装的运行目录
cp objs/nginx /usr/local/nginx/sbin/nginx
平滑升级:
make upgrade
nginx -v #查看nginx版本
五 nginx添加到系统服务
我们使用yum安装的服务时,一般启动方式均为 :systemctl 服务名 操作 。对于源码安装后的nginx并不能直接像这样使用。所以我们可以通过脚本或则系统服务的更改来实现系统服务的启动方式
方式一:脚本方式
#!/bin/bash
#chkconfig: 2345 20 90
#description:This is Nginx Service Control Script
CMD="/usr/local/nginx/sbin/nginx"
PID="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
$CMD
;;
stop)
kill -s QUIT $(cat $PID)
;;
restart)
$0 stop
$0 start
;;
reload)
kill -s HUP $(cat $PID)
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
(需要切换init状态才能生效)
方式二: 在主服务中(/lib/systemd/system/)添加nginx服务配置
实验前准备:
[root@localhost init.d]#mkdir nginx.old [root@localhost init.d]#mv nginx ./nginx.old/
开始执行第二种方式:
vim /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@localhost init.d]#vim /lib/systemd/system/nginx.service
[root@localhost init.d]#chmod 754 /lib/systemd/system/nginx.service
[root@localhost init.d]#systemctl daemon-reload #执行前重载服务
[root@localhost init.d]#systemctl start nginx
[root@localhost init.d]#systemctl status nginx