Nginx从入门到实践(一)

结合实践、收集各种场景、常见问题,讲解Nginx中最实用的Webserver场景,提供一套整体的搭建配置方式

Nginx中间件,不局限于业务逻辑,有效独立于后台开发框架(不论后端是Java开发、PHP开发、或者其他语言框架)都能做到平台通用

不仅重实践、也会结合原理(如:Http协议、操作系统),让你理解背后的原理更有利于你解决实际问题(如:bug解决、二次开发等)

基础篇

环境调试确认

yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
cd /opt;mkdir app download logs work backup

关闭iptables

# 查看
iptables -L

# 关闭
iptables -F

# 查看
iptables -t nat -L

# 关闭
iptables -t nat -F

Nginx优势

  • 多路IO复用
  • 使用Epoll模型
  • 轻量级
  • CPU亲和
  • sendfile

安装

http://nginx.org/en/linux_packages.html#stable

vim /etc/yum.repos.d/nginx.repo 

内容如下S

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
yum install nginx
# 查看版本
nginx -v

# 查看安装编译参数
nginx -V

基本参数使用

安装目录

rpm -ql nginx

路径 类型 作用
/etc/logrotate.d/nginx 配置文件 nginx日志轮转,用于logrotate服务的日志切割
/etc/nginx
/etc/nginx/nginx.confd
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
目录,配置文件 nginx主配置文件
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/fastcgi_params
配置文件 cgi配置相关,fastcgi配置
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/win-utf
配置文件 编码转换映射转化文件
/etc/nginx/mime.types 配置文件 设置http协议的Content-Type与扩展名对应关系
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
配置文件 用于配置出系统守护进程管理器管理方式
/usr/lib64/nginx/modules
/etc/nginx/modules
目录 nginx模块目录
/usr/sbin/nginx
/usr/sbin/nginx-debug
命令 nginx服务的启动管理的终端命令
/usr/share/doc/nginx-1.14.2
/usr/share/doc/nginx-1.14.2/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
文件, 目录 nginx的手册和帮助文件
/var/cache/nginx 目录 nginx的缓存目录
/var/log/nginx 目录 nginx的日志目录
安装编译参数

nginx -V

编译选项 作用
--prefix=/etc/nginx
--sbin-path=/usr/sbin/nginx
--modules-path=/usr/lib64/nginx/modules
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
安装目的目录或路径
--http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
执行对应模块时,nginx所保留的临时性文件
--user=nginx
--group=nginx
设定nginx进程启动的用户和组用户
--with-cc-opt=parameters 设置额外的参数将被添加到CFLAGS变量
--with-ld-opt=parameters 设置附加的参数,链接系统库

默认配置语法

- - -
user 设置nginx服务的系统使用用户
worker_processes 工作进程数
error_log nginx的错误日志
pid nginx服务启动时候pid
events worker_connections
use
每个进程允许最大连接数
工作进程数

log

http://nginx.org/en/docs/http/ngx_http_log_module.html

错误日志,格式如下

2018/12/11 15:51:32 [error] 5809#5809: *37 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 120.194.101.83, server: _, request: "GET /favicon.ico HTTP/1.1", host: "120.79.65.88", referrer: "http://120.79.65.88/"

error_log /var/log/nginx/error.log warn;

日志存放位置/var/log/nginx/error.log

级别warn

access_log 记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息,形式如下

222.88.236.165 - - [11/Dec/2018:16:38:42 +0800] "GET /static/js/login.js HTTP/1.1" 200 14459 "http://mxonline.iceflower.xyz:8081/login/?next=/course/info/6/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36" "-"

格式设置

    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;

具体的设置可以在官网中找到,可进行自定制

模块

http://nginx.org/ru/docs/http/ngx_http_stub_status_module.html

sub_status

--with-http_stub_status_module nginx的客户端状态

配置nginx文件,写在server中

location = /mystatus {
    stub_status;
}

重启nginx,浏览器访问IP+/mystatus,格式如下

Active connections: 1
server accepts handled requests
 43 43 79
Reading: 0 Writing: 1 Waiting: 0 

Active connections

当前活动客户端连接数,包括Waiting连接数。

accepts

已接受的客户端连接总数。

handled

处理的连接总数。通常,参数值与accepts 除非已达到某些资源限制(例如, worker_connections限制)相同。

requests

客户端请求的总数。

Reading

nginx正在读取请求标头的当前连接数。

