linux nginx搭建与配置

安装

  • 方法一,使用epel源
    安装epel源

yum -y install epel-release

出现epel源

[root@localhost yum.repos.d]# ls /etc/yum.repos.d/
CentOS-Base.repo       CentOS-Media.repo          epel.repo
CentOS-CR.repo         CentOS-Sources.repo        epel-testing.repo
CentOS-Debuginfo.repo  CentOS-Vault.repo
CentOS-fasttrack.repo  CentOS-x86_64-kernel.repo

yum -y install nginx

  • 方法二,使用官方提供的nginx源

rpm -uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
修改yum源
vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx.repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

启动Nginx并设置开机启动

systemctl start nginx.service
systemctl enable nginx.service
检查安装版本
nginx -v
重启
/usr/sbin/nginx -s stop
/usr/sbin/nginx -s reload

配置文件

配置文件位置:

/etc/nginx

[root@localhost yum.repos.d]# ls /etc/nginx
conf.d                  koi-utf             scgi_params
default.d               koi-win             scgi_params.default
fastcgi.conf            mime.types          uwsgi_params
fastcgi.conf.default    mime.types.default  uwsgi_params.default
fastcgi_params          nginx.conf          win-utf
fastcgi_params.default  nginx.conf.default
  • 查看nginx.conf主配置文件

  • 查找默认的安装位置

find / -name *nginx*

[root@localhost /]# find / -name *nginx*
/run/nginx.pid
/sys/fs/cgroup/systemd/system.slice/nginx.service
/etc/systemd/system/multi-user.target.wants/nginx.service
/etc/systemd/system/nginx.service.d
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/nginx.conf
/etc/nginx/nginx.conf.default
/var/tmp/systemd-private-9fbd51e7c0714a37bc28f8f7aee49468-nginx.service-CmQIIT
/var/lib/yum/yumdb/n/f8a4655b1aa3ca9c0275be2d64ea287e99fc7217-nginx-filesystem-1.20.1-9.el7-noarch
/var/lib/yum/yumdb/n/85502cf4b35f5368569b0b62e550755496b72249-nginx-1.20.1-9.el7-x86_64
/var/lib/nginx
/var/log/nginx
/tmp/systemd-private-9fbd51e7c0714a37bc28f8f7aee49468-nginx.service-szPRoy
/usr/bin/nginx-upgrade
/usr/sbin/nginx
/usr/lib/systemd/system/nginx.service
/usr/lib/systemd/system/nginx.service.d
/usr/lib64/nginx
/usr/share/doc/nginx-1.20.1
/usr/share/licenses/nginx-1.20.1
/usr/share/man/man3/nginx.3pm.gz
/usr/share/man/man8/nginx-upgrade.8.gz
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html/nginx-logo.png
/usr/share/vim/vimfiles/ftdetect/nginx.vim
/usr/share/vim/vimfiles/ftplugin/nginx.vim
/usr/share/vim/vimfiles/indent/nginx.vim
/usr/share/vim/vimfiles/syntax/nginx.vim

  • 查看启动的service配置
[root@localhost /]# cat /etc/systemd/system/multi-user.target.wants/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

可以发现安装到了/usr/sbin/nginx下

文件配置解读

[root@localhost /]# cat /etc/nginx/nginx.conf

# 运行用户
user nginx;
# 启动进程 一般与cpu数量相等
worker_processes auto;
# 全局错误日志
error_log /var/log/nginx/error.log;
# 进程日志文件位置
pid /run/nginx.pid;

