一、什么是Nginx?

      Nginx是一个使用c语言开发的高性能的http服务器及反向代理服务器。Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。

为什么使用Nginx?

      在传统的Web项目中,并发量小,用户使用的少。所以在低并发的情况下,用户可以直接访问tomcat服务器,然后tomcat服务器返回消息给用户。比如,我们上传图片:

nginx切图 nginx做图片服务器原理_Nginx


      当然我们知道,为了解决并发,可以使用负载均衡:也就是我们多增加几个tomcat服务器。当用户访问的时候,请求可以提交到空闲的tomcat服务器上。

nginx切图 nginx做图片服务器原理_服务器_02

      但是这种情况下可能会有一种这样的问题:上传图片操作。我们把图片上传到了tomcat1上了,当我们要访问这个图片的时候,tomcat1正好在工作,所以访问的请求就交给其他的tomcat操作,而tomcat之间的数据没有进行同步,所以就发生了我们要请求的图片找不到。

      为了解决这种情况,我们就想出了分布式。我们专门建立一个图片服务器,用来存储图片。这样当我们都把图片上传的时候,不管是哪个服务器接收到图片,都把图片上传到图片服务器。

      图片服务器上需要安装一个http服务器,可以使用tomcat、apache、nginx。

nginx切图 nginx做图片服务器原理_nginx_03

      看到这里大家可能会问,既然我们要选择的是http服务器,为什么不继续使用tomcat,而要使用Nginx?

      原因如下:nginx常用做静态内容服务和代理服务器,直面外来请求转发给后面的应用服务(tomcat,django什么的),tomcat更多用来做做一个应用容器,让java web app跑在里面的东西,对应同级别的有jboss,jetty等东西。

 

 Nginx的应用场景

      1、 http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。

      2、 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。

      3、 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

二、安装

2.1 环境要求

  •     Centos 7
  •     nginx-1.15.5.tar.gz

2.2 先安装nginx依赖的包

      nginx是C语言开发,建议在linux上运行,本教程使用Centos7作为安装环境。

  •     gcc

      安装nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:

yum install gcc-c++
  •       PCRE

      PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre库。

yum install -y pcre pcre-devel

     注:pcre-devel是使用pcre开发的一个二次开发库。nginx也需要此库。

  •     zlib

      zlib库提供了很多种压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库。

yum install -y zlib zlib-devel
  •        openssl

      OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
      nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux安装openssl库。

yum install -y openssl openssl-devel

2.3 把nginx的源码上传到linux系统,并解压

      这一步可以使用软件,也可以用代码的方式。这里小编使用crt,直接把windows上的nginx-1.15.5.tar.gz包拷贝到“/usr/local/src”下。然后解压。

tar -zxvf nginx-1.15.5.tar.gz

2.4 安装

      解压后,会产生nginx-1.15.5的文件夹,进入后

cd nginx-1.15.5

在默认情况下,经过编译安装的Nginx包含了大部分可用模块。可以通过“./configure  --help”选项设置各个模块的使用情况,例如对不需要的http_ssi模块,可通过“--without-http_ssi_module”方式关闭此模块;同理,如果需要“http_perl”模块,那么可以通过“--with-http_perl_module”方式安装此模块

运行configure:

./configure --prefix=/usr/local/nginx

然后执行编译

make

     安装

make install

查找安装路径:

whereis nginx

 2.5 Nginx的启动、停止

      1、启动、停止nginx

cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop
./nginx -s quit
./nginx -s reload

./nginx -s quit:此方式停止步骤是待nginx进程处理任务完毕进行停止。
./nginx -s stop:此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查询nginx进程:

ps aux|grep nginx

重启 nginx

1.先停止再启动(推荐):
对 nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。如下:

./nginx -s quit
./nginx

2.重新加载配置文件:
当 ngin x的配置文件 nginx.conf 修改后,要想让配置生效需要重启 nginx,使用-s reload不用先停止 ngin x再启动 nginx 即可将配置信息在 nginx 中生效,如下:
./nginx -s reload

启动成功后,在浏览器可以看到这样的页面:

nginx切图 nginx做图片服务器原理_nginx_04

