32-高性能WEB服务NGINX(一)

2020-05-05  本文已影响0人  Liang_JC

本章内容
◆ I/O模型
◆ nginx介绍
◆ nginx安装
◆ nginx各种模块实现web服务
◆ nginx实现fastcgi反代代理
◆ nginx实现http负载均衡
◆ nginx实现tcp反向代理
◆ tengine实现
◆ nginx高并发Linux内核优化

性能影响

影响用户体验的几个因素

● 客户端硬件配置
● 客户端网络速率
● 客户端与服务端距离
● 服务端网络速率
● 服务端硬件配置
● 服务端架构设计
● 服务端应用程序工作模式
● 服务端并发数量
● 服务端响应文件大小及数量
● 服务端I/O压力

Httpd MPM

I/O介绍

I/O模型

阻塞IO模型

image.png

同步非阻塞IO模型

image.png

I/O多路复用模型

image.png

信号驱动IO模型

image.png

异步IO模型

image.png

I/O模型的具体实现

select/poll/epoll

image.png image.png
#查看源码内核FD_SETSIZE的值
find linux-5.1.4/ -type f | xargs grep "FD_SETSIZE"

零拷贝

nginx介绍

nginx的程序架构

nginx模块

nginx的功用

nginx的安装

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
module_hotfixes=true
yum install nginx

编译安装示例

useradd -r -s /sbin/nologin nginx
./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
make && make install  

小笔记:nginx

yum install nginx
systemctl start nginx
echo "welcome" > /usr/share/nginx/html/index.html

nginx       #启动服务
nginx -s reload|stop|restart
nginx -t    #检查配置文件
nginx -T    #查看配置文件内容
nginx -V    #查看编译的参数

小笔记:源码编译nginx

wget http://nginx.org/download/nginx-1.16.1.tar.gz
tar xf nginx-1.16.1.tar.gz
yum install gcc pcre-devel openssl-devel zlib-devel
useradd -r -s /sbin/nologin nginx
cd nginx-1.16.1
./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
make && make install
ln -s /apps/nginx/sbin/nginx /usr/sbin/

/apps/nginx/html    #主页文件目录

nginx目录结构和命令

nginx配置

nginx配置文件

主配置文件结构:四部

main block:主配置段,即全局配置段,对http,mail都有效
    event {
        ...
    } 事件驱动相关的配置
http {
    ...
}   http/https 协议相关配置段
mail {
    ...
}   mail 协议相关配置段
stream {
    ...
}   stream 服务器相关配置段

http协议相关的配置结构

http {
    ...
    ... 各server的公共配置
    server { 每个server用于定义一个虚拟主机
        ...
        }
    server {
        ...
        server_name 虚拟主机名
        root 主目录
        alias 路径别名
        location [OPERATOR] URL { 指定URL的特性
            ...
            if CONDITION {
            ...
            }
        }
    }
}

nginx配置

ngx_http_core_module

server {
    ...
    root /data/www/vhost1;
}
示例
    http://www.magedu.com/images/logo.jpg
            --> /data/www/vhosts/images/logo.jpg
server {...
    server_name www.magedu.com;
    location /images/ {
        root /data/imgs/;
    }
}
    http://www.magedu.com/images/logo.jpg
            --> /data/imgs/images/logo.jpg  
location = / {
     ...
 }
 http://www.magedu.com/ 匹配
http://www.magedu.com/index.html 不匹配
^~ 对URI的最左边部分做匹配检查,不区分字符大小写
~ 对URI做正则表达式模式匹配,区分字符大小写
~* 对URI做正则表达式模式匹配,不区分字符大小写
不带符号 匹配起始于此uri的所有的uri
\ 转义符,可将 . * ?等转义为普通符号

匹配优先级从高到低:=, ^~, ~/~*, 不带符号

root /vhosts/www/htdocs/;
    http://www.magedu.com/index.html
        --> /vhosts/www/htdocs/index.html
server {
    root /vhosts/www/htdocs/ ;
    location /admin/ {
        root /webapps/app1/data/;
    }
}
    http://www.magedu.com/admin/index.html
        --> /webapps/app1/data/admin/index.html
