nginx

简介

nginx是一款轻量级的web服务器/反向代理服务器/电子邮件(IMAP,POP3)代理服务器,并在一个BSD-like协议下发行。

nginx的特点是内存占用少,并发能力强。,在同类网页服务器中表现比较好。

特性与优点

特性

  • 能支持最高50000个并发连接数的响应
  • nginx作为负载均衡服务器,既可以作为http服务器对外服务,也可内部直接支持php程序对外服务(反向代理)
  • nginx采用c编写,系统资源开销或cpu使用效率都高于perlbal( Perl 编写的单线程的事件驱动服务器,可充当 Web 服务器 和 HTTP 负载均衡)

优点

  • 高并发连接,最多支持5万并发,生产环境能到2~3万并发连接数
  • 内存消耗少,3万并发连接下,10个nginx进程占用150M内存
  • 配置文件通俗易懂(相对)
  • 成本低廉(开源软件)
  • 支持rewrite重写规则,根据域名,统一资源定位器URL,将http请求分发到不同后端服务器群组。
  • 内置健康检测,不会因为单个web服务器宕机影响前端访问
  • 节省带宽,可以添加浏览器本地缓存
  • 模块化设计,支持动态编译。
  • 外围支持好:模块和二次开发多
  • 支持热部署: 不停机重载配置文件
  • 支持事件驱动,AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化

nginx功能

基本功能

  • 静态资源的web服务器

  • http,smtp,pop3协议的反向代理服务器

  • 缓存加速,负载均衡(负载均衡离不开反向代理,二者相互依存)

  • 支持FastCGI(fpm,LNMP),uWSGI(python)等

  • 模块化

  • 支持SSL(证书https等)

扩展功能

  • 基于名称和IP的虚拟主机

  • 支持keepalive(长连接,不是高可用!)

  • 支持平滑升级

  • 定制访问日志、支持使用日志缓冲区提高日志存储性能

  • 支持URL重写

  • 支持路径别名

  • 支持基于IP及用户的访问控制

  • 支持速率限制,支持并发数限制

    应用类别

  • 使用nginx结合FastCGI运行PHP、JSP、Perl等程序

  • 使用nginx作反向代理、负载均衡、规则过滤

  • 使用nginx运行静态HTML网页、图片

  • nginx与其他新技术的结合应用

nginx模块与工作原理

nginx由内核和模块组成。其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

模块分类

nginx的模块从结构上分为:

核心模块

  • HTTP模块
  • EVENT模块
  • MAIL模块

基础模块

  • HTTP Access模块
  • HTTP FastCGI模块
  • HTTP Proxy模块
  • HTTP Rewrite模块

第三方模块

  • HTTP Upstream模块
  • Request Hash模块
  • Notice模块
  • HTTP Access Key模块

nginx模块从功能上分类,分为三类:

  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
  • Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出
  • Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能

nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等

  • nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:
    • 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部(配置文件行的最左)
    • 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
    • 配置模块:提供包含机制(include)

工作原理

nginx模块被直接编译进nginx,属于静态编译方式。

启动时将模块编译为一个so文件,然后在配置文件中决定是否加载模块。

nginx启动,产生一个master进程,该进程不处理任何客户端请求,而是用来产生worker线程。worker线程用来处理多个request(请求)

基本的WEB服务请求步骤:

nginx安装与配置

安装(源码)

//防火墙selinux关闭
systemctl stop firewalld.service 
setenforce 0
//创建nginx用户
[root@node1 ~]# useradd -r -M -s /sbin/nologin nginx

//安装开发工具组和依赖包
[root@node1 ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make 
[root@node1 ~]# yum -y groups mark install 'development tools'
//创建日志存放目录
[root@node1 ~]# mkdir -p /var/log/nginx
[root@node1 ~]# chown -R  nginx.nginx /var/log/nginx
//下载源码包
[root@node1 ~]# cd /usr/src/
[root@node1 src]# wget http://nginx.org/download/nginx-1.20.0.tar.gz
[root@node1 src]# ll
...
-rw-r--r--. 1 root root 1061070 Apr 20 22:46 nginx-1.20.0.tar.gz
//解压
[root@node1 src]# tar xf nginx-1.20.0.tar.gz 
[root@node1 src]# cd nginx-1.20.0/
//编译安装
[root@node1 nginx-1.20.0]# ./configure \
> --prefix=/usr/local/nginx \	#指定路径
> --user=nginx \	#指定用户
> --group=nginx \	#指定组
> --with-debug \	#启用debug测试
> --with-http_ssl_module \	#启用ssl证书模块
> --with-http_realip_module \	#启用http真实ip模块
> --with-http_image_filter_module \	#启用http图像过滤器模块
> --with-http_gunzip_module \	#启用http压缩模块
> --with-http_gzip_static_module \	#启用静态压缩
> --with-http_stub_status_module \	#启用状态页面
> --http-log-path=/var/log/nginx/access.log \	#指定日http访问日志路径
> --error-log-path=/var/log/nginx/error.log	#指定报错日志路径

//启用多核心加速安装
[root@node1 nginx-1.20.0]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install

配置

配置文件详解

默认是“nginx安装路径/conf/nginx.conf'

配置文件 作用
nginx.conf nginx的基本配置文件
mime.types MIME类型关联的扩展文件
fastcgi.conf 与fastcgi相关的配置
proxy.conf 与proxy相关的配置
sites.conf 配置nginx提供的网站,包括虚拟主机
//添加环境变量
[root@node1 nginx-1.20.0]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@node1 nginx-1.20.0]# source /etc/profile.d/nginx.sh
[root@node1 nginx-1.20.0]# which nginx
/usr/local/nginx/sbin/nginx