Writing

nginx将响应写回客户端的当前连接数。

Waiting

当前等待请求的空闲客户端连接数。

random_index

http://nginx.org/en/docs/http/ngx_http_random_index_module.html

--with-http_random_index_module 目录中选择一个随机主页

location / {
    root /opt/app/code/html;
    random_index on;
}

root 后面是主页面存放位置

不会选择隐藏文件作为主页面

sub_module

http://nginx.org/en/docs/http/ngx_http_sub_module.html

--with-http_sub_module HTTP内容替换

location / {
    sub_filter ‘<a href="http://127.0.0.1:8080/‘  ‘<a href="https://$host/‘;
    sub_filter ‘<img src="http://127.0.0.1:8080/‘ ‘<img src="https://$host/‘;
    sub_filter_once on;
}

敏感词,流媒体替换

请求限制

limit_conn_module

limit_conn_module 连接频率限制

http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    ...

    server {

        ...

        location /api/ {
            limit_conn addr 10;
            limit_conn_status 503;
        }
    }
}

示例中定义key(zone=addr)为addr,分配内存大小为10m(zone=addr:10m)(如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回503),同一个ip($binary_remote_addr)和服务器连接超过10个(limit_conn addr 10)将会被拦截并返回503(limit_conn_status 503)错误码

limit_conn_zone
语法: limit_conn_zone key zone=name:size;(设置限制规则、区域名称及分配的内存大小)
可配置区域: http
key: 必选项;设置限制规则;取值可以是text文本、nginx变量或两者的组合;实例中使用的nginx变量$binary_remote_addr表示根据每个ip限制并发
name: 必选项; 自定义一个区域名称; 任意字符串
size: 分配内存的大小

limit_conn
语法: limit_conn zone number; (使用由limit_conn_zone定义的拦截规则, 并设置具体的限制连接数量)
可配置区域: http, server, location
zone: 必选项; 由limit_conn_zone(zone=name)定义的名称; 表示使用定义的哪个限制规则
number: 必选项; 正整数; 表示具体的限制连接数量

limit_conn_status
语法: limit_conn_status code;
默认值: 503
可配置区域: http, server, location
表示超出limit_req配置的请求数量后返回给客户端的错误码使用该指令
  

limit_conn_log_level
语法: limit_conn_log_level info | notice | warn | error;
默认值: limit_conn_log_level error;
可配置区域: http, server, location
当服务器拒绝处理由于速率超过或延迟请求处理而拒绝处理请求时,设置所需的日志记录级别。
limit_req_module

limit_req_module 请求频率限制

http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

http {
    limit_req_zone $binary_remote_addr zone=req_perip:50m rate=10r/s;

    ...

    server {

        ...

        location /api/ {
                limit_req zone=req_perip burst=50 nodelay;
                limit_req_status 503;
        }
    }
}

示例中定义的区域名称为req_perip(zone=req_perip),分配内存大小为50m(如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回503),同一个ip($binary_remote_addr)平均处理的请求频率不能超过每秒10次(rate=10r/s); 如果超过每秒10次但超过的请求数量小于等于50(burst=50)时,会延迟请求。如果超过每秒的请求数超过50,则立即返回503(limit_req_status 503)给客户端

limit_req_zone
语法: limit_req_zone key zone=name:size rate=rate;(可理解为该指令用来定义限制请求频率)
可配置区域: http
key: 必选项;取值范围: 1,text(文本); 2,nginx变量;3,text和nginx变量的组合; name: 必选项;自定义字符串
size: 必选项;分配内存大小,用来保存键值的状态参数
rate: 必选项;每秒可请求的频率(r/s), 或每分钟可请求的频率(r/m)
  

limit_req
语法: limit_req zone=name [burst=number] [nodelay]; (可理解为使用定义的限制请求频率,一定是先定义后使用!也就是一定要有limit_req_zone指令的配置后才能使用该配置)
可配置区域: http, server, location
name: 必选项;自定义字符串, 名字必须与limit_req_zone中zone=name这个名字一致
number: 必选项;正整数数字, 平均每秒允许不超过limit_req_zone指令中rate规定的请求数,并且不会超过该值所指定数量的请求,可延迟请求的数量
nodelay: 可选配置,表示请求频率超过rate规定值后又超过burst规定值后立即返回客户端503(可设置返回code)
  

