Nginx 特性

  • NGINX 有什么不同? NGINX 使用可扩展的事件驱动架构,而不是更传统的过程驱动架构。这需要更低的内存占用,并且当并发连接扩大时,使内存使用更可预测。
  • 在传统的 Web 服务器体系结构中,每个客户端连接作为一个单独的进程或线程处理,随着网站的流行度增加,并发连接数量的增加,Web 服务器减慢,延迟了对用户的响应。
  • 从技术的角度来看,产生一个单独的进程/线程需要将 CPU 切换到新的任务并创建一个新的运行时上下文,消耗额外的内存和 CPU 时间,从而对性能产生负面影响。
  • NGINX 开发的目标是实现 10 倍以上的性能,优化服务器资源的使用,同时也能够扩展和支持网站的动态增长。 因此,NGINX 成为最知名的模块化,事件驱动,异步,单线程Web 服务器和 Web 代理之一。
  • Nginx 是一个高性能的 Web 和反向代理服务器, 它具有很多非常优越的特性:

nginx工作方式

nginx与服务器的关系

NGINX安装后还能编译吗_服务器

nginx与路由器的关系

NGINX安装后还能编译吗_nginx_02

网络层次结构每一层可用的负载均衡服务

越底层,速度越快。

  • Nginx:给应用层代理。
  • haproxy:给TCP/UDP…的服务做代理。
  • lvs:给IP地址做代理。
  • F5:给MAC地址做代理。

Nginx 安装

直接给通过apt get的方式安装

sudo apt-get install nginx

压缩包的方式安装

准备第三方支持库源码:

解压并安装

# 解压
tar xzvf nginx-1.13.7.tar.gz 
tar xzvf openssl-1.1.0g.tar.gz 
tar xzvf pcre-8.41.tar.gz    
tar xzvf zlib-1.2.11.tar.gz 

# 配置nginx
cd nginx-1.13.7
./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=文件目录/pcre-8.41 --with-zlib=文件目录/zlib-1.2.11 --with-openssl=文件目录/openssl-1.1.0g

# 编译
make

# 安装
sudo make install 

# 加载nginx的配置文件并启动nginx
./sbin/nginx –c ./conf/nginx.conf

Nginx快速入门

  • 在配置文件中确定 nginx 及其模块的工作方式。默认情况下,配置文件名为 nginx.conf,并放在目录:/usr/local/nginx/conf, /etc/nginx, 或 /usr/local/etc/nginx 中。
  • 在前面安装文章配置中,使用的安装配置目录是:/usr/local/nginx/conf 。所以可以在这
    个目录下找到这个配置文件。

启动,停止和重新加载 Nginx 配置

当 nginx 启动后,可以通过使用-s 参数调用可执行文件来控制它。 使用以下语法:

$ nginx -s signal

信号(signal)的值可能是以下之一:

  • stop - 快速关闭服务
  • quit - 正常关闭服务
  • reload - 重新加载配置文件
  • reopen - 重新打开日志文件
关闭

要通过等待工作进程完成服务当前请求来停止 nginx 进程,可以执行以下命令:

$ nginx -s quit

注:该命令应该在启动 nginx 的同一用户下执行

重新加载配置文件

在将重新配置命令的命令发送到 nginx 或重新启动之前,配置文件中的更改将不会被应用。
要重新加载配置文件,请执行:

$ nginx -s reload

当主进程收到要重新加载配置的信号,它将检查新配置文件的语法有效性,并尝试应用其中
提供的配置。 如果这是成功的,主进程将启动新的工作进程,并向旧的工作进程发送消息,
请求它们关闭。 否则,主进程回滚更改,并继续使用旧配置。 老工作进程,接收关闭命令,
停止接受新连接,并继续维护当前请求,直到所有这些请求得到维护。 之后,旧的工作进
程退出。

获取进程nginx列表

要获取所有运行的 nginx 进程的列表,可以使用 ps 命令,例如,以下列方式:

ps -ax | grep nginx

杀死使用进程

kill -s QUIT 进程号 或者 kill -9 进程号

配置文件

Nginx 配置文件
NGINX 与其他服务类似,因为它具有以特定格式编写的基于文本的配置文件。 默认情况下,文件名为 nginx.conf 并放在/etc/nginx 目录中(对于开源 NGINX 产品,位置取决于用于安装 NGINX 和操作系统的软件包系统,它通常位于/usr/local/nginx/conf/etc/nginx 或/usr/local/etc/nginx。)
配置文件由指令及其参数组成。 简单(单行)指令各自以分号结尾。 其他指令作为“容器”,将相关指令组合在一起,将其包围在花括号({})中。

常用语法
  • 为了使配置更易于维护,建议您将其拆分为存储在/etc/nginx/conf.d 目录中的一组功能特定文件,并在主 nginx.conf 文件中使用 include 指令引用(包函)指定文件的内容。如下所示:

include conf.d/http;
include conf.d/stream;
include conf.d/exchange-enhanced;

  • 几个顶级指令(称为上下文)将适用于不同流量类型的指令组合在一起:

events – 一般连接处理
http – HTTP 协议流量
mail – Mail 协议流量
stream – TCP 协议流量

  • Nginx 由配置文件中指定的指令控制的模块组成。 指令分为简单指令和块指令。
  • 一个简单的指令由空格分隔的名称和参数组成,并以分号(;)结尾。
  • 块指令具有与简单指令相同的结构,但不是以分号结尾,而是以大括号({和})包围的一组附加指令结束。
  • 如果块指令可以在大括号内部有其他指令,则称为上下文(例如:events,http,server 和 location)。
  • 配置文件中放置在任何上下文之外的伪指令都被认为是主上下文。events 和 http 指令驻留
    在主上下文中,server 在 http 中的,而 location 在 http 块中。
  • #号之后的一行的部分被视为注释
