jinhy的技术分享中间件java高级

Nginx入门指南

2018-05-09  本文已影响45人  _Away_y

背景

Nginx一直就比较想去学习了解,最开始是之前搭梯子的时候听说过通过Nginx反向代理访问Google,后来的话项目中也开始用起了Nginx来做负载均衡。但是自己一直拖延着没有去学,这次知识地图认定觉得想把它考过,顺便督促自己把这个东西弄明白。

关于本文的内容及顺序

最开始我理所当然的去看Nginx的官网或者资料,里面介绍他是Web服务器,可是我对这个感觉没什么概念,因为我知道Tomcat就是服务器啊,那有什么区别呢?我们平常开发的时候经常用的不就是Tomcat么,为啥没用Nginx;而且负载均衡为啥要用Nginx;当然还有反向代理。因为疑问太多了,所以这篇文章不会立即进入主题,而是一步步额抠概念,最终达成使用并理解Nginx的目的。

引子一 Web服务器

什么是服务器(server)?

一般来说,server有两重意思

  1. 有时候server标识硬件,即一台机器。它还有另一个名字:「主机」。
  2. 更多的时候,server表示软件程序,这种程序主要用来对外提供某些些服务,比如邮件服务、FTP服务、数据库服务、网页服务等。

作为开发者,我们说server的时候,一般指的后者,也就是一个24小时运行的软件程序。而一台主机上面可以运行多个这个服务,一个服务也可以运行在多个主机上。

什么是Web Server?

顾名思义,Web Server就是提供Web服务的Server。

比如我们访问http://www.baidu.com,其实就是在使用百度的Server提供的服务。

一般来说,Web Server对外提供HTTP服务(也可以是其他的服务)。

如何提供HTTP服务?

下面是用Node.js写的一个最简单的HTTP Server

var http = require('http')
var server = http.createServer(function(request,response){
    response.end('这是页面内容,你请求的路径是:' + request.url)
})
server.listen(8080,function(){
    console.log("正在监听 %s 端口", 8080);
})

你不用看懂这段代码,你只需要知道两件事:

  1. 这段程序监听了当前机器的8080端口
  2. 一旦外部访问当前机器的8080端口,这段程序就会返回一段文字。

这就是一个最简单的HTTP Server。

引子二 Web服务器与应用服务器的区别

在大多数时候,Web服务器和应用服务器这两个术语是可以互换使用的。

以下是Web服务器和应用服务器在特性上的一些关键的差异:

Web服务器包括Nginx、Apache、IIS等。

应用服务器包括WebLogic、JBoss、Tomcat等。

引子三 正向代理和反向代理

正向代理

A同学想要创业但是缺少资金,所以决定向马云爸爸借钱,可是没能成功。通过打探了一番消息,原来A同学的大学老师王老师是马云的同学,于是A同学请求王老师帮忙向马云借款。最后终于成功了马云把钱借给了王老师,并由王老师把钱交到了A同学手上。

在上面是故事中,王老师扮演了一个非常关键的角色,即代理,也可以说是正向代理。王老师代替A同学办这件事,这个过程中真正借钱的人是谁,马云是不知道的,这点非常关键。

我们常说的代理也就是指正向代理。在正向代理的过程中,它隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求。

某些科学上网工具扮演的就是典型的正向代理角色。用浏览器访问http://www.google.com是时,被残忍的block,于是你可以在国外搭建一台代理服务器,让代理帮我去请求google.com,代理把请求返回的相应结构返回给我。

正向代理

反向代理

大家都有过这样的经历吧,拨打10086的客服电话,一个地区的客服有几个或者几十个,你永远不会关心电话另一头的客服到底是哪一个,你关心的只是问题能不能得到专业的解答,而你总能得到解答。这里的10086总机号码就是我们说的反向代理。客户不知道真正提供服务的人是谁。

反向代理隐藏了真实的服务端,当我们请求http://wwww.baidu.com的时候,就像拨打10086一样,背后可能有成千上万台服务器为我们服务,但是具体是哪一台,你并不需要知道,你只需要知道反向代理服务器是谁就好了,http://www.baidu.com就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真是的服务器那里去。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

反向代理

总结

两者的区别在于代理的对象不一样

模型如下:

模型

又看到一个比较全面的图,也贴上吧。。。

正向代理和反向代理

什么是Nginx?

Nginx是俄罗斯人Igor Sysoev编写的十分轻量级的HTTP服务器(Web服务器)。它是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP代理服务器。

Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载均衡。其拥有匹配Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题。

Nginx因为它的稳定性、丰富的模块库、灵活的配置和低系统资源的消耗而闻名。对proxy和rewrite模块支持的很彻底,还支持mod_fcgi、ssl、vhosts,适合用来做mongrel clusters的前端HTTP响应。

Nginx入门

安装

nginx的发布版本分为Linuxwindods版本。

也可以下载源码,编译后运行。

从源代码编译Nginx

把源码解压缩之后,在终端里运行如下命令:

$ ./configure
$ make
$ sudo make install

默认情况下,Nginx会被安装在/usr/local/nginx。通过设定编译选项可以改变这个设定。

Window安装

下载解压后,到其目录下打开命令行直接执行start nginx即可。(不要直接双击启动,会失去控制)

命令

