源码地址:https://github.com/duchenlong/linux-text/tree/master/socket
对于为什么会有Nginx这个东西,主要的原因还是因为需求量越来越大。
一开始,我们在部署服务器的时候,就是直接写一个服务端的程序,然后跑起来,把他挂到后台就可以了。这样的话,客户端与服务端之间的关系是多对一
慢慢的,如果越来越多的人访问服务器,那么就会造成这样的局面
如果同时访问我们服务器的用户比较多的话,会增大服务器的负载程度,就出现下面这种情况
在
多对一
的结构中,再次进行升级,是否可以有其他服务器来分摊部分用户访问带来的压力呢?
为了解决多个用户同时访问服务端,而造成服务器压力过大的问题,就进行横向扩展
,再增加几台服务器
当有多个用户进行请求访问的时候,将处理请求的逻辑放在其他服务器中,就避免了一个服务器需要阻塞的处理多个请求,那么多个用户请求可以并行处理,降低服务器的负载程度
直观上看,如果要实现这种模式,每个用户就得指导每个服务器的地址,那么这样就是一个多对多
的结构
但是这样的结构对于用户来说有些复杂,就为了访问一个项目,还得直到所有服务器的网址,显然是不科学也不安全的。
没有什么是加一层解决不了的,如果有,那就再加一层
于是乎,就出现了下面这种代理服务器的模式,用户在访问的时候,只需要访问一个特点的网址,然后代理服务器负责将这些请求分配到不同的服务器中进行处理。
这样就可以将多对多
的结构,转变为用户和代理服务器,代理服务器和服务器之间多对一,一对多
的联系,降低了用户和服务器之间的联系
那么中间这个代理服务器就需要实现反向代理
的功能,就是说,有这么一个请求来了,代理服务器需要知道哪像服务器可以处理该请求,然后将该请求发送给这个服务器去处理,处理完之后再通过代理服务器返回给用户。
除此之外,还需要有负载均衡
的能力,而Nginx
就是可以实现这些功能的软件之一。
百度百科
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。
特点:
事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
在介绍反向代理之前,还有一个正向代理的概念。 我们在访问国外的网站时,访问速度会比较慢,通常的做法就是在我们的电脑上开一个VPN,而VPN就是一个正向代理的服务器。
就是说,我们国内有些地方直接访问国外服务器的话,可能会比较慢,但是有些地方访问国外服务器是会比较快的,就可以在这个地方建立一个中转的服务器,帮助我们访问国外的网站就可以了,再将响应的结果通过代理服务器返回给我们,就可以快速的访问国外的网站了。
正向代理可以说是我们客户端自己的一种主动行为,而反向代理则是服务端的一种方式,类比我们访问网站的一个过程来说
我们在浏览器中访问一个网址,通过网络后,我们的请求就会到达一个代理服务器中,代理服务器根据我们后台服务器的处理能力,将请求发送给一个指定的服务器来进行处理,处理完毕后,返回给代理服务器,再通过网络返回给我们请求的结果
在Nginx中,负载均衡有两种策略,为内置策略和扩展策略
内置策略主要有:
在轮询的策略中,我们服务端中的服务器处理请求的方式为顺序处理,依次为每一个服务器分配一个请求,当分配到最后一个服务器的时候,下一次请求的处理便从第一个服务器重新开始
加权轮询的策略中,解决的问题就是,我们后端的服务器可能处理的能力不同,有些服务器性能很好,可以处理3个请求,但是有些服务器性能比较差,只能处理1个请求。
这样如果使用轮询的方式,对于那些处理能力比较差的服务器,很可能会陷入阻塞,那么就出现了加权轮询的方式,可以为每一个服务器分配一个权重,那么后面的请求会根据每个服务器的权重依次分配。
对客户端的ip进行哈希操作,根据哈希操作的结果,将客户端的ip请求发送给一台固定的服务器。也就是说,客户端每次访问的时候,都是由一个固定的服务器来处理该请求的
下载之后,进行解压,会出现以下的目录
开启Nginx服务,只需要在命令行界面中运行nginx.exe
程序就行 ( 直接点击可视化图标没有效果
在浏览器中输入localhost:80
或者127.0.0.1:80
,进行访问( 浏览器会默认加上80端口,所以也可以不用手动加上80端口信息
先下载对应的安装包,然后再通过Xshell
传到Linux系统中,输入以下命令即可
# 解压
tar -zxvf nginx-1.18.0.tar.gz
# 进入 nginx-1.18.0 目录中
cd nginx-1.18.0
# 运行 configure 程序
./configure
# 安装
make
# 如果权限不够,可以使用sudo ,root用户
make install
在执行configure程序时,可能会出现以下错误,只需要对应安装即可
sudo yum -y install pcre-devel
sudo yum -y install zlib-devel
可以使用whereis
命令来查看是否安装成功
[duchlong@localhost nginx-1.18.0]$ whereis nginx
nginx: /usr/local/nginx
手动运行Nginx
,先进入/usr/local/nginx
目录
再进入sbin
目录下,运行nginx
程序即可(如果出现权限问题,可以加sudo,再运行
Nginx在启动之前,一点要注意,他的默认端口号是80
,所以一定要保证对应的端口号是开放的。
如果是虚拟机中,可以关闭防火墙,或者单独开放指定端口
# 查看firewalld 服务状态
systemctl status firewalld
# 查看firewalld 状态
firewall-cmd --state
# 开启 firewalld 服务
service firewalld start
# 重启 firewalld 服务
service firewalld restart
# 关闭 firewalld 服务
service firewalld stop
# 查看防火墙规则
firewall-cmd --list-all
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除80端口
firewall-cmd --permanent --remove-port=80/tcp
#重启防火墙(修改配置后要重启防火墙
firewall-cmd --reload
参数解释
如果是在云服务器中,则需要配置安全组,开放80端口 (或者自定义的端口
# 进入Nginx 的运行目录
cd /usr/local/nginx/sbin
# 启动 ( 出现权限问题,可以加上 sudo
./nginx # sudo ./nginx
# 停止
./nginx -s stop
# 安全退出
./nginx -s quit
# 重新加载配置文件
./nginx -s reload
# 查看Nginx进程
ps aux | grep nginx
Nginx 的配置文件所在的地址为:/usr/local/nginx/conf
,在配置文件中我们可以修改Nginx的一些配置( 默认的端口号,进程数量,可保持的连接数量。。。等等
参考菜鸟教程
Nginx的配置文件分为三部分:
一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等
每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等
如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等
server 块的配置
配置http服务的反向代理
首先,在配置文件中,配置反向代理的服务器地址,并设置权重,加上一个备用的服务器。
我们预期的结果,就是客户端第一次访问的时候,先访问第一个服务器19998
端口,第2,3次访问19999
端口的服务器,然后第4次再访问第一个服务器。。。依次轮回
服务器使用
socket
套接字建立,可以参考之前的博客
TCP协议的通信小程序与函数接口
http协议简单实现使用ip访问html网页的demo
备用服务器的访问中,只要还存在其他服务器没有宕机,那么备用服务器是不会启动的
最后,可以看到Nginx中加权服务器的分配和我们预期的结果不太一样,他是考虑到了一个这样的问题:如果后端服务器的权重为1:2:3
,那么我们普通的轮询分配方式为ABBCCC
,但是如果是CCBACB
这样来分配,是不是会更好一点,避免了一个服务器连续处理多个请求的情况
Nginx 的轮询调度机制
对于每一个后端服务器,他的默认值为0
模拟加权轮询的过程,他权重为 A : B : C = 1 : 2 : 3 A:B:C = 1 : 2 : 3 A:B:C=1:2:3,初始的值为 0 : 0 : 0 0:0:0 0:0:0
轮次 | 当前的值 | 选择的服务器 | 选择之后的值 |
---|---|---|---|
1 | 1 2 3 | C | 1 2 -3 |
2 | 2 4 0 | B | 2 -2 0 |
3 | 3 0 3 | A | -3 0 3 |
4 | -2 2 6 | C | -2 2 0 |
5 | -1 4 3 | B | -1 -2 3 |
6 | 0 0 6 | C | 0 0 0 |
很巧妙的,经过一轮之后,所有服务器的值都变为了0,和初值相同