了解Nginx

1. 安装Nginx

版本 nginx-1.14.0

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

# 安装C++编译器yum -y install gcc-c++# 下载并安装OpenSSLopenssl-fips-2.0.16.tar.gztar -zxf openssl-fips-2.0.16.tar.gzcd openssl-fips-2.0.16./config && make && make install# 下载并安装pcrepcre-8.42.tar.gtar -zxf pcre-8.42.tar.gcd pcre-8.42./configure && make && make install# 下载并安装zlibzlib-1.2.11.tar.gztar -zxf zlib-1.2.11.tar.gzcd zlib-1.2.11./configure && make && make install# 下载并安装Nginxnginx-1.14.0.tar.gztar -zxf nginx-1.14.0.tar.gzcd nginx-1.14.0./configure && make && make install

2. 快速开始

nginx有一个master进程和多个worker进程。

master进程主要负责读取和评估配置,并维护worker进程。

worker进程负责实际的请求处理。worker进程的数量在配置文件中定义,可以指定一个固定值,也可以根据可用CPU内核的数量自动调整。

nginx及其模块的工作方式由配置文件决定。默认情况下,配置文件的名字叫nginx.conf,并且所在位置是/usr/local/nginx/conf, /etc/nginx, 或 /usr/local/etc/nginx

2.1. 启动/停止/重新加载配置

为了启动nginx,运行可执行文件nginx。一旦nginx启动以后,就可以通过 -s 参数来控制它。

用下面的语法格式:

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

例如,为了停止nginx进程,并且等待worker进程完成当前请求的处理,可以执行下面的命令:

nginx -squit

(画外音:执行这个命令的用户必须与启动nginx的用户相同)

为了重新加载配置,执行下面的命令:

nginx -s reload

一旦master进程收到重新加载配置的信号以后,它检查配置文件的语法,并尝试应用配置文件中提供的配置。如果成功的话,master进程会启动一个新的worker进程并且发送消息给旧的worker进程请求它们立即shut down。否则,master进程回滚本次更改,继续用旧的配置工作。当旧的worker进程收到一个shut down的命令时,它停止接受新的连接,并继续服务当前请求,直到它收到的所有请求都处理完成。此后,旧的worker进程就退出了。

在Unix工具的帮助下(比如 kill)也可以向nginx进程发送信号。在这种情况下,信号直接被发送到给定的进程ID所代表的进程。默认情况下,nginx master进程的进程ID被写入nginx.pid文件中,该文件所在目录通常是/usr/local/nginx/logs 或 /var/run。例如,如果master进程ID是1628,那么为了发送QUIT信号给nginx,执行下面的命令:

kill-sQUIT1628

为了获取所有正在运行的nginx进程列表,可以使用ps命令,例如:

ps-ax |grepnginx

2.2. 配置文件的结构

nginx由配置文件中的指令所控制的模块组成。指令分为简单指令和块指令。简单指令由名称和参数组成,它们之间用空格隔开,以分号(;)结束。块指令的结构与简单指令相同,但它不是以分号结尾,而是一组由大括号({ 和 })包围的附加指令。如果一个block指令可以在大括号中包含其他指令,那么它被成为上下文(例如:events, http, server 和 location)。events 和 http 指令在main上下文下,server指令在http中,location在server中。

默认的配置文件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,ifApache'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 somenamealiasanother.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; # } #}}

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

2.3. 服务静态内容

Web服务器其中一个重要的任务是提供文件(比如,图片和静态HTML页面)。

首先,让我们来创建/data/html目录,并在其中放一个index.html文件。同时再建一个/data/images目录用于放置图片。

接下来,打开配置文件,在默认的配置文件中server块下已经包含了一些例子,通常它们是被注释了的。

以/images/开头的请求,服务器将从/data/images目录下查找并返回文件。

例如:http://192.168.101.5/images/a.png请求,服务器将返回/data/images/a.png文件,如果这个文件不存在,则返回404。

不是以/images/开头的的请求将映射到/data/html目录。

http://192.168.101.5/

http://192.168.101.5/index.html

http://192.168.101.5/example.html

root指令:

2.4. 简单的代理服务器

首先,通过在配置文件中提那家一个或多个server块来定义代理服务器

上面的例子中定义了一个简单服务器,它监听8080端口,并且把所有请求映射到本地/data/up1目录。注意,这里root指令放在了server上下文。当一个请求不包含location它在自己的root指令中,则会使用这个server上下文中的root指令。(画外音:简单的来说,location指令中的root相当于局部变量,而server指令下的root相当于全局变量,当请求不匹配局部变量时,则使用全局变量。类比Java就是一个是自定义的方法,一个是默认实现的方法)

接下来,修改前面的配置。我们在第一个location块中放置proxy_pass指令

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

参数是一个匹配所有以.gif, .jpg, 或者.png结尾的URIs的正则表达式。与之相应的,请求被映射到/ata/images目录。

location指令的参数是正则表达式

在正则表达式前面应该加上~

当nginx选择一个location块来服务一个请求时,它首先检查location指令所指定的前缀,记住最长的前缀的那个location,然后检查正则表达式。如果匹配正则表达式,则挑选这个location,否则挑选他所记住的更早的那个。

