20190802_Nginx基础

20190802_Nginx基础

文章主要内容:

关于中间件比较通俗易懂的解释

个人理解:将具体业务和底层逻辑解耦的组件。

大致的效果是:需要利用服务的人(前端写业务的),不需要知道底层逻辑(提供服务的)的具体实现,只要拿着中间件结果来用就好了。

介于操作系统和应用程序之间的产品,中间件简单解释,你可以理解为面向信息系统交互,集成过程中的通用部分的集合,屏蔽了底层的通讯,交互,连接等复杂又通用化的功能,以产品的形式提供出来,系统在交互时,直接采用中间件进行连接和交互即可,避免了大量的代码开发和人工成本。其实,理论上来讲,中间件所提供的功能通过代码编写都可以实现,只不过开发的周期和需要考虑的问题太多,逐渐的,这些部分,以中间件产品的形式进行了替代。

比如常见的消息中间件,即系统之间的通讯与交互的专用通道,类似于邮局,系统只需要把传输的消息交给中间件,由中间件负责传递,并保证传输过程中的各类问题,如网络问题,协议问题,两端的开发接口问题等均由消息中间件屏蔽了,出现了网络故障时,消息中间件会负责缓存消息,以避免信息丢失。相当于你想给美国发一个邮包,只需要把邮包交给邮局,填写地址和收件人,至于运送过程中的一系列问题你都不需要关心了。

通俗易懂的例子:我开了一家炸鸡店(业务端),然而周边有太多屠鸡场(底层),为了成本我肯定想一个个比价,再综合质量挑选一家屠鸡场合作(适配不同底层逻辑)。由于市场变化,合作一段时间后,或许性价比最高的屠鸡场就不是我最开始选的了,我又要重新和另一家屠鸡场合作,进货方式、交易方式等等全都要重来一套(重新适配)。然而我只想好好做炸鸡,有性价比高的肉送来就行。于是我找到了一个专门整合屠鸡场资源的第三方代理(中间件),跟他谈好价格和质量后(统一接口),从今天开始,我就只需要给代理钱,然后拿肉就行。代理负责保证肉的质量,至于如何根据实际性价比,选择不同的屠鸡场,那就是代理做的事了。

--------------------------------------------------------------------------------------------------------------------------------------------

在网站后台,往往存在很多应用服务,对应的是操作系统驱动硬件提供对应的服务。在很多应用的情况下,应用与应用之间直接调用,或应用直接与操作系统交互,会导致层次化的应用不够隔离,代码耦合程度高。此时需要中间件代理处理一些请求,让应用只负责业务的逻辑处理。

大型网站中,中间件一个个串联,使得网站层次性更高,维护更简单。

中间件还有web请求负载均衡,http请求缓存服务,安全应用防控等作用。

 

Nginx简述

Nginx是一个开源且高性能、可靠的HTTP中间件(企业应用场景最多)、代理服务。

常见HTTP服务:HTTPD,IIS,GWS(不对外开放)

Nginx特性优点:

  1. IO多路复用epoll:IO多路复用解决方案有select、poll和epoll,epoll是select和poll的增强版本,更灵活,没有描述符限制,效率更高
  2. 轻量级:功能模块少,代码模块化
  3. CPU亲和(affinity,一种把CPU核心和nginx工作进程绑定的方式):通过把每个worker进程固定在一个cpu上执行,减少切换cpu的cache miss,获得更好性能
  4. 采用sendfile使得nginx处理静态文件的效率非常有优势:sendfile机制,静态文件直接通过内核空间传递给socket,而不需要进一步经过用户空间的逻辑性的处理。

 

Nginx环境配置以及安装

安装Nginx前的环境配置:

  • 系统能上外网,确认yum可用,需要通过yum来安装装一些编译环境和实用软件;
  • 禁用iptables,firewall防火墙;
  • 禁用SELinux
cd /opt
mkdir app dpwnload logs work backup
yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake
yum install -y wget httpd-tools vim

配置好环境后,到Nginx官网:http://nginx.org/en/linux_packages.html#RHEL-CentOS,复制对应系统的yum源参数,其中nginx-stable是稳定版,nginx-mainline为开发版,实际应用中当然选稳定版。

vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

安装nginx:

yum install -y nginx
#查看nginx版本 nginx
-v
#查看nginx编译参数 nginx
-V
#启动nginx服务
nginx

 