//语法
[root@node1 nginx-1.20.0]# nginx -help
nginx version: nginx/1.20.0
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
             [-e filename] [-c filename] [-g directives]

Options:
  -?,-h         : this help	#帮助信息
  -v            : show version and exit	#显示版本
  -V            : show version and configure options then exit		#显示版本和配置选项
  -t            : test configuration and exit	#测试配置并退出
  -T            : test configuration, dump it and exit	#测试配置
  -q            : suppress non-error messages during configuration testing	#配置测试期间只输出错误信息
  -s signal     : send signal to a master process: stop, quit, reopen, reload	#传递控制信号给主进程
  -p prefix     : set prefix path (default: /usr/local/nginx/)	#设置路径
  -e filename   : set error log file (default: /var/log/nginx/error.log) #设置错误日志路径
  -c filename   : set configuration file (default: conf/nginx.conf)	#设置配置文件路径
  -g directives : set global directives out of configuration file	#从配置文件中设置全局指令

//启动测试
[root@node1 nginx-1.20.0]# nginx 
[root@node1 nginx-1.20.0]# ss -antl
State   Recv-Q  Send-Q   Local Address:Port     Peer Address:Port  
LISTEN  0       128            0.0.0.0:80            0.0.0.0:*     
LISTEN  0       128            0.0.0.0:22            0.0.0.0:*     
LISTEN  0       128               [::]:22               [::]:* 

nginx.conf配置文件详解

配置文件语法

  • main配置段:全局配置段。其中main配置段中可能包含event配置段
  • event {}:定义event模型工作特性
  • http {}:定义http协议相关的配置

语法格式:
derective value1 [value2 ...];

设置变量:
set VAR_NAME value

用于调试,定位问题的配置

daemon on|off;	#守护进程
master_process {on|off};    #是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别;    #配置错误日志存放路径,消息级别

正常运行必备的配置参数

user USERNAME [GROUPNAME];    #指定运行worker进程的用户和组
pid /path/to/pid_file;    #指定nginx守护进程的pid文件
worker_rlimit_nofile NUM; 	#指定每个worker进程最大可以打开的文件数(默认1024,最大65535)kvm设置过。
worker_rlimit_core NUM;	#设置给worker进程的最大核心数(推荐为总核心数-1)

性能优化的配置参数

 
timer_resolution interval;    #单位ms计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority number;    #指明worker进程的nice值(-20~20)
worker_processes n;    #启动n个worker进程,为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
worker_cpu_affinity cpumask ...;	#将进程绑定到指定cpu避免频繁刷新内存用二进制表示绑定cpu	0001 0010 0100 1000

事件相关配置

accept_mutex {off|on};    #master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file file;    #accept_mutex用到的互斥锁锁文件路径,二者一般绑定出现
use [epoll | rtsig | select | poll];    #指明使用的事件模型,建议让nginx自行选择
worker_connections #每个进程能够接受的最大连接数

网络相关配置参数

keepalive_timeout number;    #长连接的超时时长,默认为65(s)
keepalive_requests number;    #在一个长连接上所能够允许请求的最大资源数
keepalive_disable [msie6|safari|none];    #为指定类型的UserAgent(浏览器类型)禁用长连接
tcp_nodelay on|off;    #是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on
client_header_timeout number;    #读取http请求报文首部的超时时长
client_body_timeout number;   #读取http请求报文body(文本内容)部分的超时时长
send_timeout number;    #发送响应报文的超时时长

长连接:数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据

fastcgi配置参数

lnmp部署时参数修改

#单服务器部署,取消注释即可。分离部署需修改反向代理ip和端口
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;
}

nginx作为web服务器的配置

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;
        }

https配置

生成私钥后证书签署并获得证书,nginx如下配置

server {
  listen       443 ssl;
  server_name  www.idfsoft.com;
  ssl_certificate      /etc/nginx/ssl/nginx.crt;
  ssl_certificate_key  /etc/nginx/ssl/nginx.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;
  }
}

访问控制

针对ip,套接字,无类别域间路由(Classless Inter-Domain Routing、CIDR)的访问控制

allow

