Nginx学习&反向代理实操

Nginx学习&反向代理实操

前言

公司项目使用Nginx完成反向代理以及静态资源服务器,所以对Nginx相关的知识学习整理一下

Nginx简介

Nginx由俄罗斯工程师伊戈尔·赛索耶夫使用C语言编写创造(致敬🚀️ )并开源,是一款具有高性能、高可靠性的 Web 和反向代理服务器,占用内存少、并发能力强、支持热部署,支持高达 5w 个并发连接数。

Nginx优势

  • 高并发、高性能;Nginx采用了多进程和I/O多路复用(epoll)的底层实现,从而拥有优秀的并发能力及性能
  • 高可靠性;Nginx采用的多进程模式运行,其中有一个master主进程和N个worker进程,每个worker进程之间相互独立提供服务,master主进程可以在某一个worker进程出错时,快速去拉起新的worker进程提供服务
  • 配置简单,扩展性强;模块化架构使得它的扩展性非常好,这些模块的使用可以通过配置文件的配置来添加
  • 热部署、平滑升级;Nginx可以在不停止的情况下,对Nginx进行文件升级、更新配置和更换日志文件等功能
  • 开源,社区繁荣;免费且好用,大家都喜欢😄

Nginx使用场景

  • 作为静态资源服务器
  • 作为反向代理服务器,并提供负载均衡和容错
  • 邮件代理服务
  • 虚拟主机、过滤器功能等等

Nginx基础命令

我们可以通过Nginx安装目录sbin下的可执行文件来对nginx进行控制,使用 nginx -h查看可使用参数(因为我这里使用docker方式启动的所以前面使用了docker exec -it 容器命,不必在意)

1719326798838.jpg

nginx -h #显示帮助信息
nginx -V #打印版本号信息和配置信息并退出
nginx -T #测试nginx的配置文件语法是否正确并列出用到的配置文件信息然后退出
nginx -q #在配置测试期间禁止显示非错误消息
nginx -s stop   #立刻停止nginx服务
nginx -s quit   #等待所有请求处理完毕后,停止nginx服务
nginx -s reopen #重新打开日志文件
nginx -s reload #重新加载nginx配置文件,以热部署的方式重启
nginx -p "prefix"     #指定Nginx的prefix路径,(默认为: /usr/local/nginx/)
nginx -c "filename"   #指定Nginx的配置文件路径,(默认为: conf/nginx.conf)
nginx -g "directives" #补充Nginx配置文件,向Nginx服务指定启动时应用全局的配置

Nginx核心配置

配置文件概览

Nginx的核心配置文件默认路径 /usr/local/nginx/conf/nginx.conf (如果是以docker容器的方式启动那么就不一样了哈,应该是在 /etc/nginx/nginx.conf),作为开发人员主要关注点就是其相关的使用及配置参数,直接贴一份比较详细的配置文件吧,当然看nginx的默认配置文件也可以的

# 全局配置信息
user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes  auto;             # Nginx 进程数,一般设置为和 CPU 核数一样
error_log  /var/log/nginx/error.log warn;   # Nginx 的错误日志存放目录
pid        /var/run/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

# events段配置信息
events {
    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
    worker_connections 1024;   # 每个进程允许最大并发数
}