如果不能正常访问注意linux防火墙有没有配置,下面是CentOs7关闭防火墙的命令:

1:查看防火状态

systemctl status firewalld

2:暂时关闭防火墙

systemctl stop firewalld

3:永久关闭防火墙

systemctl disable firewalld

4:重启防火墙

systemctl enable firewalld

3.开机自启动

即在rc.local增加启动代码就可以了。

vi /etc/rc.local

增加一行 /usr/local/nginx/sbin/nginx 设置执行权限:

chmod 755 rc.local

三、Nginx的配置

      在/usr/local/nginx/conf目录下nginx.conf文件是nginx的配置文件。

#开启进程数 <=CPU数
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 {
#每个进程最大连接数(最大连接=连接数x进程数) 
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压缩
#gzip on;
#设定请求缓冲
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
#设定负载均衡的服务器列表
upstream myproject { 
#weigth参数表示权值,权值越高被分配到的几率越大
#max_fails 当有#max_fails个请求失败,就表示后端的服务器不可用,默认为1,将其设置为0可以关闭检查
#fail_timeout 在以后的#fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器
#这里指定多个源服务器,ip:端口,80端口的话可写可不写 
server 192.168.1.78:8080 weight=5 max_fails=2 fail_timeout=600s;
#server 192.168.1.222:8080 weight=3 max_fails=2 fail_timeout=600s; 
}
#第一个虚拟主机
server {
#监听IP端口
listen 80;
#主机名 网站域名
server_name localhost;
#设置字符集
#charset koi8-r;
#本虚拟server的访问日志 相当于局部变量
#access_log logs/host.access.log main; 
#对本server"/"启用负载均衡
location / { 
#root /root; #定义服务器的默认网站根目录位置
#index index.php index.html index.htm; #定义首页索引文件的名称
proxy_pass http://myproject; #请求转向myproject定义的服务器列表
#以下是一些反向代理的配置可删除.
# proxy_redirect off; 
# proxy_set_header Host $host; 
# proxy_set_header X-Real-IP $remote_addr; 
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
# client_max_body_size 10m; #允许客户端请求的最大单文件字节数 
# client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, 
# proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) 
# proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) 
# proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) 
# proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 
# proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 
# proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) 
# proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
} 
location /upload { 
alias e:/upload; 
}
#设定查看Nginx状态的地址 
location /NginxStatus { 
stub_status on; 
access_log off; 
#allow 192.168.0.3;
#deny all;
#auth_basic "NginxStatus"; 
#auth_basic_user_file conf/htpasswd; 
}
#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 / {
# WEB文件路径,其中html为文件路径名称
# root html;
#默认首页
# index index.html index.htm;
# }
#}
# HTTPS server HTTPS SSL加密服务器
#
#server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#} 
}

 

3.1 通过端口区分虚拟机

      在nginx.conf文件中添加一个Service节点,修改端口号就可以

server {
        listen       81;
        server_name  localhost;

        location / {
            root   html81;
            index  index.html index.htm;
        }
   }

说明:

server 配置一个网站

listen 监听端口

server_name 网站域名

root 网站绝对地址,后面记得带斜杠

index 指定网站首页

 

3.2 Nginx部署多个网站

为节省资源,通常一个服务器会运行多个网站,比如www.siteA.com作为博客,www.siteB.com作为论坛.通常一个服务一个IP,多个域名共用一个IP,多个域名共用一个端口(通常是80端口)。这时候需要一台服务器部署多个网站,多个网站共用一个IP,共用一个80端口

  需要修改nginx.conf配置文件,修改配置后需要重新加载配置文件:  

server {
    listen       80;                        # 监听端口
    server_name www.siteA.com siteA.com;    # 站点域名
    
 
    location / {
        root  /home/user/www/blog;              # 站点根目录
        index index.html index.htm index.php;   # 默认导航页
    }
 
}
server {
        listen       80;
        server_name  comwww.siteB.com siteB.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /home/user/www/forum;
            index  index.html index.htm;
        }
   }

现在访问www.siteA.com和www.siteB.com,你将发现浏览器会打开不同的站点

3.3访问Nginx跳转到tomcat

