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=
enabled=
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 ; #指定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 ; #设置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 ; #客户端连接超时时间 #gzip on; #是否开启gzip模块 include /etc/nginx/conf.d/*.conf; #包含指定路径下所有conf文件的配置
}

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

server {
listen ; #虚拟主机的服务端口
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 /.html; # redirect server error pages to the static page /50x.html
#
error_page /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:
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:; #将以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
error_page /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 ;
#limit_req zone=req_zone;
#当客户端请求超过指定次数,最多宽限3次请求,并延迟处理,1秒1个请求
#limit_req zone=req_zone burst=;
#当客户端请求超过指定次数,最多宽限次请求,并立即处理。
#limit_req zone=req_zone burst= 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/; # 允许IP 151.19..* 访问
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 局限性:用户信息依赖文件方式,操作管理效率低下。

最新文章

  1. WIFI网络操作
  2. 取消IE提示下载安全提问
  3. ASP.NET DAY1
  4. iOS----Xcode6或者Xcode7设置LaunchImage图标
  5. AFNetworking简单用法
  6. Nginx - Windows下Nginx初入门
  7. springAOP配置文件
  8. Xamarin 安装体验
  9. php&mysql
  10. java.util.concurrent.atomic 类包详解
  11. hdu 2565 放大的X
  12. 用sklearn封装的kmeans库
  13. ASP.NET MVC5+EF6+EasyUI 后台管理系统(92)-打印EasyUI 的datagrid表格
  14. 三十五、minishell(3)
  15. 升级 Apache Tomcat的办法
  16. prop和attr的比较
  17. Python 全栈开发七 面向对象
  18. java 2和java有什么区别
  19. Python shutil模块(目录和文件操作)
  20. 使用DataTrigger来代替Triggerr

热门文章

  1. sqlserver之datepart和datediff应用查找当天上午和下午的数据
  2. SharpSocket类库功能介绍
  3. 理解了quote和 symbol-list的 关系
  4. Linux 目录简介
  5. Java常用类StringBuffer详解
  6. 【开发笔记】- yml中出现特殊字符启动失败的问题
  7. Linux自有服务(2)-Linux从入门到精通第六天(非原创)
  8. Linux自有服务(1)-Linux从入门到精通第五天(非原创)
  9. 转:Oracle中SQL语句执行过程中
  10. CMake相关代码片段