命令 作用
nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。
nginx -s reopen 重新打开日志文件。
nginx -c filename 为Nginx指定一个配置文件来代替缺省的。
nginx -t 不运行,测试配置文件。
nginx -v 显示nginx的版本。
nginx -V 显示nginx的版本,编译器版本和配置参数。

配置说明

通过以下各种具体配置来总结归纳。

反向代理

#运行用户
#user somebody;

#启动进程,通常设置成和cpu的数量相等
worker_processes  1;

#全局错误日志
error_log  D:/Tools/nginx-1.10.1/logs/error.log;
error_log  D:/Tools/nginx-1.10.1/logs/notice.log  notice;
error_log  D:/Tools/nginx-1.10.1/logs/info.log  info;

#PID文件,记录当前启动的nginx的进程ID
pid        D:/Tools/nginx-1.10.1/logs/nginx.pid;

#工作模式及连接数上限
events {
    worker_connections 1024;    #单个后台worker process进程的最大并发链接数
}

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
    #设定mime类型(邮件支持类型),类型由mime.types文件定义
    include       D:/Tools/nginx-1.10.1/conf/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    D:/Tools/nginx-1.10.1/logs/access.log main;
    rewrite_log     on;
    
    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
    #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime.
    sendfile        on;
    #tcp_nopush     on;

    #连接超时时间
    keepalive_timeout  120;
    tcp_nodelay        on;
    
    #gzip压缩开关
    #gzip  on;
 
    #设定实际的服务器列表 
    upstream zp_server1{
        server 127.0.0.1:8089;
    }

    #HTTP服务器
    server {
        #监听80端口,80端口是知名端口号,用于HTTP协议
        listen       80;
        
        #定义使用www.xx.com访问
        server_name  www.helloworld.com;
        
        #首页
        index index.html
        
        #指向webapp的目录
        root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;
        
        #编码格式
        charset utf-8;
        
        #代理配置参数
        proxy_connect_timeout 180;
        proxy_send_timeout 180;
        proxy_read_timeout 180;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarder-For $remote_addr;

        #反向代理的路径(和upstream绑定),location 后面设置映射的路径
        location / {
            proxy_pass http://zp_server1;
        } 

        #静态文件,nginx自己处理
        location ~ ^/(images|javascript|js|css|flash|media|static)/ {
            root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
            #过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
            expires 30d;
        }
    
        #设定查看Nginx状态的地址
        location /NginxStatus {
            stub_status           on;
            access_log            on;
            auth_basic            "NginxStatus";
            auth_basic_user_file  conf/htpasswd;
        }
    
        #禁止访问 .htxxx 文件
        location ~ /\.ht {
            deny all;
        }
        
        #错误处理页面(可选择性配置)
        #error_page   404              /404.html;
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}
    }
}

需要注意的如果想要使用域名www.helloworld.com需要在C:\Windows\System32\drivers\etc\host中添加一条DNS记录,如下

127.0.0.1 www.helloworld.com

当然也可以不用上面配的域名访问,可以使用IP |localhost访问。

负载均衡

http {
    #设定mime类型,类型由mime.type文件定义
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #设定日志格式
    access_log    /var/log/nginx/access.log;

    #设定负载均衡的服务器列表
    upstream load_balance_server {
        #weigth参数表示权值,权值越高被分配到的几率越大
        server 192.168.1.11:80   weight=5;
        server 192.168.1.12:80   weight=1;
        server 192.168.1.13:80   weight=6;
    }

   #HTTP服务器
   server {
        #侦听80端口
        listen       80;
        
        #定义使用www.xx.com访问
        server_name  www.helloworld.com;

        #对所有请求进行负载均衡请求
        location / {
            root        /root;                 #定义服务器的默认网站根目录位置
            index       index.html index.htm;  #定义首页索引文件的名称
            proxy_pass  http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表

            #以下是一些反向代理的配置(可选择性配置)
            #proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $remote_addr;
            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服务器传
            
            client_max_body_size 10m;          #允许客户端请求的最大单文件字节数
            client_body_buffer_size 128k;      #缓冲区代理缓冲用户端请求的最大字节数
        }
    }
}

多个webapp的配置

http {
    #此处省略一些基本配置
    
    upstream product_server{
        server www.helloworld.com:8081;
    }
    
    upstream admin_server{
        server www.helloworld.com:8082;
    }
    
    upstream finance_server{
        server www.helloworld.com:8083;
    }

    server {
        #此处省略一些基本配置
        #默认指向product的server
        location / {
            proxy_pass http://product_server;
        }

        location /product/{
            proxy_pass http://product_server;
        }

        location /admin/ {
            proxy_pass http://admin_server;
        }
        
        location /finance/ {
            proxy_pass http://finance_server;
        }
    }
}

静态站点

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    gzip on;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
    gzip_vary on;

    server {
        listen       80;
        server_name  static.zp.cn;

        location / {
            root /app/dist;
            index index.html;
            #转发任何请求到 index.html
        }
    }
}

基础知识

location相关

格式
  1. location [ = | ~ | ~* | ^~ ] uri { ... }
  2. location @name { ... }

即有两种配置方案:

  1. 前缀 + uri (字符串/正则表达式)
  2. @ + name

前缀的含义:

基础知识

参考资料

上一篇下一篇

猜你喜欢

热点阅读