设为首页 收藏本站
查看: 458|回复: 0

[经验分享] Nginx 详解(一)

[复制链接]

尚未签到

发表于 2018-11-9 08:08:17 | 显示全部楼层 |阅读模式
  Nginx简介
  Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师IgorSysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、腾讯,另外知名的微网志Plurk也使用nginx
  nginx可以作为一个反向代理服务器,用户请求经过它(其实这里用户请求到这里已经终止),判断静态页面或动态页面后再送往后方相应的服务器(nginx要另外启用一个进程到后方服务器取内容),服务器得到请求,响应,返回给nginx,nginx会重新封装首部,缓存后再返回给客户端(nginx又重新启用一个进程发送结果给客户端了)。
  所以Nginx的实际并发能力,要除以2,因为它既要处理用户的请求,又要重新构建新的请求。它在反向代理的情况下,处理能力是有限的。
  注意:这里的缓存,是把url做hash,存储为key,因为hash可以保证唯一并且长度很小。响应的内容存储为value
  Nginx安装
  详细过程参考http://dengxi.blog.51cto.com/4804263/1710472
  Nginx的配置文件
  配置文件位于 /etc/nginx/nginx.conf
  1、配置文件的结构
  ....
  events
  {
  ....
  }
  http
  {
  ....
  server
  {
  location{}
  ....
  }
  server
  {
  location {}
  ....
  }
  }
  2、正常运行的必备配置
  
  (1)、user username [groupname];
  指定运行worker进程的用户和组
  例:user nginx nginx;
  (2)、pid /path/to/pidfile_name;
  指定nginx的pid文件
  (3)、worker_rlimit_nofile #;
  指定一个worker进程所能够打开的最大文件句柄数;要等于或略大于worker_connections的值,因为还要打开其他文件
  例: worker_rlimit_nofile 51200;
  (4)、worker_rlimit_sigpending #;
  设定每个用户能够发往worker进程的信号的数量;
  (5)、events {
  use epoll;
  worker_connections  51200;
  }
  使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeBSD系统推荐采用kqueue模型
  3、优化性能相关的配置
  (1)、worker_processes 6;此项很关键!
  worker进程的个数,通常其数值应该为CPU的物理核心数减一
  (2)、worker_cpu affinity cpumask ...; 此项很关键!
  例:
  worker_processes6;  初始产生的worker进程个数,6个进程,把6个进程分别绑定在以下任意一个内核上(例如CPU一共有8个内
  核,nginx的进程只运行在这6个上面)
  worker_cpu_affinity00000001 00000010 00000100 00001000 00010000 00100000
  (3)、ssl_engine device;
  ssl硬件加速器,由于https链接所消耗的资源比http大得多,可能要多消耗5、6倍,所以有专门处理ssl的硬件设备
  (4)、timer_resolution t;  此项很关键!
  每次内核事件调用返回时,都会使用gettimeofday()来更新nginx缓存时钟,time_resolution用于定义每隔多久才会
  由gettimeofday()更新一次。因为每次调用返回都更新的话太消耗资源。不过目前x86-64系统上,gettimeofday()花费时间已经很
  小,可以忽略
  (5)、worker_priority nice;
  用于定义worker的优先级,-20至19,这项对系统性能提升很大,但值不要太小了。此项很关键
  4、事件相关
  (1)、accept_mutex [on|off]  默认打开
  是否打开Nginx的负载均衡锁,此锁能够让多个worker进程轮流的、序列化地与新的客户端建立连接。而通常一个worker进程的负
  载达到其上限的7/8,master就尽可能不再将请求调度至此worker
  (2)、lock_file /path/to/lock_file;
  (3)、accept_mutex_delay #ms; 默认500ms
  accept锁模式中,一个worker进程为取得accept锁的等待时长。如果某worker进程在某次视图取得锁时失败了,至少要等待#ms才
  能再一次请求锁。详细看“Nginx的accept_mutex配置分析”
  (4)、multi_accept on |off 默认off
  是否允许一次性响应多个用户请求。当一批用户请求进来时,是否让一个worker响应所有请求。允许的话效率有提高
  (5)、use [epoll|rtsig|select|poll]
  定义使用的事件模型,建议让nginx自动选择。Linux一般会选poll
  (6)、 worker_connections #;
  每个worker能够并发响应最大请求数。但要注意,系统每处理一个请求就要消耗一个套接字文件。做反向代理的时候要把
  worker_rlimit_nofile的值X2。
  5、用于调试的配置
  
  用于调试、定位问题,只在调试nginx时使用:
  (1)、daemon [on|off]
  是否让nginx运行在后台:默认为on,调试时可以设置为off,使得所有信息直接输出控制台、屏幕
  (2)、master_process on|off
  是否以master/worker模式运行nginx,默认on;调试时可以设置off,只运行一个worker进程。
  (3)、error_log/path/to/error_log level; 默认error级别
  错误日志文件及级别。调试可使用debug级别.但要求编译时必须--with-debug 启用debug功能
  6、虚拟主机的配置
  使用虚拟机来配置站点,每个虚拟主机使用一个server{}段,非虚拟主机的配置或公共配置,需要定义在server{}之外,http{}之内
  
  (1)基于IP及端口的虚拟主机
  一段server{...}就是一个虚拟主机,要基于端口,只要把端口改为相应的即可
  http
  {
  #第一个虚拟主机
  server
  {
  #监听的ip和端口
  listen 192.168.61.141:80;
  #主机名称
  server_name 192.168.61.141;
  #访问日志文件存放路径
  access_log logs/server1.access.log combined;
  location/
  {
  #默认首页文件,顺序从左到右
  index index.html index.htm;
  #HTML网页文件的存放目录
  root /web/server1;
  }
  }
  #第二个虚拟主机
  server
  {
  #监听的ip和端口
  listen 192.168.61.141:80;
  #主机名称
  server_name 192.168.61.141;
  #访问日志文件存放路径
  access_log logs/server2.access.log combined;
  location/
  {
  #默认首页文件,顺序从左到右
  index index.html index.htm;
  #HTML网页文件的存放目录
  root /web/server2;
  }
  }
  }
  (2)基于域名的虚拟主机
  注意写法*.a.com 除www.a.com之外的所有*.a.com二级域名的访问都由它来处理
  http
  {
  #第一个虚拟主机
  server
  {
  #监听的ip和端口
  listen 80;
  #主机名称
  server_name www.a.com *.a.com;
  #访问日志文件存放路径
  access_log logs/server1.access.log combined;
  location/
  {
  #默认首页文件,顺序从左到右
  index index.html index.htm;
  #HTML网页文件的存放目录
  root /web/server1;
  }
  }
  #第二个虚拟主机
  server
  {
  #监听的ip和端口
  listen 80;
  #主机名称
  server_name www.b.com *.b.com;
  #访问日志文件存放路径
  access_log logs/server2.access.log combined;
  location/
  {
  #默认首页文件,顺序从左到右
  index index.html index.htm;
  #HTML网页文件的存放目录
  root /web/server2
  }
  }
  }
  (3)参数详细说明
  (a)、listen
  listen地址[:端口]
  常用参数
  default_server:定义此server为http中默认的server.如果所有的server都没有使用listen参数,那么第一个server即为默认
  server
  rcvbuf=size:接受缓冲大小
  sndbuf=size:发送缓冲大小
  ssl:是否https 服务
  (b)、server_name
  设定主机名,可以跟多个。名称中可以使用通配符和正则表达式。当nginx收到一个请求时,会取出其首部的server的值,跟众
  多server_name进行比较,方式:
  (1)先做精确匹配 www.dx.com
  (2)左侧通配符匹配 *.dx.com
  (3)右侧通配符匹配 www.*
  (4)正则表达式匹配 ~^.*\.dx\.com$
  (c)、server_name_hash_bucket_size  有32|64|128
  为了实现快速主机查找,nginx使用hash表来保存主机名
  (d)、location [=|~|~*|^~] uri { ... }
  location @name { ... }
  功能:允许根据用户请求的URI来匹配指定的各location以进行访问配置;匹配到时,将被location块中的配置所处理
  =:精确匹配
  ~:正则表达式模式匹配,匹配时区分字符大小写
  ~*:正则表达式模式匹配,匹配时忽略字符大小写
  ^~:只需要前半部分与uri匹配即可,左侧匹配,不检查正则表达式
  匹配优先级:
  字符字面量最精确匹配、正则表达式检索(由多个时,由第一个匹配到的所处理),按字符字面量
  (e)、文件路径定义
  1、root path
  设置web资源路径,用于指定请求的根文档目录,从跟开始匹配
  root:root/URI
  2、alias path
  指定路径别名,只能用于location中,从最后一个/开始匹配
  alias:alias/
  3、index file....
  定义默认页面,可以跟多个值。自左向右匹配
  4、error_page code ... [=[response]] uri
  当对于某个请求发回错误时,如果匹配上了error_page指令中设定的code,则从定向至新的新URI中错误重定向
  5、try_files path1 [path2...] uri;
  自左向右尝试读取由path所指定路径,在第一找到即停止并返回,如果所有path均不存在,则返回最后一个uri
  例:
  location~* ^/document/(.*)${
  root/www/htdocs
  try_files$uri /docu/$1 /temp.html
  }
  http://www.wangfeng7399.com/documents/a.html
  http://www.wangfeng7399.com/docu/a.html
  http://www.wangfeng7399.com/temp.html
  7、网络连接相关的设置
  (1)、keepalive_timeouttime;
  保持连接的超时时长,默认为65s
  (2)、keepalive_requests n
  在一次长连接上允许承载的最大请求数
  (3)、keepalive_disable[msie6|safari |none]
  对指定的浏览器禁止使用长连接
  (4)、tcp_nodelay on|off
  对keepalive连接是否使用tcp_nodelay选项
  (5)、client_header_timeouttime
  读取http请求首部的超时时长
  (6)、client_body_timeouttime
  读取http请求包体的超时时间
  (7)、save_timeout time
  发送响应的超时时长
  8、对客户端请求的限制
  (1)、limit_except method...{ ... }
  指定范围之外的其他方法的访问控制,只能用于location中
  (2)、client_max_body_size 20m
  客户端http请求包体的最大值,常用于限定客户端所能够请求的最大包体。根据请求首部中的Content-Length来检查,以避免无
  用的传输。
  例如:
  网站上限定了用户最大上传文件为1G,如果不设置这个参数做限制,那么当用户已经上传了1G后,网站程序才能发现不能给它上
  传了,已经浪费了前面的时间和资源了。这里可以提前从heart头部读取到要传送的文件的大小,提前拒绝不必要的上传!
  (3)、client_max_body_buffer_size 256k
  请求包体内存缓存区大小,为什么这个值这么小呢?可以想象一下如果有10000个并发会占用多少内存?所以,如果超过这个大
  小会存在client_body_temp_path 磁盘上
  (4)、limit_rate speed
  限制客户端每秒传输的字节数,默认为0,表示没有限制
  (5)、limit_rate_after time
  nginx向客户端发送响应报文时,如果时长超过了此处指定的时长,则后续的发送过程开始限速
  例如:一个下载网站,很多用户在下载,当传送了一定时间,占用了不少带宽,为避免对其他用户的影响,开始根据limit_rate
  限速了
  9、对客户端请求的特殊处理
  (1)、ignore_invalid_headerson|off
  是否忽略不合法的http首部,默认为on,off意味着请求首部中出现不合规的首部将拒绝响应,只能用于server和http
  (2)、log_not_found on|off
  用户访问的文件不存在时,是否将其记录到错误日志中
  (3)、resolver address:
  指定nginx使用的dns服务器地址
  (4)、resolve timeout
  指定DNS解析超时时长,默认为30s
  (5)、server_tokens on|off
  是否在错误页面中显示nginx的版本号,为了安全,一般都要关闭
  10、文件操作的优化
    (1)、sendfile on|off
  是否启用sendfile功能
  (2)、aio on|off
  是否启用aio功能
  (3)、open_file_cache man=N[incative=time]|off
  是否打开文件缓存功能
  max:用于缓存条目的最大值,允许打开的缓存条目最大数,当满两类以后将根据LRU(最小最少连接数)算法进行置换
  inactive:某缓存条目在指定时长内没有被访问过时,将自动被删除;通常默认为60s
  缓存的信息包括:
  文件句柄、文件大小和上次修改时间
  已经打开的目录结构
  没有找到或没有访问权限的信息
  (4)、open_file_cache_errorson|off
  是否缓存文件找不到或没有权限访问等相关信息
  (5)、open_file_cache_validtime
  多长时间检查一次缓存中的条目是否超出非活动时长,默认为60s
  (6)、open_file_cache_min_use#
  在inactive指定的时长内被访问超过此处指定的次数时,才不会被删除
  (7)、open_log_file_cachemax=1000 inactive=20s min_uses=1 valid=1m;
  打开日志缓存,最大条目1000条,非活动时间20秒,最少使用1次,有效时间1分钟
  11、http核心模块的内置变量:
  $uri:当前请求的uri,不带参数
  $request_uri:请求的uri,带完整参数
  $host:http请求报文中host首部;如果请求中没有host首部,则以处理此请求的主机的主机名代替
  $hostname:nginx服务运行所在主机的主机名
  $remote_addr:客户端IP
  $remote_port:客户端port
  $remote_user:使用用户认证时客户端用户输入的用户名
  $request_filename:用户请求中的URI经过本地root或alias转换后映射的本地的文件路径
  $request_method:请求方法
  $server_addr:服务器地址
  $server_name:服务器名称
  $server_port:服务器端口
  $server_protocol:服务器向客户端发送响应时的协议,如http/1.1,http/1.0
  $scheme:在请求中使用的scheme 映射协议本身的协议
  $http_HEADER:匹配请求报文中指定的HEADER,$http_host匹配请求报文中的host首部
  $sent_http_HEADER:匹配响应报文中指定的HERDER,例如$http_content_type匹配相应报文中的content-type首部
  $document_root:当前请求映射到的root配置
  12URLrewrite
  nginx通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else。
  该模块需要PCRE支持,应在编译 nginx 时指定PCRE源码目录
  (a)、nginx rewrite指令执行顺序:
  (1)、执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
  (2)、执行location匹配
  (3)、执行选定的location中的rewrite指令
  如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件
  如果循环超过10次,则返回500 Internal ServerError错误
  (b)、break指令
  语法:break;
  默认值:无
  作用域:server,location,if
  停止执行当前虚拟主机的后续rewrite指令集
  break指令实例:
  if ($slow) {
  limit_rate 10k;
  break;
  }
  (c)、if指令
  语法:if(condition){...}
  默认值:无
  作用域:server,location
  对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。
  if条件(conditon)可以是如下任何内容:
  一个变量名;false如果这个变量是空字符串或者以0开始的字符串;
  使用= ,!= 比较的一个变量和字符串
  是用~, ~*与正则表达式匹配的变量,如果这个正则表达式中包含},;则整个表达式需要用" 或' 包围
  使用-f ,!-f 检查一个文件是否存在
  使用-d, !-d 检查一个目录是否存在
  使用-e ,!-e 检查一个文件、目录、符号链接是否存在
  使用-x , !-x 检查一个文件是否可执行
  if指令实例
  if ($http_user_agent ~ MSIE) {
  rewrite ^(.*)$ /msie/$1 break;
  }
  if ($http_cookie ~*"id=([^;]+)(?:;|$)") {
  set $id $1;
  }
  if ($request_method = POST) {
  return 405;
  }
  if ($slow) {
  limit_rate 10k;
  }
  if ($invalid_referer) {
  return 403;
  }
  (d)、return指令
  语法:
  return code;
  return code URL;
  return URL;
  默认值:无
  作用域:server,location,if
  l  停止处理并返回指定状态码(code)给客户端。
  l  非标准状态码444表示关闭连接且不给客户端发响应头。
  l  从0.8.42版本起,return 支持响应URL重定向(对于301,302,303,307),或者文本响应(对于其他状态码).
  l  对于文本或者URL重定向可以包含变量
  (e)、rewrite指令
  语法:rewrite regexreplacement [flag];
  默认值:无
  作用域:server,location,if
  l  如果一个URI匹配指定的正则表达式regex,URI就按照replacement重写。
  l  rewrite按配置文件中出现的顺序执行。flags标志可以停止继续处理。
  l  如果replacement以"http://"或"https://"开始,将不再继续处理,这个重定向将返回给客户端。
  flag可以是如下参数
  last 停止处理后续rewrite指令集,然后对当前重写的新URI在rewrite指令集上重新查找。
  break 停止处理后续rewrite指令集,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的
  非rewrite语句可以执行。
  redirect 如果replacement不是以http:// 或https://开始,返回302临时重定向
  permant 返回301永久重定向
  最终完整的重定向URL包括请求scheme(http://,https://等),请求的server_name_in_redirect和 port_in_redirec三部分
  ,说白了也就是http协议 域名 端口三部分组成。
  rewrite实例
  server {
  ...
  rewrite ^(/download/.*)/media/(.*)..*$$1/mp3/$2.mp3 last;
  rewrite ^(/download/.*)/audio/(.*)..*$$1/mp3/$2.ra last;
  return 403;
  ...
  }
  如果这些rewrite放到“/download/” location如下所示, 那么应使用break而不是last , 使用last将循环10次匹配,然后返回
  500错误:
  location /download/ {
  rewrite ^(/download/.*)/media/(.*)..*$$1/mp3/$2.mp3 break;
  rewrite ^(/download/.*)/audio/(.*)..*$$1/mp3/$2.ra break;
  return 403;
  }
  如果客户端使用IE浏览器,则重定向到/nginx-ie目录下
  if ($http_user_agent~ MSIE) {
  rewrite ^(.*)$ /nginx-ie/$1 break;
  }
  禁止访问多个目录:
  location ~^/(cron|templates)/ {
  deny all;
  break;
  }
  禁止访问以/data开头的文件:
  location ~ ^/data {
  deny all;
  break;
  }
  禁止访问.sh、.flv、.mp4为文件名后缀的URL地址:
  location ~.*\.(sh|flv|mp4)?$ {
  return 403;
  }
  注意:
  (1)、在写URI地址的时候,留意.是否要转义字符操作,测试过暂时不用,但老师是写的。
  (2)、如果正则表达regex式中包含“}”或“;”, 那么整个表达式需要用双引号或单引号包围.
  (3)、如果被替换的URI中含有参数(即类似/app/test.php?id=5之类的URI),默认情况下参数id=5会自动附加到替换串上,如
  果不想自动附带后面的参数,可以在replacement后加一个问号。如下,我们加了一个自定义的参数user=$1,然后在结尾
  处放了一个问号?,把原请的参数去掉。
  例:
  rewrite ^/users/(.*)$/show?user=$1? last;
  rewrite ^/test(.*)$http://www.test.com/home? permanent; 结果是http://www.test.com/home
  (f)、rewrite_log指令
  语法:rewrite_log on|off;
  默认值:rewrite_log off;
  作用域:http,server,location,if
  开启或关闭以notice级别打印rewrite处理日志到error log文件。
  例:
  rewrite_log on;
  error_loglogs/xxx.error.log notice;
  n  打开rewrite on
  n  把error log的级别调整到 notice


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-632591-1-1.html 上篇帖子: 如何写nginx module 下篇帖子: nginx 多个虚拟主机 no input file specified-linuxer
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表