目录

Life in Flow

Embrace your dreams and unlock your full potential at every stage of life.

X

nginx

什么是Nignx服务器

  • Nginx介绍

    • 官网:http://nginx.org/
    • 是一个高性能的[HTTP]和[反向代理]web服务器
    • Nginx代码完全用[C语言]从头写成
  • 市场上使用情况

    • 据统计,世界上每3个网站中就有一个使用Nginx
  • 为什么要用这个

    • 社区活跃
    • 高性能-支持单机千万级连接
    • 强大的第三方库支持
    • 功能强大:负载均衡、静态文件服务器、支持多种协议https、POP3等等

什么是正向代理服务器和反向代理服务器

正向代理服务器

  • 客户端和目标服务器之间的服务器,客户端向代理发送一个请求指定目标服务器,然后代理向目标服务器请求并获得内容,并返回给客户端,平时说的代理服务器一般是正向代理服务器
  • 核心:用户知道自己访问的目标服务器
  • 场景:跳板机、访问原来无法访问的网站, 比如国外的一些站点

反向代理服务器(Nginx)

  • 客户端和目标服务器之间的服务器,客户端向代理发送一个请求,然后代理向目标服务器请求并获得内容,并返回给客户端。反向代理隐藏了真实的服务器
  • 核心:客户端不知道要访问的目标服务器是哪台服务器,代理会根据一定的策略选择一个真实的服务器进行请求
  • 场景:访问淘宝,知道访问的域名是taobao.com, 但是后面提供数据的具体是什么域名或ip我们是不知道的

Nginx安装

  • 下载压缩包 并上传

  • 安装依赖

    • yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
  • 创建一个文件夹,上传本地提供的nginx包

    • tar -zxvf nginx-1.18.0.tar.gz
      //执行命令
      ./configure
      make
      make install 
      
  • 默认安装路径

    • /usr/local/nginx
  • 访问配置

    cd /usr/local/nginx/sbin   
    ./nginx
    
    [root@localhost sbin]# ps -ef | grep "nginx"
    root     20186     1  0 11:12 ?        00:00:00 nginx: master process ./nginx
    nobody   20187 20186  0 11:12 ?        00:00:00 nginx: worker process
    root     20189  8494  0 11:14 pts/0    00:00:00 grep --color=auto nginx
    
    

Nginx目录文件

源码编译安装后,默认目录

/usr/local/nginx

目录核心介绍

conf  #所有配置文件目录
  nginx.conf    #默认的主要的配置文件
  nginx.conf.default  #默认模板

html  # 这是编译安装时Nginx的默认站点目录
  50x.html #错误页面
  index.html #默认首页
  
logs  # nginx默认的日志路径,包括错误日志及访问日志
  error.log  #错误日志
  nginx.pid  #nginx启动后的进程id
  access.log #nginx访问日志

sbin  #nginx命令的目录
  nginx  #启动命令

常见命令

./nginx  #默认配置文件启动

./nginx -s reload #重启,加载默认配置文件

./nginx -c /usr/local/nginx/conf/nginx.conf #启动指定某个配置文件

./nginx -s stop #停止

#关闭进程,nginx有master process 和worker process,关闭master即可
ps -ef | grep "nginx" 
kill -9 PID 

Nginx核心之配置文件剖析

  • 全局配置
  • server 主机设置
  • location(URL匹配特定位置的设置)
# 每个配置项由配置指令和指令参数 2 个部分构成
#user  nobody;  # 指定Nginx Worker进程运行以及用户组
worker_processes  1;   # 推荐与CPU核心数保持一致,CPU与核心数进行绑定

#error_log  logs/error.log;  # 错误日志的存放路径  和错误日志
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;   # 进程PID存放路径


# 事件模块指令,用来指定Nginx的IO模型,Nginx支持的有select、poll、kqueue、epoll 等。不同的是epoll用在Linux平台上,而kqueue用在BSD系统中,对于Linux系统,epoll工作模式是首选
events { 
    use epoll;
  # 定义Nginx每个进程的最大连接数, 作为服务器来说: worker_connections * worker_processes,
  # 作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为反向代理服务器,每个  并发会建立与客户端的连接和与后端服务的连接,会占用两个连接
    worker_connections  1024; 
}