limit_req_status
语法: limit_req_status code;
默认值: 503
可配置区域: http, server, location
表示超出limit_req配置的请求数量后返回给客户端的错误码使用该指令
  

limit_req_log_level
语法: limit_req_log_level info | notice | warn | error;
默认值: limit_req_log_level error;
可配置区域: http, server, location
当服务器拒绝处理由于速率超过或延迟请求处理而拒绝处理请求时,设置所需的日志记录级别。

$binary_remote_addr是$remote_addr(客户端IP)的二进制格式,固定占用4个字节。而$remote_addr按照字符串存储,占用7-15个字节。用$binary_remote_addr可以节省空间。

访问控制

http_access_module

http_access_module 基于IP的访问控制

http://nginx.org/en/docs/http/ngx_http_access_module.html

location / {
    deny  192.168.1.1;  # 拒绝访问
    allow 192.168.1.0/24;   # 允许访问
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;   # IPV6
    deny  all;
}

局限性

IP1 客户端

IP2 代理服务器

IP3 服务器

基于客户端的IP,但是对于Nginx来说,它不会管你哪个是真正的客户端,如果我们的访问不是客户端与服务端直接连接,而是通过了一层代理,比如它的代理可以负载均衡、CDN的这种代理实现,也就是我们的访问不是客户端直接访问的服务端,而是通过其他的中间件访问服务端,这时候会出现一个问题,因为Nginx的access_module它是基于remote_addr这个变量来识别客户端的IP的,那么如果一个ip通过中间件访问服务端,那么Nginx认为访问的ip就是中间件的IP,那么我们在基于IP做限制的时候,那么其实是没有作用的。所以这样的话,准确性是不高的,所以就是利用nginx的access_module有局限性。

解决办法

  • 使用http_x_forwarded_for来解决这个问题

    但是http_x_forwarded_for进行访问控制会存在问题,因为是一个协议要求的,并不是所有的cdn和代理厂商它会按照要求来做,甚至x_forwarded_for存在被修改的可能,因为只是一个头信息,所以最终还是不真实。

    http_x_forwardded_for也是Nginx的http头变量的一个常用的变量,它和remote_addr是有区别的。不同的是,x_forwarded_for是http协议中规定头中要携带的,所以在客户端访问中间件,再访问服务端的时候,那么服务端通过Nginx会记录真实IP和中间件的IP。

    格式:http_x_forwarded_for = 客户端ip,第一台代理ip,第二台代理ip,第N台代理ip....,所以http_x_forwarded_for是由一连串以逗号分隔的ip组成的。

  • 结合geo模块

    http://nginx.org/ru/docs/http/ngx_http_geo_module.html

  • 通过HTTP自定义变量传递
http_auth_basic_module

http_auth_basic_module 基于用户的信任登录

http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

location / {
    auth_basic           "输入密码";
    auth_basic_user_file user_passwd;
}

htpasswd安装

yum install httpd-tools -y

首次创建并加入

htpasswd -c ./user_passwd admin

[[email protected] nginx]# cd /etc/nginx/
[[email protected] nginx]# ls
conf.d     fastcgi_params  koi-win     modules     nginx.conf.rpmnew  uwsgi_params
default.d  koi-utf         mime.types  nginx.conf  scgi_params        win-utf
[[email protected] nginx]# htpasswd -c ./user_passwd admin
New password:
Re-type new password:
Adding password for user admin
[[email protected] nginx]# ls
conf.d     fastcgi_params  koi-win     modules     nginx.conf.rpmnew  user_passwd   win-utf
default.d  koi-utf         mime.types  nginx.conf  scgi_params        uwsgi_params
[[email protected] nginx]# vim user_passwd
[[email protected] nginx]# cat user_passwd
admin:$apr1$I04BhX5R$9JexKOl2aYCe.Tww67XMu0
[[email protected] nginx]# 

http_auth_basic_module局限性

用户信息依赖文件方式,管理操作机械,效率不高

解决方法:

Nginx结合LUA实现高效验证

Nginx结合LDAP,利用nginx_auth_ldap模块

原文地址:https://www.cnblogs.com/gaoyongjian/p/10105368.html

时间: 2024-11-09 17:52:11

Nginx从入门到实践(一)的相关文章

Nginx视频教程|Nginx从入门到实践