location = / {                      http://www.magedu.com/
[ configuration A ]
}
location / {                        http://www.magedu.com/index.html
[ configuration B ]
}
location /documents/ {              http://www.magedu.com/documents/logo.jpg
[ configuration C ]
}
location ^~ /images/ {              http://www.magedu.com/documents/linux.txt
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {     http://www.magedu.com/images/logo.jpeg
[ configuration E ]
}
server {
    listen 80;
    server_name www.magedu.net;
    location / {
        root /data/nginx/html/pc;
    }
    location /about {
        root /opt/nginx/html/pc;
        #必须要在html目录中创建一个about目录才可以访问,否则报错
        index index.html;
    }
}
#mkdir /opt/nginx/html/pc/about
#echo about > /opt/nginx/html/pc/about/index.html  
location ^~ /static/ {
    root /data/nginx/static;
}
# 或者
location ~* \.(gif|jpg|jpeg|png|bmp|tiff|tif|css|js|ico)$ {
    root /data/nginx/static;
}  
server {
    listen 80;
    server_name www.magedu.net;
    location / {
        root /data/nginx/html/pc;
    } 
    #使用alias的时候uri后面如果加了斜杠则下面的路径配置必须加斜杠,否则403
    location /about {   #当访问about时,访问alias定义的/opt/nginx/html/pc内容
    alias /opt/nginx/html/pc;
        index index.html;
    }
}
#生产案例:

listen 80;
server_name www.magedu.net;
error_page 500 502 503 504 404 /error.html;
location = /error.html {
    root /data/nginx/html;
}  
 limit_except GET {
    allow 192.168.1.0/24;
    deny all;
}

除了GET和HEAD 之外其它方法仅允许192.168.1.0/24网段主机使用

小笔记:nginx配置文件

cd /etc/nginx/
grep -Ev "^#|^$" nginx.conf
mkdir conf.d/test

vim nginx.conf
user nginx;                         #指定用户名
worker_processes 4;                 #进程数,跟CPU核心有关
#worker_cpu_affinity 00000001 00000010 00000100 00001000 ;      #进程跟CPU绑定
#worker_priority -20                #优先级-20到20,越小越大
#worker_rlimit_nofile 65535         #与ulimit -n的值保持一致,配置文件/etc/security/limits.conf
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;        #每个worker进程所能够打开的最大并发连接数
    #master_process on|off;         #默认为on,当指定off 将不启动worker
}

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            on;         #开启后nopush才有效
    tcp_nopush          on;         #性能优化
    tcp_nodelay         on;         #性能优化
    keepalive_timeout   65;         #保持连接超时时长
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

vim conf.d/test.conf
charset utf-8
server_tokens nginx

小笔记:配置虚拟主机

#server
mkdir /data/site1
mkdir /data/site2
echo /data/site1/index.html > /data/site1/index.html
echo /data/site2/index.html > /data/site2/index.html

vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
}
server {
    server_name www.magedu.tech;
    root /data/site2/;
}

#client
echo "192.168.37.7 www.magedu.net www.magedu.tech" > /etc/hosts
curl http://www.magedu.net
curl http://www.magedu.tech

小笔记:location

#server
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    location /test {
        root /opt/testdir;
    }
}
mkdir /opt/testdir -p
echo "/opt/testdir/index.html" > /opt/testdir/index.html

#client
curl http://www.magedu.net/test

#--------------分割线---------------#

#静态资源
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    location ~* \.(jpg|gif|html|txt)$ {
        root /opt/static;
    }
    location ~* \.(php|jsp) {
        root /opt/dynamic;
    }
}
mkdir /opt/static
echo a.jsp > /opt/static/a.jsp
echo aaa.html > /opt/static/a.html

#client
curl http://www.magedu.net/a.jsp

#--------------分割线---------------#

#别名
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    location /about {           #about后面不要加"/"
        alias /opt/testdir;
        index test.html
    }
    error_page 404 /40x.html
    #error_page 404 =200 /404.html  #错误重定向
    location = /40x.html {}
}

#client
curl http://www.magedu.net/about