Nginx的目录和配置语法

查看nginx安装目录:rpm -ql nginx

路径

类型

作用

/etc/logrotate.d/nginx

配置文件

Nginx日志轮转,用于logrotate服务的日志切割

/etc/nginx

/etc/nginx/nginx.conf

/etc/nginx/conf.d

/etc/nginx/conf.d/default.conf

目录、配置文件

Nginx主配置文件。默认配置下nginx.conf中加载了default.conf

/etc/nginx/fastcgi_params

/etc/nginx/uwsgi_params

/etc/nginx/scgi_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.16.0

/usr/share/doc/nginx-1.16.0/COPYRIGHT

/usr/share/man/man8/nginx.8.gz

文件、目录

Nginx的手册和帮助文件

/var/cache/nginx

目录

Nginx的缓存目录

/var/log/nginx

目录

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

设置附加的参数,链接系统库

 

完整的nginx配置文件结构

一个http可以有多个server,一个server可以有多个location

nginx服务会先读取主配置文件nginx.conf,默认的nginx.conf的最后有一句“include /etc/nginx/conf.d/*.conf”,即会读取该目录下的所有conf文件。

nginx服务主配置文件/etc/nginx/nginx.conf的参数解释:

user  nginx;    #指定Nginx的worker进程运行用户以及用户组,默认为nginx
worker_processes  1;    #指定Nginx要开启的进程数,一般与cpu核心数一样即可

error_log  /var/log/nginx/error.log warn;    #用来定义全局错设日志文件的路径和日志名称。日志输出级别有debug,info,notice,warn,error,crit可供选择,其中debug输出日志最为详细,面crit输出日志最少。
pid        /var/run/nginx.pid;    #用来指定进程id的存储文件位置。

events {    #设定nginx的工作模式及连接数上限
    worker_connections  1024;    #设置nginx每个进程最大的连接数,默认是1024,所以nginx最大的连接数max_client=worker_processes * worker_connections。进程最大连接数受到系统最大打开文件数的限制,需要设置ulimit。
#use epoll #指定nginx的工作模式(这里是epoll,epoll是多路复用IO(I/O Multiplexing)中的一种方式),nginx支持的工作模式有select ,poll,kqueue,epoll,rtsig,/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,对于linux系统,epoll是首选。 } #以上是对nginx全局属性的配置 #下面是nginx对http服务相关属性设置 http { include
/etc/nginx/mime.types; #include包含某文件的设定,减少主配置文件的复杂度,相当于把部分设置放在别的地方,然后在包含进来,保持主配置文件的简洁。 default_type application/octet-stream; #默认文件类型,当文件类型未定义时候就使用这类设置。 #log_format:指定nginx日志的格式 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 on; #开启sendfile,开启高效文件传输模式(zero copy 方式),避免内核缓冲区数据和用户缓冲区数据之间的拷贝。 #tcp_nopush on; keepalive_timeout 65; #客户端连接超时时间 #gzip on; #是否开启gzip模块 include /etc/nginx/conf.d/*.conf; #包含指定路径下所有conf文件的配置 }

nginx服务子配置文件/etc/nginx/conf.d/default.conf配置参数解释:

server {
    listen       80;    #虚拟主机的服务端口
    server_name  localhost;    #指定ip或域名,多个域名用逗号分开

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
    
    location / {    #地址匹配设置,支持正则匹配,也支持条件匹配,这里是默认请求地址,用户可以location命令对nginx进行动态和静态网页过滤处理
        root   /usr/share/nginx/html;    #虚拟主机的网页根目录
        index  index.html index.htm;    #默认访问首页文件
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504 /50x.html;    #若出现500等错误,则跳转到下面的location配置路径下的50x.html
    location = /50x.html {
        root   /usr/share/nginx/html;    #错误页面的路径
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {    
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;    #将以php为后缀的文件转发到 FastCGI处理. 使用FastCGI默认配置。本地9000端口处理
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

 修改静态内容无需重启nginx服务,但修改了conf配置文件则需要重启服务方能生效,也可以柔和重启

vim /etc/nginx/conf.d/default.conf
17     error_page   500 502 503 504 404 /50x.html;    #添加404错误,出现404错误时跳转到50x.html
nginx -t    #检查nginx配置文件是否有语法问题
nginx -s reload    #柔和重启,无需关闭服务即可加载最新的配置

 

Nginx日志_log_format

Nginx日志主要分为两种:访问日志(access.log)和错误日志(error.log)。日志开关在Nginx配置文件(/etc/nginx/nginx.conf)中设置,两种日志都可以选择性关闭,默认都是打开的。

访问日志

主要记录客户端访问Nginx的每一个请求,格式可以自定义。通过访问日志,可以得到用户地域来源、跳转来源、使用终端、某个URL访问量等相关信息。Nginx中访问日志相关指令主要有两条:

(1)log_format用来设置日志格式,也就是日志文件中每条日志的格式,具体说明:

  • 语法:log_format name(格式名称) type(格式样式)
  • 支持模块:http

nginx.conf中默认的log_format 格式样式的变量含义:

  • $remote_addr:远程客户端的IP地址。
  • -:空白,用一个“-”占位符替代,历史原因导致还存在。
  • $remote_user:远程客户端用户名称,用于记录浏览者进行身份验证时提供的名字,若没有登录就是空白(变量值为空,在日志输出结果为一个"-"符号)。
  • [$time_local]:访问的时间与时区,如[04/Aug/2019:11:13:43 +0800],时间信息最后的"+0800"表示服务器所处时区位于UTC之后的8小时。
  • $request:请求的URI(即ip地址后的/XXX/XXX.html)和HTTP协议(有版本号),这是整个PV日志记录中最有用的信息,记录服务器收到一个什么样的请求
  • $status:记录请求返回的http状态码,比如成功是200
  • $body_bytes_sent:发送给客户端的文件主体内容的大小,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量。
  • $http_referer:记录从哪个页面链接访问过来的。 
  • $http_user_agent:客户端浏览器信息
  • $http_x_forwarded_for:客户端的真实ip,通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

HTTP请求变量:http请求的request头和response头,可以用curl命令看http请求响应报文的详细内容。

  • arg_PARAMETER:HTTP请求中某个参数的值,如/index.php?site=www.ttlsa.com,可以用$arg_site取得www.ttlsa.com
  • http_HEADER:客户端向服务端的request请求header,如user_agent,host,accept
  • sent_http_HEADER:服务端返回给客户端的response响应header,如server,date,content_type,content_length等

 (2)access_log用来指定日志文件的存放路径(包含日志文件名)、格式和缓存大小,具体说明:

  • 语法:access_log path(存放路径) [format(自定义日志格式名称) [buffer=size | off]]
  • 支持模块:http、server、location

 

如果想关闭日志,可以如下:access_log off;

需要注意的是:Nginx进程设置的用户和组必须对日志路径有创建文件的权限,否则会报错

Nginx支持为每个location指定强大的日志记录。同样的连接可以在同一时间输出到不止一个的日志中。

 

错误日志

主要记录客户端访问Nginx出错时的日志,格式不支持自定义。通过错误日志,可以得到系统某个服务或server的性能瓶颈等。

错误日志由指令error_log来指定,具体格式如下:error_log path(存放路径) level(日志等级)

path含义同access_log,level表示日志等级,具体如下:[ debug | info | notice | warn | error | crit ]

从左至右,日志详细程度逐级递减,即debug最详细,crit最少。

需要注意的是:error_log off并不能关闭错误日志,而是会将错误日志记录到一个文件名为off的文件中。

正确的关闭错误日志记录功能的方法如下:error_log /dev/null;把存储日志路径定义为“黑洞”,即不会记录错误日志。

 

Nginx模块

--with-http_stub_status_module:nginx的客户端状态。在server块里面添加如下location,浏览器访问http://ip地址/mystatus,显示客户端状态信息

location /mystatus {
stub_status;    #可以使用在server块和location块中
}

--with-http_random_index_module:目录中选择一个随机主页。在server块里面添加如下location,浏览器访问http://ip地址,随机显示location定义路径下的一个html文件作为主页,可刷新页面测试。

该模块只能在location为“/”的情况下生效,且隐藏文件不会作为随机主页的对象。

location / {
        root   /opt/app/code;    #在此路径下创建若干个html文件
        random_index on;    #开启随机主页功能,只能用在location块中
        #index  index.html index.htm;
    }

--with-http_sub_module:HTTP内容替换。在server块里面添加如下location,浏览器访问http://ip地址,可以对页面的指定字符串内容替换为指定内容。

该模块只能在location为“/”的情况下生效。

 location / {
        root /usr/share/nginx/html;    #主页文件的内容为fuck you fuck me
        index index.html index.htm;
        sub_filter 'fuck' 'FUCK';    #fuck替换为FUCK,可用在http,server,location中
        sub_filter_once off;    #替换文本中所有匹配的fuck为FUCK(默认为on,只会替换按第一个fuck)。可用在http,server,location中
    }

 

Nginx的请求限制

HTTP请求建立在一次TCP连接的基础上。一次TCP连接至少可以产生一次HTTP请求,HTTP1.1版本以后,建立一次TCP连接可以发送多次HTTP请求。

连接频率限制:limit_conn_module

#语法
Syntax:   limit_conn_zone key zone=name:size;
Default:  —
Context:  http
 
Syntax:   limit_conn zone number;
Default:  —
Context:  http, server, location

请求频率限制:limit_req_module

#语法
Syntax:  limit_req_zone key zone=name:size rate=rate;
Default: —
Context: http

Syntax:  limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location

例:

http {
  # ...其它代码省略...
  # 开辟一个10m的连接空间,命名为conn_name
  limit_conn_zone $binary_remote_addr zone=conn_name:10m;
  # 开辟一个10m的请求空间,命名为req_zone。同一个IP发送的请求,平均每秒只处理一次
  limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s; 
  server {
      ...
    location / {
      ...
      #服务器每次只允许一个IP地址连接
      #limit_conn con_zone 1;
      #limit_req zone=req_zone;
      #当客户端请求超过指定次数,最多宽限3次请求,并延迟处理,1秒1个请求
      #limit_req zone=req_zone burst=3;
      #当客户端请求超过指定次数,最多宽限次请求,并立即处理。
      #limit_req zone=req_zone burst=3 nodelay;
    }
  }
}

 具体可以用ab压力测试命令进行测试:ab -n 50 -c 20 http://ip地址。n表示请求数,c表示同时并发请求数。

 

Nginx的访问控制

基于IP的访问控制:http_access_module

语法:#address表示IP地址,CIDR表示网段,unix表示Socket方式,all代表所有

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

用法:在nginx配置文件中的 server 下配置

server {
  # ...其它代码省略...
  location ~ ^/index_1.html {
    root  /usr/share/nginx/html;
    deny 151.19.57.60; # 拒绝这个IP访问
    allow all; # 允许其他所有IP访问
  } 
  location ~ ^/index_2.html {
    root  /usr/share/nginx/html;
    allow 151.19.57.0/24; # 允许IP 151.19.57.* 访问
    deny all; # 拒绝其他所有IP访问
  }
}

http_access_module局限性:当客户端通过代理访问时,nginx的remote_addr获取的是代理的IP,此时用http_access_module就不是对客户端的精准控制了,所有通过该代理IP访问nginx服务的客户端都会被配置规则所控制。

http_x_forwarded_for:可以记录客户端及所有中间代理的IP,格式:http_x_forwarded_for = Client IP, Proxy1 IP, Proxy2 IP, ...

 

基于用户的登录认证:http_auth_basic_module

语法:

Syntax:  auth_basic string | off;
Default:  auth_basic off;
Context: http, server, location, limit_except
 
Syntax:  auth_basic_user_file file;
Default:  —
Context: http, server, location, limit_except

用法:

1.用htpasswd命令生成账号密码文件(没有该命令则安装httpd-tools)

yum -y install httpd-tools
htpasswd -c /etc/nginx/auth_conf kamin    #kamin是用户名(随便起)

2.在nginx配置文件中的 server 下配置

server {
  # ...其它代码省略...
  location ~ ^/index.html {
    root  /usr/share/nginx/html;
    auth_basic "Auth access! Input your password!";    #提示字符串
    auth_basic_user_file /etc/nginx/auth_conf;    #以生成的auth_conf文件中的用户密码作为认证条件
  }
}

配置好并重启nginx服务后,浏览器访问会弹出用户密码认证输入框。

http_auth_basic_module 局限性:用户信息依赖文件方式,操作管理效率低下。

posted @ 2019-08-05 00:00  RNG丶Perfume  阅读(213)  评论(0编辑  收藏  举报