Syntax:	allow address | CIDR | unix: | all;
Default:	—
Context:	http, server, location, limit_except

deny

Syntax:	deny address | CIDR | unix: | all;
Default:	—
Context:	http, server, location, limit_except

用户认证

auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file"
//用户认证文件内容格式为:
username:password
//建议用htpasswd来创建此文件
htpasswd -c -m /path/to/.user_auth_file USERNAME

开启状态界面

stub_status

Syntax:	stub_status;
Default:	—
Context:	server, location
location /status {
  stub_status {on | off};	#自定义状态页面是否开启
  allow 172.16.0.0/16;	#针对访问控制
  deny all;
}

rewrite

通过执行URL重定向,在不改变用户习惯的前提下将资源迁移至新空间。防止恶意访问,替换的可以是路径,也可以是url。

rewrite 正则 替换 flag;
context: location
//匹配"/images/"开头"任意.jpg"结尾的标识符,请求转发到/img/(.*.jpg)内容
rewrite ^/images/(.*\.jpg)$ /imgs/$1  break;
//匹配"/bbs"开头的"/任意结尾的"的临时重定向到新的url"http://www.idfsoft.com/index.html"去

rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect;

常见flag

flag 作用
last 表示当前匹配结束,继续下一个匹配,最多匹配10~20。
不再被后面rewrite规则处理,而是对重写后的url再执行一次
break 终止匹配:重写完成后,不会被当前location内的任何rewrite规则所检查
redirect 临时重定向http状态302返回新的url
permanent 永久重定向http状态301返回新的url

nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:

标识符 意义
^ 必须以^后的实体开头
$ 必须以$前的实体结尾
. 匹配任意字符
[] 匹配指定字符集内的任意字符
[^] 匹配任何不包括在指定字符集内的任意字符串
| 匹配 | 之前或之后的实体
() 分组,组成一组用于匹配的实体,通常会有| 来协助

实例:

[root@node1 ~]# cd /usr/local/nginx/html
[root@node1 html]# mkdir images
[root@node1 html]# cd images/
[root@node1 images]# ll
total 452
-rw-r--r--. 1 root root 459622 Jun  1 21:49 moto.jpg

//模拟图片访问路径改变
[root@node1 html]# mkdir newimgs
[root@node1 html]# mv images/moto.jpg newimgs/

//rewrite重写规则
[root@node1 html]# vim ../conf/nginx.conf
     location /images {
            rewrite ^/images/(.*\.jpg)$ /newimgs/$1 break;
        }
[root@node1 html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node1 html]# nginx -s reload

再次刷新正常访问

if条件判断

判断条件是否满足,满足则执行规则。

Syntax:	if (condition) { ... }
Default:	—
Context:	server, location
//例子
if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;	#判断浏览器是否是IE,是则重定向到/msie目录下的资源
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

if ($request_method = POST) {	#请求方法为POST时,返回状态码405
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

//防盗链
location ~* \.(jpg|gif|jpeg|png)$ {#不区分大小写的图片资源
  valid_referers none blocked www.idfsoft.com;#定义有效链接
  if ($invalid_referer) {	#判断是否为无效链接
    rewrite ^/ http://www.idfsoft.com/403.html;#成立则返回403状态页面
  }
}

负载均衡和反向代理

upstream

文档_http_upstream_module (nginx.org)

通过这个模块能实现nginx的负载均衡

Syntax:	upstream name { ... }
Default:	—
Context:	http	#与server平级

//用到的参数
server	#后端服务器域名(或ip)默认端口80
weight	#权重:默认1,权重越大请求越多。
ip hash	#用户经常访问的后端服务器绑定

nginx常用负载均衡算法

  • 轮询(默认算法):每个请求会依次分配给后端不同的应用程序服务器,不理会后端服务器的实际压力

  • 加权轮询:权重越大的服务器,被分配到的次数就会越多,通常用于后端服务器性能不一致的情况

  • IP HASH:当同IP进行重复访问时会被指定到上次访问到的服务器,可以解决动态网站SESSION共享问题

测试

node2,node4安装http,node1安装nignx。

修改2和4的index.html,方便验证

ssystemctl stop firewalld
setenforce 0
[root@node2 ~]# echo node2> /var/www/html/index.html
[root@node4 ~]# echo node4> /var/www/html/index.html

//负载均衡配置
[root@node1 html]# vim ../conf/nginx.conf
...
upstream loadbalance {	#定义一个服务器组
        server 192.168.94.143:80 ;	#node2服务器
        server 192.168.94.130:80 ;	#node4服务器
         }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://loadbalance;	#代理转发调用刚刚定义的“loadbalance”
        }
[root@node1 html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node1 html]# nginx -s reload
//访问测试
[root@node1 html]# curl 192.168.94.141
node4
[root@node1 html]# curl 192.168.94.141
node2

posted on 2021-05-24 22:51  fxx013  阅读(86)  评论(0编辑  收藏  举报

导航