#--------------分割线---------------#

#错误
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    error_page 404 /40x.html;
    #error_page 404 =200 /404.html; #错误重定向
    location = /40x.html {}
}

#--------------分割线---------------#

#try_files
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    location /images {
        alias /data/images
        try_files $uri $uri.jpg =404;   #先找uri(uri=/images/{这个值}),再找$uri/defalut.jpg,都找不到就404
    }
}

#--------------分割线---------------#

#单线程限速
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    limit_rate 10k;
}

#--------------分割线---------------#
#limit_except
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
    server_name www.magedu.net;
    root /data/site1/;
    location / {
        limit_except GET {          #除了get外所有指令都支持
            allow 192.168.37.6;
            deny all;
        }
    }
}

#client
curl -I -X OPTIONS www.magedu.net
curl -I -X GET www.magedu.net

#--------------分割线---------------#

#缓存

ngx_http_access_module

ngx_http_auth_basic_module

ngx_http_stub_status_module

小笔记:模块

#访问控制
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
  server_name www.magedu.net;
  root /data/site1/;
  location / {    
      allow 192.168.37.6;
      deny all;
  }
}

#用户的访问控制
htpasswd -b -c /etc/nginx/conf.d/.nginx_passwd alice centos
htpasswd -b /etc/nginx/conf.d/.nginx_passwd bob centos
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
  server_name www.magedu.net;
  root /data/site1/;
  location /admin {   
      root /data/;
      allow 192.168.37.0/24;
      deny all;
      auth_basic "Admin Area";
      auth_basic_user_file /etc/nginx/conf.d/.nginx_passwd;
  }
}
mkdir /data/admin/
echo /data/admin/index.html > /data/admin/index.html

#client
http://www.magedu.net/admin
curl -u bob:centos http://www.magedu.net/admin

#状态页
vim /etc/nginx/conf.d/test.conf
server_tokens off;
server {
  server_name www.magedu.net;
  root /data/site1/;
  location /admin {   
      root /data/;
      allow 192.168.37.0/24;
      deny all;
      auth_basic "Admin Area";
      auth_basic_user_file /etc/nginx/conf.d/.nginx_passwd;
  }
  location /nginx_status {
      stub_status;
      allow 127.0.0.1;
      allow 172.16.0.0/16;
      allow 192.168.37.0/24;
      deny all;
  }  
}

#client
ab -c1000 -n 2000 www.magedu.net/m.html
http://www.magedu.net/nginx_status

nginx 第三方模块

yum install git –y
yum install gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
cd /usr/local/src
git clone https://github.com/openresty/echo-nginx-module.git
cd nginx-1.16.0/
useradd –r –s /sbin/nologin nginx
./configure \
--prefix=/apps/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_perl_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--add-module=/usr/local/src/echo-nginx-module
make && make install

vim /apps/nginx/conf/conf.d/pc.conf
location /test {
    index index.html;
    default_type text/html;
    echo "hello world,main-->";
    echo_reset_timer;
    echo_location /sub1;
    echo_location /sub2;
    echo "took $echo_timer_elapsed sec for total.";
}
location /sub1 {
    echo_sleep 1;
    echo sub1;
}
location /sub2 {
    echo_sleep 1;
    echo sub2;
}

小笔记:第三方模块

#按上面步骤先重新编译nginx
#1.16 版本不兼容,改用1.14