Nginx从入门到实践网盘地址:https://pan.baidu.com/s/1kXf6pH9 密码:0iud备用地址(腾讯微云):https://share.weiyun.com/76db50c30a433f512db3d80692fbb299 密码:WOrWdY 第1章 课程前言总览课程,介绍课程学习须知,环境准备,了解课程意义. 第2章 基础篇讲解Nginx的快速部署安装.模块.基础配置语法.Nginx的日志输出.Nginx默认配置模块.Nginx对于请求的处理,访问控制模块使用,并区别

Nginx反向代理入门到实践

Nginx反向代理入门到实践 Nginx反向代理的作用: 由于公司内网有多台服务器的http服务要映射到公司外网静态IP,如果用路由的端口映射来做,就只能一台内网服务器的80端口映射到外网80端口,其他服务器的80端口只能映射到外网的非80端口.非80端口的映射在访问的时候要域名加上端口,比较麻烦.并且公司入口路由最多只能做20个端口映射.肯定以后不够用. 然后发现可以在内网搭建一个nginx反向代理服务器,将nginx反向代理服务器的80映射到外网IP的80,这样指向到公司外网IP的域名的HT

Nginx入门到实践-Nginx 中间件

第1章 课程前言总览课程,介绍课程学习须知,环境准备,了解课程意义.1-1 课程介绍1-2 学习环境准备 第2章 基础篇讲解Nginx的快速部署安装.模块.基础配置语法.Nginx的日志输出.Nginx默认配置模块.Nginx对于请求的处理,访问控制模块使用,并区别介绍连接限制与请求限制.2-1 什么是Nginx2-2 常见的中间件服务2-3 Nginx优势多路IO复用2-4 Nginx使用Epoll模型的优势介绍2-5 Nginx-CPU亲和2-6 Nginx-sendfile2-7 Ngin

nginx配置入门

谢谢作者的分享精神,原文地址:http://www.nginx.cn/591.html nginx配置入门 之前的nginx配置是对nginx配置文件的具体含义进行讲解,不过对于nginx的新手可能一头雾水. 今天看到个文档不错,翻译过来分享给大家,可以让新手更详细地了解nginx配置,可以说是nginx配置入门必备. Nginx是一个轻量级高性能的web服务器,它是为快速响应大量静态文件请求和高效利用系统资源而设计的.与apache使用面向进程或线程的方式处理请求不同,nginx使用异步事件驱

《SaltStack技术入门与实践》—— 实践案例 &lt;中小型Web架构&gt;3 Memcached配置管理

实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态数据库驱动网站的访问速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通

&lt;&lt;Python编程:从入门到实践&gt;&gt;踩坑记 Django

<<Python编程:从入门到实践>>踩坑记 Django Django Python 19.1.1.5 模板new_topic 做完书上的步骤后,对主题添加页面经行测试,但是浏览器显示 服务器异常. 个人采用的开发环境是virtual studio code , 测试起来很是难受,因为我配置的debug环境,断点操作没有作用. 经过我不断的测试,才发现我失败的原因是由于之前的误操作,先建立new_pizzas.py后改为new_pizzas.html的,错误就在这里.在我之后新建

嵌入式LINUX入门到实践

从今天开始,用这个博客记录和总结嵌入式LINUX从入门到实践完整过程. 第一章的内容是IIC协议与自平衡小车.首先树立目标: 1.使用mini2440开发板的IIC协议,采集MPU6050六轴传感器数据. 2.将步骤1整理为驱动,写入LINUX内核. 3.编写简单的上位机3D模型,实时显示传感器状态. 4.完善上述三步骤,完成平衡小车的硬件. 5.搭建基于2440芯片的自平衡小车平台,包括机械与电路部分. 6.完成自平衡小车的平衡. 7.完成自平衡小车的前进和转向. 8.加入安卓端,进行简单的手

Nginx快速入门菜鸟笔记

Nginx快速入门-菜鸟笔记   1.编译安装nginx 编译安装nginx 必须先安装pcre库. (1)uname -a 确定环境 Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux (2)yum install -y pcre pcre-devel -y 必须安装pcre库(实现nginx rewrite模块功

《Python编程从入门到实践》_第十章_文件和异常

读取整个文件 文件pi_digits.txt #文件pi_digits.txt 3.1415926535 8979323846 2643383279 下面的程序打开并读取整个文件,再将其内容显示到屏幕中: with open("pi_digits.txt") as fileobject: contents = fileobject.read() print(contents) #运行结果 3.1415926535 8979323846 2643383279 使用函数open()打开文件