配置文件demo
# 配置有4线程
worker_processes 4;
# 配置可用的工作事件有1024条
events {
	worker_connections 1024;
}

# 配置协议
http {
	# 配置模块,backend这个名字随便取
	upstream backend {
		# 配置权重
		server 192.168.142.128 weight=2;
		server 192.168.142.129 weight=1;
	}
	# 配置服务
	server {
		listen 8888;
		server_name localhost;
		# 设置最大可传输文件大小
		client_max_body_size 100m;
		# 设置默认访问路径
		location / {
			# 设置默认路径
#			root /usr/local/nginx/html/;
			# 启动代理此ip地址
#			proxy_pass http://192.168.142.128;
			# 做负载均衡
			proxy_pass http://backend;
		}		
		# 设置图片访问路径
		location /images/ {
			root /usr/local/nginx/;
		}
		# 配置媒体文件访问路径(使用正则的方式)
		location ~ \.(mp3|mp4) {
			root /usr/local/nginx/media/;
		}		
	
	}	
	# 配置cgi服务
	server {
		listen 9000;
		# 配置一个cgi程序
		location ~ \.cgi {
			# cgi配置的服务端口
			fastcgi_pass 127.0.0.1:9001;
			fastcgi_index index.cgi;
			fastcgi_param SCRIPT_FILENAME cgi$fastcgi_script_name;
			# 这个包含没有就没有fastcgi系列的指令
			include ../conf/fastcgi_params;
		}
	} 
}

反向代理

概念:反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
下面贴上一段简单的实现反向代理的代码:

server { 
    listen 80; 
    server_name localhost; 
    client_max_body_size 1024M;
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host:$server_port;
    }
}

保存配置文件后启动 Nginx,这样当我们访问 localhost 的时候,就相当于访问 localhost:8080 了

负载均衡

负载均衡:分摊到多个操作单元上进行执行。
例如 Web 服务器、FTP 服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。简单而言就是当有 2 台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而 Nginx 目前支持自带 3 种负载均衡策略,还有 2 种常用的第三方策略。

RR(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

# 负载均衡的核心代码
upstream test {
    server localhost:8080;
    server localhost:8081;
}
server {
    listen 81; 
    server_name localhost; 
    client_max_body_size 1024M;
    location / {
    	# 调用
        proxy_pass http://test;
        proxy_set_header Host $host:$server_port;
    }
}

这里配置的两个服务,如果有一个宕机了,nginx会自动访问另一台,不会去访问宕机的服务器。
因为 Nginx 会自动判断服务器的状态,如果服务器处于不能访问(服务器挂了),就不会跳转到这台服务器,所以也避免了一台服务器挂了影响使用的情况,由于 Nginx 默认是 RR 策略,所以我们不需要其他更多的设置。

权重

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。 例如

upstream test {
    server localhost:8080 weight=9;
    server localhost:8081 weight=1;
}

那么 10 次一般只会有 1 次会访问到 8081,而有 9 次会访问到 8080

ip_hash

上面的 2 种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了 session 保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了 session 中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用 iphash 了,iphash 的每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

upstream test {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
}
fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backend {
    fair;
    server localhost:8080;
    server localhost:8081;
}
url_hash(第三方)

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓
存时比较有效。 在 upstream 中加入 hash 语句,server 语句中不能写入 weight 等其他的参数,hash_method 是使用的 hash 算法

upstream backend {
    hash $request_uri;
    hash_method crc32;
    server localhost:8080;
    server localhost:8081;
}

以上 5 种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过 fair 和 url_hash 需要安装第三方模块才能使用

设置 FastCGI 代理

nginx 可用于将请求路由到运行使用各种框架和 PHP 等编程语言构建的应用程序的FastCGI 服务器。使用 FastCGI 服务器的最基本 nginx 配置包括使用 fastcgi_pass 指令(而不是proxy_pass 指令),以及 fastcgi_param 指令来设置传递给 FastCGI 服务器的参数。

假设 FastCGI服务器可以在 localhost:9000 上访问。 以上一节的代理配置为基础,用 fastcgi_pass 指令替换 proxy_pass 指令,并将参数更改为 localhost:9000。 在 PHP 中,SCRIPT_FILENAME 参数用于确定脚本名称,QUERY_STRING 参数用于传递请求参数。 最终的配置将是:

server {
    location / {
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME 
        $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING $query_string;
    }
    location ~ \.(gif|jpg|png)$ {
    	root /data/images;
    } 
}

这将设置一个服务器,将除静态图像请求之外的所有请求路由到通过 FastCGI 协议在localhost:9000 上运行的代理服务器。

fastcig安装

工具包:

# 解压
tar xzvf fcgi.tar.gz
tar xzvf spawn-fcgi-1.6.4.tar.gz  

cd spawn-fcgi-1.6.4
./configure
make
cd src
# cp到nginx的目录下
sudo cp spawn-fcgi /usr/local/nginx/sbin 

cd ../..
cd fcgi
./configure
make
# 可能会出现EOF未定义,修改如下
# 找到fcgio.h加入#include<stdio.h>
vi include/fcgio.h
make
sudo make install

cgi程序实例

#include <stdio.h>
#include <fcgi_stdio.h>
int main()
{
	while(FCGI_Accept() >=0){
		printf(" Content-type: text/html\r\n");
		printf("\r\n");
		printf("<title>Fast CGI Hello! </title>");
		printf("<h1>ZVoice cgi<h1>");
		printf("Thank you cgi\n");
	}
	return 0;
}

cgi程序编译

gcc -o 程序名 代码文件.c -lfcgi

调用

./spawn-fcgi -a 127.0.0.1 -p 9002 -f 程序路径