我们就修改了上面两个地方,我的tomcat在8080端口,可以根据自己的需要修改。这里有一个新元素proxy_pass,它表示代理路径,相当于转发,而不像之前说的root必须指定一个文件夹

server {
        listen       80;
        server_name localhost:8080 
      
        location / {  
            proxy_pass http://localhost:8080;
        }
}

重新加载配置文件

./nginx -s reload

nginx切图 nginx做图片服务器原理_nginx_05

关于nginx静态资源分离部署自行参考

四、负载均衡

      首先我们得知道什么是负载均衡。

      负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

      负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

    负载均衡的核心是:将负载进行平衡

      对于Nginx来说,他可以把提交的请求进行转发。架构如下:

nginx切图 nginx做图片服务器原理_nginx切图_06

      架构图解释:在这个图中,用户提交请求先到Nginx服务器,然后由Nginx进行对这些请求的转发,转发到各个tomcat服务器上,然后tomcat进行逻辑处理。

Nginx内置的负载均衡策略有3种:轮询,加权轮询,IP hash。同时支持扩展策略,完全可以自己写一套规则交给Nginx去执行。

(1)轮询

nginx切图 nginx做图片服务器原理_nginx切图_07


这种策略简单易行,将请求平均的分配给每个服务器去处理。如果应用服务器down掉,自动剔除,剩下的继续轮询。 

实现方式:

upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}

(2)加权轮询

nginx切图 nginx做图片服务器原理_服务器_08

    而Nginx是如何做的呢?首先Nginx中写入了各个tomcat的服务器的地址,架构师可以根据tomcat的性能,增加对其使用的程度。Nginx只需在nginx.conf中进行配置:

#配置多台服务器(这里只在一台服务器上的不同端口)
#权重比设置为1  : 3  意思为  用户请求四次服务器,平均访问8082端口3次,8081端口一次,以此达到服务器均衡的作用(高并发)
     upstream local_tomcat {
   server localhost:8080 weight=1;
      server localhost:8090 weight=3;  #热备
    }

Nginx的具体配置

在server外添加一个upstream,在proxy_pass里面直接用http://+upstream的名称来使用。upstream中的server元素必须要注意,不能加http://,但proxy_pass中必须加

upstream local_tomcat {
   server localhost:8080 weight=1;
      server localhost:8090 weight=3;  #热备
    }
    server {
        listen       80;
        server_name  localhost;//或者外网域名 tom.com,www.tom.com

        location / {
            proxy_pass http://local_tomcat; 
        }

       
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

 Nginx根据proxy_pass来访问的路径来确定访问的server,根据权重自动分配选择的哪一个。权重大的处理的概率高。

(3)IP hash

nginx切图 nginx做图片服务器原理_服务器_09


对客户端请求的IP进行hash操作,然后根据hash结果将同一个客户端IP的请求分发给同一台服务器进行处理,可以解决session不共享的问题。 

代码实现

upstream backserver {
ip_hash;
server 192.168.0.14:88;//注意这里在部署到服务器时一定要用内网IP,外网IP会出现打开页面提示下载的情况
server 192.168.0.15:80;
}

2、nginx其他配置

upstream myServer {    
  
    server 192.168.72.49:9090 down;   
    server 192.168.72.49:8080 weight=2;   
    server 192.168.72.49:6060;   
    server 192.168.72.49:7070 backup;   
}

1)down

    表示单前的server暂时不参与负载

2)Weight

    默认为1.weight越大,负载的权重就越大。

3)max_fails

    允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误

4)fail_timeout

    max_fails 次失败后,暂停的时间。

5)Backup

    其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

3、使用Nginx的高可用 

      除了要实现网站的高可用,也就是提供n多台服务器用于发布相同的服务,添加负载均衡服务器分发请求以保证在高并发下各台服务器能相对饱和的处理请求。同样,负载均衡服务器也需要高可用,以防如果负载均衡服务器挂掉了,后面的应用服务器也紊乱无法工作。

     实现高可用的方案:添加冗余。添加n台nginx服务器以避免发生上述单点故障。具体方案详见下文:keepalive+nginx实现负载均衡高可用