# 包含了子配置文件
include /usr/share/nginx/modules/*.conf;
# 工作模式以及链接上限
events {

    use epoll;
    #epoll 是多路复用,IO模型中的一种,仅适用与linux2.6以上的内核,可以大大提高nginx的性能
    worker_connections 1024;
    #单个后台worker_processes 进程的最大并发数
}

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;
	# sendfile 指令指定nginx是否调用sendfile函数(zero copy 方式),来输出文件,对于普通应用必须设置为on,如果用来进行下载等应用IO负载应用,可设置为off,以平衡磁盘与网络io处理速度,降低系统的uptime
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    #链接超时时间
    keepalive_timeout   65;
    types_hash_max_size 4096;
	# 设定mime类型,类型由mime.types文件定义
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
	#开启gzip压缩
	gzip on;
	gzip_disable "MSIE [1-6]\.(?!.*SV1)";
    #设定请求缓冲
	client_header_buffer_size 1k;
	large_client_header_brffers 4 4k;
    include /etc/nginx/conf.d/*.conf;

	#设定负载均衡的服务器列表
	upstream myserver{
		#weight 表示权重
		server 192.168.31.10:8080 weight=3; 
		server 192.168.31.11:8080 weight=3; 
		server 192.168.31.12:8080 weight=3; 
	}

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

变量说明

变量名 含义
$remote_addr 用以记录客户端的ip地址
$http_x_forwarded_for 用以记录客户端的ip地址
$remote_user 用来记录客户端用户名称
$time_local 用来记录访问的时间与时区
$request 用来记录请求的url与请求协议(http/https)
$status 记录请求状态:成功时200等
$body_bytes_send 记录发送给客户端文件主体内容大小
$http_referer 记录从哪个页面链接过来的

nginx 基于域名的虚拟主机

server {
        listen       80;
        listen       [::]:80;
        server_name  myserver my.server;
        location = / {
        	root /nginx/html;
        	index index.html index.htm;
        }
     
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        	root html;
        }
      }

反向代理

  • 代理分为两种:正向代理 ,反向代理

正向代理即代理的时服务端:如客户端访问 www.baidu.com,客户端发送请求到我们的代理端,假设是nginx,nginx再转发请求到www.baidu.com,nginx再把请求结果返回给客户端。
反向代理即服务端代理 :如客户端访问的是nginx服务192.168.31.10/search,但是,nginx服务器访问了服务www.baidu.com/search,将结果返回给客户端。

  • 反向代理配置
配置参数 说明
proxy_pass 真实web/app服务器IP地址
proxy_redirect 如果真实服务器使用的时真的IP非默认端口,则改成ip+默认端口
proxy_set_header 重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP 启用客户端真实地址(如果未启用,Nginx的日志,记录的只有当前层代理日志,不会追溯源地址)
proxy_set_header X-Forwarded-For 记录代理地址
proxy_connect_timeout 后端服务器链接的超时时间,发起三次握手的等待超时时间
proxy_send_timeout 后端服务器传回数据时间,在规定的时间内必须完成传输
proxy_read_timeout nginx接收upstream(上游/真实)server数据超时,默认60s,如果连续的60s内没有接收到一个字节,连接关闭
proxy_buffering on 开启缓存
proxy_buffer_size 只是响应头的缓冲大小
proxy_buffers 4 128k 内容缓冲区域大小,一般设置的比较大,以响应网页,单个缓冲区的大小由系统内存叶决定,一般4k,proxy_buffers由缓冲数和缓冲区大小组成,总大小为number*size
proxy_busy_buffers_size 256k 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方
proxy_max_temp_file_size 256k 超大的响应头存储文件
server {
        listen       80;
        server_name  www.mytest.com;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        # include /etc/nginx/default.d/*.conf;
		 location = / {
		 	proxy_pass http://192.168.31.11:80;
		 	proxy_set_header Host $http_host;
		 	proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
		 	proxy_set_header X-Real-Proto $scheme;
		 	proxy_set_header X-Nginx-Proxy true;
			
			proxy_connect_timeout 30;
			proxy_send_timeout  60;
			proxy_read_timeout  60;

			proxy_buffering on;
			proxy_buffer_size 32k;
			proxy_buffers 4 128k;
			proxy_busy_buffers_size  256k;
			proxy_max_temp_file_size 256k;
			 
        }


        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

Nginx 负载均衡

基于反向代理,在我们需要减轻服务器的压力时,需要反向代理多台服务器,从而减少单台服务器压力。

upstream webapp {
	server 192.168.31.11:80;
	server 192.168.31.12:80;
}
server {
	listen 80;
	server_name localhost;
	location / {
		proxy_pass http://webapp; 
	}
}

  • 热备配置
upstream webapp {
	server 192.168.31.11:80;
	server 192.168.31.12:80 backup; #热备
}

  • 轮询权重配置
upstream webapp {
	server 192.168.31.11:80 weight=1;
	server 192.168.31.12:80 weight=2;
}

  • ip_hash,根据客户端ip去hash访问:即同一个ip访问到的一定时同一个服务器
upstream webapp {
	ip_hash;
	server 192.168.31.11:80 ;
	server 192.168.31.12:80 ;
}

案例

服务A:http:127.0.0.1:8081/****
服务B:http:127.0.0.1:8082/**** , http:127.0.0.1:8083/****
配置反向代理两个服务:

upstream user_server{
      #weight 表示权重
      server 127.0.0.1:8080 weight=3;
}
upstream goods_server{
    #weight 表示权重
    server 127.0.0.1:8081 weight=3;
    server 127.0.0.1:8082 weight=3;
}

server {
        listen       80;
        listen       [::]:80;
        server_name  localhost;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /user {
        				# 这里需要将uri去掉,因为目标路径没有这个/user   ,如果实际路径存在就不用这么处理,直接使用 http://user_server就可以了
                        set $proxy_server http://user_server;
                        if ( $request_uri ~* ^/user/(.*)$ ) {
                                set $proxy_server http://user_server/$1;
                        }
                        proxy_pass $proxy_server;
                        proxy_set_header Host $http_host;
                        proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
                        proxy_set_header X-Real-Proto $scheme;
                        proxy_set_header X-Nginx-Proxy true;

                        proxy_connect_timeout 30;
                        proxy_send_timeout  60;
                        proxy_read_timeout  60;

                        proxy_buffering on;
                        proxy_buffer_size 32k;
                        proxy_buffers 4 128k;
                        proxy_busy_buffers_size  256k;
                        proxy_max_temp_file_size 256k;

        }
        location /goods {
                        # 也可以在http://goods_server/ 添加上 / 结尾,这样也能起到如上一样的效果,这个方案推荐使用
                        proxy_pass http://goods_server/;
                        proxy_set_header Host $http_host;
                        proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
                        proxy_set_header X-Real-Proto $scheme;
                        proxy_set_header X-Nginx-Proxy true;

                        proxy_connect_timeout 30;
                        proxy_send_timeout  60;
                        proxy_read_timeout  60;

                        proxy_buffering on;
                        proxy_buffer_size 32k;
                        proxy_buffers 4 128k;
                        proxy_busy_buffers_size  256k;
                        proxy_max_temp_file_size 256k;

        }

    }

代理多个ip,实现公网访问

需要实现公网 IP+端口来访问,比如邮件 API 使用 http://192.168.1.10:125 Ps:公网服务器是多线的,那么就有多个 IP,本文假设电信是 192.168.1.10,联通是 192.168.2.10,移动是 192.168.3.10 等

#新增的IP映射配置
server {
        listen 80;
        server_name 192.168.1.10 192.168.2.10 192.168.3.10;
        location /mail_api/ {
            proxy_pass      http://DemoBackend/; #后面的斜杠不能少,作用是不往后端传递/mail-api 这个路径
            proxy_redirect  off;
            proxy_set_header  Host  mailapi.domain.com; #传递不同的host给后方节点,实现IP和域名均可以访问
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location /other_api1/ {
            proxy_pass      http://DemoBackend/; 
            proxy_redirect  off;
            proxy_set_header  Host  otherapi1.domain.com;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        #还可以添加更多映射,通过不同的路径来映射不同的API,最后对于直接访问IP则返回403,防网络上的扫码探测
	location / {
	    return 403;
	}
}

#原有的域名映射
server {
     listen 80;
     server_name mailapi.domain.com;
     location / {
	    proxy_pass      http://DemoBackend;
        proxy_redirect  off;
        proxy_set_header  Host  $host;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}
server {
     listen 80;
     server_name otherapi1.domain.com;
     location / {
	    proxy_pass      http://DemoBackend;
        proxy_redirect  off;
        proxy_set_header  Host  $host;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}
#简单的节点配置(当这些API都用到同一个Backend时,上述代码中的proxy_set_header传递的host就起到了关键性作用!)
upstream DemoBackend {
     server 192.168.10.1;
     server 192.168.10.2;
     ip_hash;
 }

Nginx会话保持(同一ip持续访问到一个服务器)

  • ip_hash

upstream webapp {
ip_hash;
server 192.168.31.11:80 ;
server 192.168.31.12:80 ;
}

ip_hash使用原地址哈希算法,将同一客户端的请求总是发往同一台服务器
当后端服务宕机后不可用
不适于前端还有代理的情况,必须是只有一层代理,如果有两层代理就不可用
同一局域网的客户会被发送到同一台服务器

  • sticky_cookie_insert
    使用sticky_cookie_insert启用会话亲情关系,这会导致来自同一客户端的请求被传递到一组服务器的同一台服务器,与ip_hash不同的是,他不是基于ip来判断客户端的,而是基于cookie来判断,一次避免了上述ip_hash中来自同一局域网的客户端丢失负载均衡的情况。

upstream webapp {
server 192.168.31.11:80 ;
server 192.168.31.12:80 ;
sticky_cokkie_insert srv_id expires=1h domain=3evip.cn path=/;
}

说明:
expires :浏览器保持cookie的时间
domain :定义cookie的域
path:为cookie定义路径

Nginx 地址重写rewrite

  • 定义:RUL重写,把传入web端的请求,重定向到其他url
  • 语法:

server {
rewrite regex replacement [flag];
}
使用regex匹配 URI,并将匹配到的 URI 替换成新的 URI(replacement ) 。如果由多个rewrite,执行顺序从上到下执行,匹配到一个依旧会向下继续匹配,知道返回最后一个匹配为止。如果中途停止需要使用flag参数。
如果 replacement 包含了协议信息:http/https,则请求就直接返回302重定向终止了。
如果,在浏览器接收到30x状态码,会再度请求rewrite之后的地址,最终得到所想要的结果。

flag种类

flag 说明
last 停止所有rewrite的相关指令,然后使用新的URI进行location匹配
break 停止所有rewrite相关指令,和last不同的时,last会继续使用新的URI匹配location,而break则是直接使用挡墙的URI进行请求,能避免重复rewrite,last一般在server,break一般在location
redirect url中不包含协议如:http,但是依然希望它返回30x,让浏览器二期请求后获取到结果就需要redirect
permanent 和redirect像是,但是它直接返回301永久重定向
  • 案例一:http://my.com/a/1.html => http://my.com/b/1.html
server{
	listen 80;
	server_name my.com;
	
	location /a{
		root /html;
		index index.html;
		rewrite .* /b/1.html permanent;
	}
	location /b{
		root /html;
		index index.html;
	}
}
  • 案例二:http://my.com/2021/a/1.html => http://my.com/2022/a/1.html
server{
	listen 80;
	server_name my.com;
	
	location /2021/a{
		root /html;
		index index.html;
		rewrite ^/2021/(.*)$ /2022/$1 permanent;
	}
	location /2022/a{
		root /html;
		index index.html;
	}
}

(.*)$ 表示以任意字符结尾的字符 $1 表示匹配中前面正则表达式的第一个()中内容

  • 案例三:http://my.com/biz/1.html => http://my.com/newbiz/1.html
server{
	listen 80;
	server_name my.com;
	
	location /biz{
		root /html;
		index index.html;
		rewrite ^/biz/(.*)$   http:$host/newbiz/$1;
	}
	location /newbiz/a{
		root /html;
		index index.html;
	}
}

Nginx 常用指令

if指令

if(条件){
rewrite …;
}
对至此哪个的条件进行判断,表达式只有一个变量时,如果指为空或者任意以0开始的字符串都会当成false
常用表达式

表达式 说明
= 或者 != 直接比较变量
~ 区分大小写的正则表达式匹配
~* 不区分大小写的正则表达式匹配
!~ 不匹配
-f 和 !-f 文件是否存在
-d 和!-d 目录是否存在
-e 和 !-e 文件或者目录存在
-x 和 !-x 判断文件是否可执行
  • 案例一:http://my.com/ => http://mynew.com/
server{
	listen 80;
	server_name my.com;
	
	location /{
		root /html;
		if($host ~* my.com){
			rewrite .*   http://mynew.com/ permanent;
		}
	}
}
  • 案例二:http://my.com/a/1.html => http://mynew.com/a/1.html
server{
	listen 80;
	server_name my.com;
	
	location /{
		root /html;
		if($host ~* my.com){
			rewrite .*   http://mynew.com$request_uri permanent;
		}
	}
}

set 指令

  • 案例一:多次rewrite set值
    http://tom.my.com => http://my.com/tom
    http://jack.my.com => http://my.com/jack

hosts文件修改
127.0.0.1 tom.my.com
127.0.0.1 jack.my.com
127.0.0.1 my.com

server{
	listen 80;
	server_name my.com;
	
	location /{
		root /html;
		if($host ~* ^my\.com*){
			break;
		}
		if($host ~* ^(.+)\.my\.com$){
			ser $user $1 
			rewrite .* http://my.com/$user permanent;
		}
	}
	location /tom{
		root /html;
		index index.html;
	}
	location /jack{
		root /html;
		index index.html;
	}
}

return指令

用户返回状态码给客户端

  • 应用环境:server location if
  • 案例一
    访问 .sh文件返回403操作拒绝错误
server{
	listen 80;
	server_name my.com;
	location ~* \.sh${
		return 403;
	}
}
  • 案例二
    80 => 443端口
server{
	listen 80;
	server_name my.com;
	return 301 https://my.com$request_uri;
}
server{
	listen 443 ssl;
	server_name my.com;
	ssl on;
	ssl_certificate /root/server.crt;
	ssl_certificate_key /root/server.key;

	location / {
		root /html;
		index index.html;
	}

}

location指令详解

nginx的http配置主要包括三个区块,结构如下:

http {											#协议级别区块
	include mime.types;
	default_type application/octet-stream;
	keepalive_timeout 65;
	gzip on;
		server{									#服务级别区块
			listen 80;
			server_name localhost;
			location / {						#请求uri级别区块
				root /html;
				index index.html;	
			}
		}


}

  • location段在server中,根据不同的uri使用不同的配置,来处理不同的请求
  • location是有顺序的。
  • 基本语法

location [ =|~|~*|^~|@] pattern {…}

前缀 含义
= 精确匹配,优先级最高
^~ 表示url一某个常规字符串开头,理解为匹配url路径即可
~ 表示区分大小的正则匹配
~* 表示不区分大小写的正则匹配
!~ 区分大小写的不匹配
!~* 不区分大小写的不匹配
/ 通用匹配,任何请求都会匹配
@ 内部跳转

你可能感兴趣的:(linux,笔记,nginx,nginx,linux,centos)