# http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
http { 
    # 设置日志模式
    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  /var/log/nginx/access.log  main;   # Nginx访问日志存放位置

    sendfile            on;   # 开启高效传输模式
    tcp_nopush          on;   # 减少网络报文段的数量
    tcp_nodelay         on;
    keepalive_timeout   65;   # 保持连接的时间,也叫超时时间,单位秒
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;      # 文件扩展名与类型映射表
    default_type        application/octet-stream;   # 默认文件类型

    include /etc/nginx/conf.d/*.conf;   # 加载子配置项
  
    # server段配置信息
    server {
    	listen       80;       # 配置监听的端口
    	server_name  localhost;    # 配置的域名
  
    	# location段配置信息
    	location / {
    		root   /usr/share/nginx/html;  # 网站根目录
    		index  index.html index.htm;   # 默认首页文件
    		deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
    		allow 172.168.33.44;# 允许访问的ip地址,可以为all
    	}
  
    	error_page 500 502 503 504 /50x.html;  # 默认50x对应的访问页面
    	error_page 400 404 error.html;   # 同上
    }
}

总的来说,Nginx配置文件分三个大块:

  1. 全局块:主要设置Nginx服务器整体运行的配置指令,全局生效
  2. events块:主要设置,Nginx服务器与用户的网络连接,这块配置Nginx服务器性能有影响较大
  3. http块:主要设置代理、缓存、日志记录、第三方模块配置等,也是我们关注最多的块

接下来会对各个模块的主要配置参数进行说明

全局块

user

语法 user username [group]用于配置运行Nginx服务器的worker进程的用户和用户组,这样对于系统的权限访问控制的更加精细,也更加安全。具体使用方式,这里不多做说明,读者可自行查阅

work process

用于配置Nginx生成工作进程的数量,这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致,可以通过 设置 worker_processes auto 让Nginx根据当前服务器配置自动选择合适的大小

pid

用来配置Nginx当前master进程的进程号ID存储的文件路径,默认路径 /usr/local/nginx/logs/nginx.pid

daenon

设定Nginx是否以守护进程的方式启动, 默认为 on 后台进程形式,不会随着控制台关闭而关闭

events块

accept_mutex

用来设置Nginx网络连接序列化,默认值 accept_mutex on,由于nginx后台以多进程方式运行时,一个请求唤醒多个进程,最终只能有一个进程可以获取连接,这样会造成资源的浪费,影响性能。将accept_mutex 设置为on,会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢

worker_connections

worker 子进程能够处理的最大并发连接数,最大值为1024

multi_accept

用来设置是否允许同时接收多个网络连接,默认值 multi_accept off默认值时nginx一个工作进程只能同时接受一个新的连接,当一个链接。否则,一个工作进程可以同时接受所有的新连接

use

用来设置Nginx服务器选择哪种事件驱动来处理网络消息,不配置时Nginx根据操作系统决定,

可选值为:select、poll、kqueue、epoll、/dev/poll、eventport

http块

http块中我们主要关注server段的配置,其他部分这里不具体介绍,直接开始反向代理的配置,实操能直观的体会server块的功能

反向代理配置

配置一(实现代理)

实现效果:通过配置nginx实现请求转发tomcat

步骤一:创建一个tomcat,修改默认index页面方便后续做区分

# 1.使用docker创建tomcta
docker run -d --name my-tomcat -p 8080:8080 -v /root/tomcat/data:/usr/local/tomcat/webapps/ROOT tomcat

# 2.修改默认页面
echo "hello tomcat 8080" >> /root/tomcat/data/index.html

步骤二:创建一个nginx,修改默认配置文件nginx.conf 中的server块

# 1.使用docker创建nginx,因为我这里宿主机80端口已经被占用所以使用的是81
docker run -d --name nginx-demo -p 81:80 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/log:/var/log/nginx/ --restart=always nginx

# 2.修改nginx.conf配置文件内容,将默认server段信息替换成如下
# Nginx server块配置
    server {
    	listen       80;       # 配置监听的端口
  
        root /usr/share/nginx/html;  # 网站根目录  
        index index.html;            # 默认首页文件
  

	location / {
            # ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的   
            # 主机端口号,不要搞混了,虽然确实有点混👀️ 
    		proxy_pass http://172.17.0.1:8080;
    	}

    	error_page 500 502 503 504 /50x.html; 
    	error_page 400 404 /50x.html;   
    }

步骤三:直接访问你的服务器ip+81端口号,效果如下,证明代理成功

image-jrmw.png

配置二(实现根据路径名进行转发)

步骤一:创建另一个tomcat,内容跟第一个做区分

# 1.使用docker创建tomcta,第一个占用8080,所以第二个使用8081
docker run -d --name my-tomcat1 -p 8081:8080 -v /root/tomcat1/data:/usr/local/tomcat/webapps/ROOT tomcat

# 2.修改默认页面
echo "hello tomcat 8081" >> /root/tomcat1/data/index.html

步骤二:修改nginx配置文件server段内容为

# 1.使用docker创建nginx,因为我这里宿主机80端口已经被占用所以使用的是81
docker run -d --name nginx-demo -p 81:80 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/log:/var/log/nginx/ --restart=always nginx

# 2.修改nginx.conf配置文件内容,将默认server段信息替换成如下
# Nginx server块配置
    server {
    	listen       80;       # 配置监听的端口
  
        root /usr/share/nginx/html;  # 网站根目录  
        index index.html;            # 默认首页文件
  

	location /tomcat {
            # ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的   
            # 主机端口号,不要搞混了,虽然确实有点混👀️ 
    		proxy_pass http://172.17.0.1:8080;
    	}

	location /tomcat1 {
            # ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的   
            # 主机端口号,不要搞混了,虽然确实有点混👀️ 
    		proxy_pass http://172.17.0.1:8081;
    	}

    	error_page 500 502 503 504 /50x.html; 
    	error_page 400 404 /50x.html;   
    }

步骤三:分别访问两个不同路径,最终实现根据路径匹配转发

访问 ip:81/tomcat

image-sprx.png

访问ip:81/tomcat1

image-tyzw.png

配置三(负载均衡)

步骤一:修改nginx配置文件,添加upstream,将代理地址替换为upstream

# 添加upstream
	upstream tomcatServer {
			server 172.17.0.1:8080;
			server 172.17.0.1:8081;
        }

    # server段配置信息
    server {
    	listen       80;       # 配置监听的端口
  
        root /usr/share/nginx/html;  # 网站根目录  
        index index.html;            # 默认首页文件
  

	location /tomcat{
			# 将代理地址替换成前面配置的upstream
    		proxy_pass http://tomcatServer/;
    	}

步骤二:重启nginx,多次访问 ip:81/tomcat,通过响应的页面可以知道我们的请求被轮询转发到两个tomcat

image-ekyz.png

Nginx负载均衡的策略

轮询

Nginx默认的策略,通过前面测试可以看出,请求被Nginx逐次转发给上游服务器

hash 算法

通过指定关键字作为 hash key ,基于 hash 算法映射到特定的上游服务器中。关键字可以包含有变量、字符串

upstream tomcatServer {
            hash $request_uri;
			server 172.17.0.1:8080;
			server 172.17.0.1:8081;
        }

hash $request_uri 表示使用 request_uri 变量作为 hash 的 key 值,只要访问的 URI 保持不变,就会一直分发给同一台服务器

ip_hash

根据客户端的请求 ip 进行判断,只要 ip 地址不变就永远分配到同一台主机。它可以有效解决后台服务器 session 保持的问题

upstream tomcatServer {
            ip_hash;
			server 172.17.0.1:8080;
			server 172.17.0.1:8081;
        }

权重

根据设置的weight权重值进行转发,默认值为1,权重越大,被转发的概率越高

upstream tomcatServer {
			server 172.17.0.1:8080 weight=10; # 这个Nginx会被转发更多的请求
			server 172.17.0.1:8081 weight=2;
        }

fair

按照服务器的响应时间来分配请求,响应时间短的优先分配,充分利用服务器资源

upstream tomcatServer {
			server 172.17.0.1:8080;
			server 172.17.0.1:8081;
            fair;
        }

server 段配置参数

listen

配置监听的端口,默认80端口

listen       80;

server_name

配置的域名

server_name      www.nginx.site;

location

配置路径,我们的请求会匹配对应的的location路径,然后被代理到不同上游服务器

location /tomcat {
 
}

proxy_pass

配置代理服务器,匹配对应的location块后,请求会被转发到 proxy_pass 配置的对应上有服务器

  location /tomcat {
  	proxy_pass http://127.0.0.1/;
  }

upstream

用于定义上游服务器的相关信息,在proxy_pass中使用定义的upstream,就可以实现多服务器的负载均衡

	upstream tomcatServer {
			server 172.17.0.1:8080;
			server 172.17.0.1:8081;
        }

总结

本篇对Nginx的基础学习做了整理,包括常用的命令使用,配置文件参数介绍,以及使用nginx进行反向代理的实操测试。这里没有涉及到的知识还有很多,需要更多的学习🚀️

LICENSED UNDER CC BY-NC-SA 4.0