vim /apps/nginx/conf/nginx.conf
http{
    include /apps/nginx/conf.d/*.conf;
    ...
}

vim /apps/nginx/conf.d/test.conf
server_token off;
server {
    server_name www.test.com;
    root /data/test;
    location /echo {
        index index.html;
        default_type text/html;
        echo "hello world";
    }
}
mkdir -p /data/test/echo
echo  /data/test/index.html > /data/test/index.html
echo  /data/test/echo/index.html > /data/test/echo/index.html
nginx -t
nginx

nginx 变量使用

小笔记:变量

vim /apps/nginx/conf.d/test.conf
server_token off;
server {
    server_name www.test.com;
    root /data/test;
    location /echo {
        index index.html;
        default_type text/html;
        echo "hello world";
        echo $remote_addr;
    }
    location /test {
        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        echo_reset_timer;
        echo_location /sub1;
        echo_location /sub2;
        echo "took $echo_timer_elapsed sec for total.";
    }
    location /sub1 {
        echo_sleep 1;
        echo sub1;
    }
    location /sub2 {
        echo_sleep 1;
        echo sub2;
    }
}

ngx_http_log_module

示例

log_format compression '$remote_addr-$remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;  

小笔记:nginx日志

#日志位置
/var/log/nginx/access.log

#自定义访问日志
vim /etc/nginx/nginx.conf
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  testlog  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" ';                  
    access_log  /var/log/nginx/access.log  main;
    ......
} 
vim /etc/nginx/conf.d/test.conf
server_token off;
server {
    server_name www.test.com;
    root /data/test;
    location / {}
    access_log /var/log/nginx/magedu_net.access.log testlog;
}   

自定义json日志格式

log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log /apps/nginx/logs/access_json.log access_json;

json格式的日志访问统计

#cat nginx_json.py
#!/usr/bin/env python
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":
            status_404.append(line.get)
        else:
            print("状态码 ERROR")
f.close()
print "状态码200的有--:",len(status_200)
print "状态码404的有--:",len(status_404)

# python nginx_json.py
状态码200的有--: 1910
状态码404的有--: 13

关于favicon.ico

location = /favicon.ico {
    log_not_found off; #文件没发现事件不记录error_log
    access_log off; #不记录access_log
}
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
    root /data/nginx/html/pc/images;
}  

ngx_http_log_module

小笔记:自定义日志格式

#自定义日志格式
vim /etc/nginx/nginx.conf
http {
log_format access_json '{"@timestamp":"$time_iso8601",'
    '"host":"$server_addr",'
    '"clientip":"$remote_addr",'
    '"size":$body_bytes_sent,'
    '"responsetime":$request_time,'
    '"upstreamtime":"$upstream_response_time",'
    '"upstreamhost":"$upstream_addr",'
    '"http_host":"$host",'
    '"uri":"$uri",'
    '"domain":"$host",'
    '"xff":"$http_x_forwarded_for",'
    '"referer":"$http_referer",'
    '"tcp_xff":"$proxy_protocol_addr",'
    '"http_user_agent":"$http_user_agent",'
    '"status":"$status"}';                 
    access_log  /var/log/nginx/access.log  main;
    ......
} 
vim /etc/nginx/conf.d/test.conf
server_token off;
server {
    server_name www.test.com;
    root /data/test;
    location / {}
    access_log /var/log/nginx/magedu_net.access.log access_json;
}

ngx_http_autoindex_module

location /download {
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
    autoindex_format json;
    limit_rate 100k;
    root /data/nginx/html/pc;
    index index.html;
}
mkdir /data/nginx/html/pc/download/

ngx_http_gzip_module

示例:

gzip on;
gzip_comp_level 6;
gzip_min_length 64;
gzip_vary on;
gzip_types text/xml text/css application/javascript; 

小笔记:充当文件下载服务

vim /etc/nginx/conf.d/test.conf
server {
    server_name www.test.com;
    root /data/test;
    location / {}
    access_log /var/log/nginx/test.com.access.log access_json;

    location /download {
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        #autoindex_format json;     #html|xml|json|jsonp
        limit_rate 100k;
        index index.html;
    }
}
mkdir /data/test/download
mount /dev/sr0 /data/test/download

小笔记:压缩

vim /etc/nginx/conf.d/test.conf
server {
    server_name www.test.com;
    root /data/test;
    location / {}
    access_log /var/log/nginx/magedu_net.access.log access_json;
    gzip on;                #启用压缩
    gzip_comp_level 6;      #压缩等级
    gzip_min_length 64;     #响应报文阈值
    gzip_vary on;           #响应报文首部插入“Vary: Accept-Encoding”  
    gzip_types text/xml text/css application/javascript;    #压缩类型
}

#client
curl --compressed http://www.magedu.net/m.html
上一篇 下一篇

猜你喜欢

热点阅读