基于Nginx的中间件架构
一、环境调试确认
四项确认
1、确认系统网络
2、确认yum可用
3、确认关闭iptables规则
4、确认停用selinux
两项安装 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 在opt里新建几个目录
自己的Linux系统中(可以自己的模拟环境,也可以是服务器或者云服务器):
首先: ping www.baidu.com ------------确认系统网络 若有信息,则证明公网连通性是没问题的
yum list|grep gcc ------------确认yum可用
查找并列出gcc样源的软件包
关闭iptables规则 ------------确认关闭iptables规则
iptables -L 查看是否有iptables规则
iptables -F 关闭iptables规则
iptables -t nat -F 一次性关闭nat里的iptables规则
selinux命令 ------------确认停用selinux
getenforce 查看
setenforce 0 关闭
然后执行: 两项安装 + 一次初始化
基础篇
Nginx的中间件架构
一、中间件
web请求 --> 中间件 --> 应用A --> 操作系统/硬件
web请求 --> 中间件 --> 应用A --> 中间件 --> 应用C
二、Nginx简述
Nginx是一个开源的且高性能、可靠的HTTP中间件、代理服务。 1、高性能是支持海量并发的websever服务 2、可靠是说明服务稳定性良好,不会出现本身代码问题而导致一些不可靠的因素,运行起来是稳定的 3、hppt中间件是企业里应用最多的
三、常见的HTTP服务
HTTPD-Apache基金会 IIS-微软 GWS-Google
四、为什么选择nginx
原因1:IO多路复用epoll
io复用:解决的是并发性的问题,当多个用户访问网站,向服务器后台而言会发起多个请求,处理多个并发的请求对于中间件会产生多个io流对应系统的读写,那么多余io流请求系统内核就会有并行处理和串行驱动的概念。 (如果用串行处理的方式的话会出现请求堵塞,因而采用并行处理方式,来完成io流的请求,以实现最大的并发和吞吐,这时候就用到了io复用技术。) io复用就是让一个socket来完成整个io流的请求,如多线程的io复用方式。其他的io复用方式:
1、什么是IO多路复用
对于io流,要获取一组文件的描述符:application发起一个信号告诉系统内核要进行系统调用,当描述符还没就绪的时候,内核会进入等待,当描述符就绪了之后,内核会返回一个信号给应用程序,告诉应用程序已经准备就绪了你可以进行系统调用了。
定义:多个描述符的I/O操作都能在一个县城内并发交替地顺序完成,这就叫做IO多路复用。
2、什么是epoll
IO多路复用的实现方式select、poll、epoll 最早出现的是select 1)什么是select?
前面说了,IO多路复用其实就是内核态当应用所需要文件对象就绪时,主动向应用发送文件就绪信息。而在应用第一次向系统发送系统调用之后到文件就绪之前的这段时间里,在应用端都是堵塞(block)住对应的socket请求的,从而维护一个fd的列表。当内核发送就绪信息之后,应用端会不断遍历fd的列表以唤醒对应的进程完成对应的数据拷贝。在整个过程中select这种方式采用的是一个线性遍历的方式。这种方式存在的一个问题是他会不断的遍历队列里的内容,因此效率很低。
缺点:1.能够监视文件描述的数量存在最大限制(1024个) 2.线性扫描效率低
2)epoll模型 a)每当FD就绪,采用系统的回调函数之间将fd放入就绪的列表,效率更高 b)没有最大连接数的限制
原因2:轻量级
一般说轻量级是指功能模块少、代码模块化
功能模块少:对于一些可以作为插件的功能,一般不会继承在nginx里的。
代码模块化:可以对代码的二次改进,对于开发人员友好。
原因3:cpu的亲和(affinity)
nginx利用到cpu的亲和从而来提升它的并发处理能力和对于cpu的工作执行效率、减少不必要的额外性能损耗。
1)为什么需要CPU亲和?
首先说一下服务器配置,对于24、32、64核的服务器已经见怪不怪了,nginx作为接入层的中间件,它对于CPU的亲和尤为重要。
如上图,假如我Nginx有两个CPU,而且每个CPU有四核,现在有worker1、worker2 ... worker8这样的进程分别均匀地分配到不同的CPU核心上,减少额外的性能损耗。
CPU亲和的含义:是一种把CPU核心和Nginx工作进程绑定方式,把每个worker进程固定在一个cpu上执行,从而减少切换cpu的cache miss,获得更好的性能。
原因4:sendfile
nginx采用sendfile系统的工作机制处理静态文件。
如图,是一个http sever 文件传输图。当我们请求一个文件的时候,文件要经过操作系统的内核空间,然后再到用户空间,最后到达socket。然后才到达用户的客户端。我们都知道静态文件不会过多经过用户空间的逻辑处理,直接进过内核空间。所以sendfile应用这一点,Linux2.2之后推出零拷贝的文件传输模式。
安装Nginx(www.nginx.org/en/download.html)
一、Nginx快速搭建与基本参数使用
Mainline version-开发版 用于学习
Stable version-稳定版本
Legacy version-历史版本
Source Code是Nginx的源代码
Pre-Built Packages是包安装的方式
pcp 源代码的安全校验
二、利用yum进行安装
cd nginx/etc/yum
vim /etc/yum.repos.d/nginx.repo
内容:(注意更改操作系统是centos还是ubuntu,以及操作系统的版本号) [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1 保存
列出nginx版本列表 yum list |grep nginx 如果有想要的版本就yum install nginx 然后一路确认 nginx -v 查看版本 nginx -V 查看一系列参数
三、基本参数使用
安装目录:
命令:
rpm -ql nginx 列出安装nginx服务的哪些文件
路径 | 类型 | 作用 |
---|---|---|
/etc/logrotate.d/nginx | 配置文件 | Nginx日志轮转,用于logrotate服务的日志切割 |
/etc/nginx/nginx.conf | 主要起作用的配置文件 | |
/etc/nginx/conf.d | ||
/etc/nginx/conf.d/default.conf | 在没有做变更的情况下,安装后没有.conf情况下起作用的文件,默认加载 | |
/etc/nginx/fastcgi_params | 配置文件 | cgi配置相关,fastcgi配置 |
/etc/nginx/uwsgi_params | ||
/etc/nginx/scgi_params | ||
/etc/nginx/koi-utf | 配置文件 | 编码转换映射文件 |
/etc/nginx/mine.types | 配置文件 | 设置http协议的Content—Type与扩展名对应关系,当nginx遇到不能识别的文件类型或者不能识别的扩展名的时候,就要配置这个文件,进行相应的添加 |
/usr/lib/systemd/system/nginx-debug.service | 配置文件 | 用于配置出系统守护进程管理器管理方式 |
/usr/lib/systemd/system/nginx.service | ||
/etc/sysconfig/nginx | ||
/usr/lib64/nginx/modules | 目录 | Nginx模块目录 |
/etc/nginx/modules | ||
/usr/sbin/nginx | 命令 | Nginx服务的启动管理的终端命令,用于Nginx的启动关闭配置管理 |
/usr/sbin/nginx-debug /usr/share/doc/nginx-1.12.0 | 文件、目录 | Nginx的手册和帮助文件 /usr/share/doc/nginx-1.12.0/COPYRIGHT | |
/usr/share/man/man8/nginx.8.gz | | /var/cache/nginx | 目录 | Nginx的缓存目录。Nginx除了做代理服务,还可以做缓存服务 /var/log/nginx | 目录 | Nginx的日志目录
logrotate:nginx实际上是对log进行服务的,logrotate实际上是对于nginx产生的日志进行处理的,处理包括:1)对日志进行轮转 :如定义一个周期,按天进行轮转,把一个日志按天生成,说白了就是个日志切割的系统服务 2)
Content-Type:是response中返回的数据的类型
编译参数: 命令: nginx -V 查看编译的参数,有哪些模块
编译选项 | 作用 |
---|---|
--prefix=/etc/nginx | 安装目的目录或路径 |
--sbin-path=/usr/sbin/nginx | |
--modules-path=/usr/lin64/nginx/modules | |
--conf-path=/etc/nginx/nginx.conf | |
--error-log-pat=/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 | 执行对应模块时,Nginx所保留的临时性文件 |
--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 | |
--user=nginx | 设定Nginx进程启动的用户和组用户 |
--group=nginx | |
--with-cc-opt=parameters | 设置额外的参数将被添加到CFLAGS变量 |
--with-ld-opt=parameters | 设置附加的参数,链接系统库 |
Nginx基础配置语法
nginx重启命令:
systemctl restart nginx.service
systemctl reload nginx.service 柔和的重启
nginx.conf:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_refer"'
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/acess.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
<!-- 它包含了这个目录下的以.conf结尾的文件,它的意思是把这个目录下的*.conf的文件读下来-->
include /etc/nginx/conf.d/*.conf;
}
default.conf:
server {
listen 80;
<!-- 域名 -->
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
<!-- 一个server里面当没有其他的访问路径的时候就采用/
访问首页或者子网页-->
location / {
<!-- 设置root访问的路径为这个-->
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 404 /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
#
}
HTTP请求
http 请求建立在tcp请求的基础之上,每一个http请求包括:一个是客户端发起的request请求,另一个是服务端发起的response相应,它们都会发送http报文:
request-包括请求行、请求头部、请求数据
response-包括状态行、消息报头、响应正文
下面模拟一个请求:
登陆到Linux的服务器上
curl # 理解为浏览器
输入curl http://www.baidu.com
返回的是html页面的代码
加一个-v可以返回具体请求详细信息内容,重定向到Linux的空设备里:curl -v http://www.baidu.com > /dev/null
Nginx日志类型
包括:
error.log 主要记录处理http请求错误的状态以及Nginx本身服务的运行状态,按照不同的级别记录到error.log里。
access_log 记录每一次http请求的访问状态,主要用于去分析每一次访问的请求和客户的交互,以及对行为的进行一些分析。
Nginx怎么实现的?
主要依赖于一个log_format的配置。Nginx.log里面记录了很多信息,而每一个信息可以理解为一个变量,log_format就是将这些变量记录到access_log里面去
log_format语法:
Syntax:log_format name [escape=default|json] string ...;
Default:log_format combined "...";
Context:http
在Linux服务器上,vim nginx.conf
user nginx;
worker_process 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
........
http{
include /etc/nginx/mime.types;
......
<!--以下面这种格式打入到access_log里面-->
log_format **main** '$remote_addr - $remote_user [$time_local] "$request'
......
access_log /var/log/nginx/access.log **main**;
<!-- main:表示以main的格式要求记录到这个里面 -->
.......
}
在服务器上输入tail -f /var/log/nginx/error.log 查看nginx日志文件
这就是error_log中打印的错误日志信息的格式: 时间 错误级别 对应的错误代码 :错误的描述以及用户请求的信息
在服务器上输入tail -f /var/log/nginx/access.log 查看nginx日志文件
Nginx可以记录的变量
** HTTP请求变量** - arg_PARAMERER、http_HEADER(request)、sent_http_HEADER(response)
举例:
在服务器输入 curl -v www.baidu.com
把内容输入到dev/null之前先清理,已有的/etc/nginx/.nginx.conf.swp
然后vim /etc/nginx/nginx.conf
将log_format main 后$符号后的名字改为需要日志记录的名字,大写变小写,-变_,如:
'$http_user_agent'
然后保存并退出(:wq)
输入命令 nginx -t -c /etc/nginx/nginx.conf对配置文件进行前期的一个检查,如果出现successful表示成功了
<!--nginx -t 表示文件的正确与否,-c表示配置文件的路径-->
重载配置文件,输入命令:nginx -s reload -c /etc/nginx/nginx.conf
查看nginx的进程:ps -aux|grep nginx
curl http://127.0.0.1:80
tail -n 200 /var/log/nginx/access.log
可以看到日志的最前面是刚才在nginx.conf里配置log_format的$http-user-agent信息
**内置变量 - Nginx内置的**
nginx.org里查询,logging to syslog ->access_log ->log_format
对于log_format中简要说明:
remote_addr 客户端的地址
remote_user 客户端请求nginx认证的用户名,默认没有开启的话,那么是不可进入的
time_local 表示是nginx的时间
status表示response返回的状态
body_bytes_sent 服务端返回给客户端,body中信息的大小
http_referer 是一个比较重要的记录信息,在防盗链里或者对用户进行行为分析的时候经常用到,表示上一级页面的访问地址
http_x_forwarded_for 每一级请求里的对应的http信息
Nginx模块
Nginx官方模块
编译选项 | 作用 |
---|---|
--with-http_stub_status_module | Nginx的客户端状态:连接状态 |
Syntax:stub_status
Default:--
Context:server,location # 要配置在server/location下
vim /conf.d/default.conf
server {
listen 80;
sercer_name localhost;
#charser koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
定义自己的客户端连接状态
location /mystatus {
stub_status;
}
location / {
root /usr/share
}
}
然后检查语法是否正确,然后重载服务:
nginx -tc /etc/nginx/nginx.conf
nginx -s reload -c /etc/nginx/nginx.conf
访问 "你服务器的ip/mystatus",页面会显示
Active connections:2
server accepts handled requests
数字a 数字b 数字c
# a表示nginx总的握手次数 b表示处理的连接数 c表示总的连接数 正常的情况下握手数和连接数是要相等的,这表示它没有丢失
Reading: 0 Writing:1 Waiting: 1
第三方模块(未完待续)