(画外音:这段话解释了nginx是如何挑选location的,我们可以这样理解,通过location指令所指定的前缀,从最长的前缀开始匹配,如果满足,则挑选这个,否则,检查第二长的,依次尝试匹配,直到找到一个匹配的location)

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

3. 常用指令

http://nginx.org/en/docs/http/ngx_http_core_module.html

3.1. location

一个location定义可以是一个前缀字符串,也可以是一个正则表达式。正则表达式使用的时候要在前面用“~*”修饰符(用于不区分大小写匹配),或者“~”修饰符(用于区分大小写)。为了找到请求匹配的location,nginx首先检查location定义,用前缀字符串(这些location成为前缀location)。其中,最长匹配前缀的location会被选中并记住。然后,检查正则表达式,按照它们在配置文件中出现的顺序。对正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果没有找到与正则表达式的匹配,则使用前面记住的前缀位置的配置。

画外音:首先检查前缀字符串,然后检查正则表达式

1、用前缀字符串(前缀location)匹配URL,并且选中并记住最长匹配前缀的location(注意:是在匹配的里面记住最长的那个)

2、按照正则表达式在配置文件中出现的顺序依次去匹配,当匹配到第一个以后立即停止,并使用与之相应的那个location。如果没有一个正则表达式匹配,则使用之前记住的那个前缀location。

以上,我们可以得出一个结论:优先使用正则表达式,如果没有匹配的正则表达式发现,则使用匹配的最长前缀字符串location

)

例如:

5. ngx_http_proxy_module模块

ngx_http_proxy_module模块允许将请求传递到另一个服务器。例如:

5.1. proxy_pass指令

设置代理服务器的协议和地址,以及应该映射哪一个可选URI。作为协议,可以指定“http”或“https”。地址可以指定为一个域名或IP地址,以及一个可选端口:

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

请求URI传递给服务器:

如果proxy_pass指令带一个特定的URI,那么请求被传给给这个服务器,正常的请求URI部分被指令中指定的URI替换,例如:

如果proxy_pass指令不带URI,那么请求URI在传递给服务器的时候和原始请求是一样的,例如:

在有些情况下,请求URI部分不能决定该如何替换:

1、当location时用一个正则表达式指定的时候,或者用内部的location命中指定的时候。

那么在这种情况下,proxy_pass在指定的时候不应该带URI

2、当用rewrite指令更改location时

在这种情况下,在指令中指定的URI将被忽略

(http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)

3、当在proxy_pass中使用变量时

在这种情况下,如果指令中指定了URI,那么将被传递给服务器,并替换原始请求URI

6. ngx_http_limit_req_module模块(限流)

ngx_http_limit_req_module模块用于限制指定的key的请求处理速率,特别是来自单个IP地址的请求处理速率。这种限制使用的是“漏桶算法”。

例如:

6.1. limit_req指令

设置共享内存区域和请求的最大突发大小。如果请求速率超过了为区域配置的速率,那么它们的处理就会延迟,这样请求就会以指定的速率进行处理。过多的请求被延迟,直到它们的数量超过最大突发大小,在这种情况下,以一个错误来终止请求。默认情况下,突发数量等于0。

平均每秒不允许超过1个请求,突发不超过5个请求。

如果不希望在请求受到限制时延迟过多的请求,则应使用参数nodelay:

可以有多个limit_req指令。例如,以下配置将限制来自单个IP地址的请求的处理速率,同时限制虚拟服务器的请求处理速率:

6.2. limit_req_zone指令

设置共享内存区域参数。key可以包含文本、变量、以及它们的组合。

这个例子中,“one”这个区域维护的内存是10M,并且这个区域的平均请求处理速率不能超过每秒1个请求。

7. 控制Nginx

8. 用Nginx作为负载均衡器

8.1. 负载均衡方法

nginx支持以下负载平衡机制(或方法):

8.2. 默认的负载均衡配置

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

在上面的例子汇总,同一个应用运行了3个实例。默认的负载均衡策略是循环。

8.3. 最少连接的负载均衡

另一个负载平衡原则是最少连接的。在某些请求需要更长的时间才能完成的情况下,最少连接允许更公平地控制应用程序实例上的负载。

使用连接最少的负载平衡,nginx将尽量不让繁忙的应用服务器超载过多的请求,而是将新请求分发到不那么繁忙的服务器。

例如:

8.4. Session持久化

使用循环或最少连接负载平衡,每个后续客户机的请求都可能被分发到不同的服务器。不能保证同一个客户端总是指向同一个服务器。

使用IP-hash,客户端的IP地址用作哈希key,以确定应该为客户端请求选择服务器组中的哪个服务器。此方法确保来自同一客户端的请求总是指向同一服务器,除非该服务器不可用。

例如:

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

8.5. 带权重的负载均衡

还可以通过使用服务器权值进一步影响nginx的负载平衡算法。

在上面的示例中,没有配置服务器权重,这意味着所有指定的服务器都被视为具有同等资格的特定负载平衡方法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容