http {
    include       mime.types;
    default_type  application/octet-stream;
    # 自定义服务日志模板
    #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  logs/access.log  main;

    # 是否开启高效传输模式 on开启 off关闭
    sendfile        on;
  
    #减少网络报文段的数量
    #tcp_nopush     on;

    #keepalive_timeout  0;
    # 客户端连接保持活动的超时时间,超过这个时间之后,服务器会关闭该连接
    keepalive_timeout  65;

    #gzip  on;
  
    # 虚拟主机的配置
    server {
        listen       80; # 虚拟主机的服务端口
        server_name  localhost; #用来指定IP地址或域名,多个域名之间用空格分开

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        #URL地址匹配
        location / {
            root   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;
        location = /50x.html {
            root   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;
        #    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;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
}

虚拟主机

  • 什么是虚拟主机

    • 指在一台物理主机服务器上划分出多个磁盘空间,每个磁盘空间都是一个虚拟主机,每台虚拟主机都可以对外提供Web服务,并且互不干扰,就类似虚拟机
    • 利用虚拟主机把多个不同域名的网站部署在同一台服务器上,节省了服务器硬件成本和相关的维护费用
  • 【注意】配置之前,拷贝一份默认的出来,nginx配置容易出错且肉眼难看出来,自己仔细核对

  • Nginx虚拟主机配置

server {
        listen       80;
        server_name  aabbcc.com;

        location / {
            root   /usr/local/nginx/html;
            index  index.html;
        }
  }
  
  
server {
        listen       80;
        server_name  aabbccdd.com;
  
        location / {
            root   html;
            index  xdclass.html index.htm;
        }
}

文件服务器

  • 图片服务器

    • 学javaweb、node、或者其他基础web项目,基本都是图片上传到项目本身,这个是生成很少用
    • 公司一般会使用图片服务器或者云厂商提供的CDN
  • 使用流程

  • 前端提交图片->后端处理->存储到图片服务器->拼接好访问路径存储到数据库和范围前端

  • 本地图片上传上去,配置专属访问路径

server {
        listen       80;
        server_name  aabbccdd.com;
        location /app/img {
          alias /usr/local/software/img/;
        }
  }

注意

  • 在location / 中配置root目录
  • 在location /path中配置alias虚拟目录, 目录后面的"/"符号一定要带上

Nginx访问日志

access.log日志用处

  • 统计站点访问ip来源、某个时间段的访问频率
  • 查看访问最频的页面、Http响应状态码、接口性能
  • 接口秒级访问量、分钟访问量、小时和天访问量
  • ...

默认配置解析

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

案例

122.70.148.18 - - [04/Aug/2020:14:46:48 +0800] "GET /user/api/v1/product/order/query_state?product_id=1&token=xdclasseyJhbGciOJE HTTP/1.1" 200 48 "https://xdclass.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"

解析

$remote_addr 对应的是真实日志里的122.70.148.18,即客户端的IP。

$remote_user 对应的是第二个中杠“-”,没有远程用户,所以用“-”填充。

[$time_local]对应的是[04/Aug/2020:14:46:48 +0800]。

“$request”对应的是"GET /user/api/v1/product/order/query_state?product_id=1&token=xdclasseyJhbGciOJE HTTP/1.1"。

$status对应的是200状态码,200表示正常访问。

$body_bytes_sent对应的是48字节,即响应body的大小。

“$http_referer” 对应的是”https://xdclass.net/“,若是直接打开域名浏览的时,referer就会没有值,为”-“。

“$http_user_agent” 对应的是”Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0”。

“$http_x_forwarded_for” 对应的是”-“或者空。

运维平台案例统计

Nginx统计站点访问量、高频url统计

  • 查看访问最频繁的前100个IP

    awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100
    
  • 统计访问最多的url 前20名

    cat access_temp.log |awk '{print $7}'| sort|uniq -c| sort -rn| head -20 | more
    

基础

awk 是文本处理工具,默认按照空格切分,$N 是第切割后第N个,从1开始

sort命令用于将文本文件内容加以排序,-n 按照数值排,-r 按照倒序来排
  案例的sort -n 是按照第一列的数值大小进行排序,从小到大,倒序就是 sort -rn

uniq 去除重复出现的行列, -c 在每列旁边显示该行重复出现的次数。

自定义日志统计接口性能

日志格式增加 $request_time

从接受用户请求的第一个字节到发送完响应数据的时间,即包括接收请求数据时间、程序响应时间、输出响应数据时间

$upstream_response_time:指从Nginx向后端建立连接开始到接受完数据然后关闭连接为止的时间(用于统计后端接口的响应时间)

$request_time一般会比upstream_response_time大,因为用户网络较差,或者传递数据较大时,前者会耗时大很多(整个请求用户的响应时间)

配置自定义日志格式

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_time';


server {
        listen       80;
        server_name  aabbcc.com;

        location / {
            root   /usr/local/nginx/html;
            index  xdclass.html;
        }
        #charset koi8-r;
        #
        access_log  logs/host.access.log  main;
}

统计耗时接口, 列出传输时间超过 2 秒的接口,显示前5条

cat time_temp.log|awk '($NF > 2){print $7}'|sort -n|uniq -c|sort -nr|head -5

备注:$NF 表示最后一列, awk '{print $NF}'

Nginx配置集群应用

安装JDK8环境

JAVA_HOME=/usr/local/software/jdk8
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
    • 环境变量立刻生效
      • source /etc/profile
    • 查看安装情况 java -version
  • 上传jar包

    • 启动应用
    • 关闭应用
      • lsof -i:port 或者 ps -ef | grep java
      • kill -9 PID

springboot应用和接口说明

  • Linux服务器需要安装JDK8

  • 准备两个一样的Jar包

    • demo-1.jar监听8080端口
    • demo-2.jar监听8081端口
  • 接口说明

  • 直接启动

    • java -jar demo-1.jar
    • java -jar demo-2.jar
  • 守护进程方式

    • nohup java -jar demo-1.jar &
    • nohup java -jar demo-2.jar &

Nginx的upstream模板介绍

  • 负载均衡(Load Balance)

    • 分布式系统中一个非常重要的概念,当访问的服务具有多个实例时,需要根据某种“均衡”的策略决定请求发往哪个节点,这就是所谓的负载均衡,
    • 原理是将数据流量分摊到多个服务器执行,减轻每台服务器的压力,从而提高了数据的吞吐量
  • 负载均衡的种类

    • 通过硬件来进行解决,常见的硬件有NetScaler、F5、Radware和Array等商用的负载均衡器,但比较昂贵的
    • 通过软件来进行解决,常见的软件有LVS、Nginx等,它们是基于Linux系统并且开源的负载均衡策略
    • 目前性能和成本来看,Nginx是目前多数公司选择使用的

配置案例

upstream lbs {
   server 192.168.0.106:8080;
   server 192.168.0.106:8081;
}
server{
	location /api/ {
    		proxy_pass http://lbs;
    		proxy_redirect default;
	}
}

访问

http://aabb.com/api/v1/pub/web

负载均衡策略解析

Nginx常见的负载均衡策略

  • 节点轮询(默认)

    • 简介:每个请求按顺序分配到不同的后端服务器
    • 场景:会造成可靠性低和负载分配不均衡,适合静态文件服务器
  • weight 权重配置

    • 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
    • 场景:服务器性能差异大的情况使用
upstream lbs {
   server 192.168.159.133:8080 weight=5;
   server 192.168.159.133:8081 weight=10; 
}

ip_hash(固定分发)

  • 简介:根据请求按访问ip的hash结果分配,这样每个用户就可以固定访问一个后端服务器
  • 场景:服务器业务分区、业务缓存、Session需要单点的情况
upstream lbs {
   ip_hash;
   server 192.168.159.133:8080;
   server 192.168.159.133:8081;
}

upstream还可以为每个节点设置状态值
	down 表示当前的server暂时不参与负载
	server 192.168.159.133:8080 down;

backup 其它所有的非backup机器down的时候,会请求backup机器,这台机器压力会最轻,配置也会相对低
	server 192.168.159.133:8080 backup;

Nginx后端节点可用性探测

如果某个应用挂了,请求不应该继续分发过去

  • max_fails 允许请求失败的次数,默认为1.当超过最大次数时就不会请求

  • fail_timeout : max_fails次失败后,暂停的时间,默认:fail_timeout为10s

  • 参数解释

    • max_fails=N 设定Nginx与后端节点通信的尝试失败的次数。
    • 在fail_timeout参数定义的时间内,如果失败的次数达到此值,Nginx就这个节点不可用。
    • 在下一个fail_timeout时间段到来前,服务器不会再被尝试。
    • 失败的尝试次数默认是1,如果设为0就会停止统计尝试次数,认为服务器是一直可用的。
  • 具体什么是nginx认为的失败呢

    • 可以通过指令proxy_next_upstream来配置什么是失败的尝试。
    • 注意默认配置时,http_404状态不被认为是失败的尝试。

配置实操

upstream lbs {
                server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ;
                server 192.168.0.106:8081 max_fails=2 fail_timeout=60s;
}


location /api/ {
         proxy_pass http://lbs;
         proxy_next_upstream error timeout http_500 http_503 http_404;
}

案例实操

  • 暂停一个后节点,然后访问接口大于10次,Nginx会把这个节点剔除
  • 重启这个节点,在fail_timeout周期里面不会再获取流量

作者:Soulboy