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网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx 是一个很强大的高性能 Web 和反向代理服务,它具有很多非常优越的特性:
在连接高并发的情况下,Nginx 是 Apache 服务不错的替代品:Nginx 在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型。
局域网要访问 Internet,要通过代理服务器。
负载均衡,英文名称为 Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如 FTP 服务器、Web 服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。
负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
用户向服务器发送多个请求,通过 Nginx 服务器负载均衡进行平衡、分摊到多个服务器上。增加服务器的数量,然后将请求分发到各个服务器上,将原先集中到单个服务器上的请求分发到多个服务器上,将负载分发到不同的服务器。
动静分离是指在 web 服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。
为了加快网站的解析速度,可以把动态页面的静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
《CentOS 下 Nginx 安装与配置》
[root@localhost ~]# cd /usr/local/nginx/
# 查看版本号。
[root@localhost nginx]# ./nginx -v
nginx version: nginx/1.12.2
# 启动 Nginx。
[root@localhost nginx]# ./nginx
# 关闭 Nginx。
[root@localhost nginx]# ./nginx -s stop
# 重新加载 Nginx。
[root@localhost nginx]# ./nginx -s reload
[root@localhost nginx]# ps -ef | grep 80
/usr/local/nginx/
nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
^ --> events 块。之间。
主要设置影响 Nginx 服务器整体运行的配置指令。
主要包括 Nginx 服务器的用户(组),允许生成的
worker_processes
数,进程PID
存放路径,日志存放路径和类型以及配置文件的引入等。
worker_processes 1; # nginx 处理并发数。
// 设置值和 CPU 核心数一致。
events 涉及的指令主要影响 Nginx 服务器与用户的网络连接。
events {
worker_connections 1024;
}
// 最大连接数。
http 全局块。
文件引入、MIME-TYPE、日志自定义、连接超时时间。
server 块。
这块和虚拟主机有密切关系。虚拟主机从用户的角度看,和一台独立的硬件主机一样,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包含多个 server 块,每个 server 块就相当于一个虚拟主机。
每个 server 块也分为
全局 server 块。
多个 location 块。
[root@localhost ~]# cd /usr/local/nginx/
# 查看版本号。
[root@localhost nginx]# ./nginx -v
nginx version: nginx/1.12.2
# 启动 Nginx。
[root@localhost nginx]# ./nginx
# 关闭 Nginx。
[root@localhost nginx]# ./nginx -s stop
# 重新加载 Nginx。
[root@localhost nginx]# ./nginx -s reload
[root@localhost nginx]# ps -ef | grep 80
在浏览器地址栏输入地址 www.123.com(192.168.223.128),跳转 Linux 系统 tomcat 主页面。
Linux 系统安装 Tomcat。
# 查看 Tomcat 日志。
tail -f catalina.out
# 对外开放端口。
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
# 查看已经开放的端口号。
firewall-cmd --list-all
浏览器 www.123.com(hosts 文件进行配置。配置域名映射的 ip 地址)。
↓
Nginx http://192.168.223.128:80/
↓
Tomcat 127.0.0.1:8080
geek@geek-PC:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 geek-PC
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.223.128 www.123.com
在 Nginx 进行请求转发的配置。(反向代理配置)。
34 server {
35 listen 80;
36 # #server_name localhost;
37 server_name 192.168.223.128;
38
39 #charset koi8-r;
40
41 #access_log logs/host.access.log main;
42
43 location / {
44 root html;
45
46 proxy_pass http://127.0.0.1:8080;
47
48 index index.html index.htm;
49 }
通过访问 http://192.168.223.128 转发到 http://127.0.0.1:8080。
http://127.0.0.1 就是 192.168.223.128 的本机地址。
使用 Nginx 反向代理,根据访问的路径跳转到不同端口的服务中。
Nginx 监听端口为 9001。
访问 http://192.168.223.128:9001/edu,直接跳转到 127.0.0.1:8080
访问 http://192.168.223.128:9001/vod,直接跳转到 127.0.0.1:8081
准备两个 Tomcat(8080 和 8081)。
# another virtual host using mix of IP-, name-, and port-based configuration
#
server {
listen 9001;
# listen somename:8080;
server_name 192.168.223.128;
# ~。——> 正则。
location ~ /edu/ {
# root html;
#index index.html index.htm;
proxy_pass http://localhost:8080;
}
location ~ /vod/ {
proxy_pass http://localhost:8081;
}
}
nginx: [emerg] “proxy_pass” cannot have URI part in location given by regular expression, or inside named location, or inside “if” statement, or inside “limit_except” block in /usr/local/nginx/nginx.conf:91
开放端口号。&& 重启 Nginx。
[root@localhost nginx]# firewall-cmd --add-port=9001/tcp --permanent
Warning: ALREADY_ENABLED: 9001:tcp
success
[root@localhost nginx]# firewall-cmd --reload
[root@localhost nginx]# ./nginx -s stop
[root@localhost nginx]# ./nginx
访问 http://192.168.223.128:9001/edu/a.html 和 http://192.168.223.128:9001/vod/a.html
- =。用于不含正则表达式的 url 前。
- ~。用于表示 url 包含正则表达式,并且区分大小写。
- ~*。用于表示 url 包含正则表达式,不区分大小写。
- ^~。用于不含正则表达式的 url 前。要求 Nginx 服务器找到标识 url 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 url 和请求字符串作匹配。
浏览器地址栏输入:http://192.168.223.128/edu/a.html,负载均衡效果,平均 8080 和 8081 端口中。
准备两个 Tomcat(8080 和 8081)。
http {
# 在 http 块中添加 `upstream + 服务名 { 服务器列表 }`。
upstream myserver {
ip_hash;
server 192.168.223.128:8080;
server 192.168.223.128:8081;
}
include mime.types;
server {
listen 80;
# #server_name localhost;
server_name 192.168.223.128;
location / {
root html;
proxy_pass http://myserver;
#proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
http://192.168.223.128/edu/a.html
两个 Tomcat 中都是 /webapps/edu/a.html。
分配策略。
- 轮询。(默认)。
每个请求按时间顺序逐一分配到不同的后端服务器。如果后端服务器 down 掉,能自动剔除。
- weight。
weight 代表权重,默认为 1。权重越高被分配的客户端越多。
指定轮询机率。weight 和访问率成正比,用于后端服务器性能不均情况。
ip_hash。
每个请求按照访问 ip 的 hash 结果分配。这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
fair。(第三方)。
按后端服务器响应时间来分配请求,响应时间短的优先分配。
http {
# 在 http 块中添加 `upstream + 服务名 { 服务器列表 }`。
upstream myserver {
# ip_hash;
server 192.168.223.128:8080 weight=1;
server 192.168.223.128:8081 weight=2;
fair;
}
include mime.types;
Nginx 动静分离简单来说就是把动态请求和静态请求分离开来。不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求和静态请求分开。可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。
动静分离从目前实现技术来讲分为两种。
纯粹把静态文件独立成单独的域名,放在独立的服务器上。(目前主流推崇的方案)。
动态和静态一起发布,通过 Nginx 来分开。
通过 location 指定不同的后缀名实现不同的请求转发;通过 expires 参数设置,可以使用浏览器缓存过期时间,减少与服务器之间的请求与流量。
具体 expires 定义。
给一个资源设定一个过期时间,也就是说无需去服务器验证,直接通过浏览器自身确认是否过期即可。所以不会产生额外的流量。此方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 expires 来缓存)。
如果设置 3d,表示在 3 天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间是没有变化,则不会从服务器抓取,返回状态码 304。如果有变化,则直接从服务器重新下载,返回状态码 200。
server{
location /www/ {
root /tmp/nginx_demo/;
index index.html index.htm;
}
location /img/ {
root /tmp/nginx_demo/;
autoindex on; # 列出访问目录。
}
}
# /tmp/nginx_demo
# /root/geek/nginx_demo/img
# /root/geek/nginx_demo/www
http://192.168.223.128/www/a.html
http://192.168.223.128/img/ # 必须加 /。
yum install keepalived
systemctl start keepalived.service
/etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
}
virtual_server 192.168.200.100 443 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.201.100 443 {
weight 1
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
virtual_server 10.10.10.2 1358 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
sorry_server 192.168.200.200 1358
real_server 192.168.200.2 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.200.3 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
virtual_server 10.10.10.3 1358 {
delay_loop 3
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.200.4 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.200.5 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
两个进程:master & worker。
master 发布任务,workers “争抢”任务。
[root@localhost ~]# ps -ef | grep nginx
root 89864 1 0 04:52 ? 00:00:00 nginx: master process ./nginx
nobody 89865 89864 0 04:52 ? 00:00:00 nginx: worker process
root 92392 76158 0 05:42 pts/0 00:00:00 grep --color=auto nginx
- 可以使用 nginx -s reload 热部署。
第一个 worker 正在执行一个任务,这时如果修改了配置,使用 nginx -s reload 热部署,第一个 worker 还是执行原先的任务。而其他的 workers 应用了新的配置去执行之后的任务。——> 实现了热部署。
- 每个 worker 是一个独立进程,不需要加锁。
Nginx 同 Redis 类似采用了 io 多路复用机制(在 Windows 下运行没有该机制),每个 worker 都是一个独立的进程,但每个进程只有一个主线程,通过异步非阻塞的方式来处理请求,即使是成千上万个请求也不在话下。每个 worker 的线程可以把一个 CPU 的行性能发挥到极致。所以 worker 数和服务器的 CPU 数相等是最为重要的。设少了会浪费 CPU,设多了会造成 CPU 频繁切换上下文带来损耗。
表示每个 worker 进程所能建立连接的最大值。
所以,一个 Nginx 能建立的最大连接数,应该是 worker_ connections * worker_processes。
这里所说的最大连接数,对于 HTTP 请求来说,是 worker_ connections * worker_processes。而 HTTP 1.1,每次访问要占 2 个连接,所以普通的静态访问最大并发数是:worker_ connections * worker_processes / 2。而如果是 HTTP 1.1 作为反向代理来说,最大并发数应该是 worker_ connections * worker_processes / 4。因为作为反向代理的服务器,每个并发会建立与客户端的连接和与后端服务器的连接,会占用 4 个连接。
发送请求,占用了 worker 的几个连接数?
2 或 4 个。
如果静态资源 —> 2 个(请求 + 响应)。
如果还需要访问 Tomcat 去数据库增删改查,4 个。(如图所示)。