目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

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
      1//执行命令
      2./configure
      3make
      4make install 
      
  • 默认安装路径

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

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

Nginx 目录文件

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

1/usr/local/nginx

目录核心介绍

 1conf  #所有配置文件目录
 2  nginx.conf    #默认的主要的配置文件
 3  nginx.conf.default  #默认模板
 4
 5html  # 这是编译安装时Nginx的默认站点目录
 6  50x.html #错误页面
 7  index.html #默认首页
 8  
 9logs  # nginx默认的日志路径,包括错误日志及访问日志
10  error.log  #错误日志
11  nginx.pid  #nginx启动后的进程id
12  access.log #nginx访问日志
13
14sbin  #nginx命令的目录
15  nginx  #启动命令

常见命令

 1./nginx  #默认配置文件启动
 2
 3./nginx -s reload #重启,加载默认配置文件
 4
 5./nginx -c /usr/local/nginx/conf/nginx.conf #启动指定某个配置文件
 6
 7./nginx -s stop #停止
 8
 9#关闭进程,nginx有master process 和worker process,关闭master即可
10ps -ef | grep "nginx" 
11kill -9 PID 

Nginx 核心之配置文件剖析

  • 全局配置
  • server 主机设置
  • location(URL 匹配特定位置的设置)
  1# 每个配置项由配置指令和指令参数 2 个部分构成
  2#user  nobody;  # 指定Nginx Worker进程运行以及用户组
  3worker_processes  1;   # 推荐与CPU核心数保持一致,CPU与核心数进行绑定
  4
  5#error_log  logs/error.log;  # 错误日志的存放路径  和错误日志
  6#error_log  logs/error.log  notice;
  7#error_log  logs/error.log  info;
  8
  9#pid        logs/nginx.pid;   # 进程PID存放路径
 10
 11
 12# 事件模块指令,用来指定Nginx的IO模型,Nginx支持的有select、poll、kqueue、epoll 等。不同的是epoll用在Linux平台上,而kqueue用在BSD系统中,对于Linux系统,epoll工作模式是首选
 13events { 
 14    use epoll;
 15  # 定义Nginx每个进程的最大连接数, 作为服务器来说: worker_connections * worker_processes,
 16  # 作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为反向代理服务器,每个  并发会建立与客户端的连接和与后端服务的连接,会占用两个连接
 17    worker_connections  1024; 
 18}
 19
 20
 21
 22
 23http {
 24    include       mime.types;
 25    default_type  application/octet-stream;
 26    # 自定义服务日志模板
 27    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 28    #                  '$status $body_bytes_sent "$http_referer" '
 29    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 30
 31    #access_log  logs/access.log  main;
 32
 33    # 是否开启高效传输模式 on开启 off关闭
 34    sendfile        on;
 35  
 36    #减少网络报文段的数量
 37    #tcp_nopush     on;
 38
 39    #keepalive_timeout  0;
 40    # 客户端连接保持活动的超时时间,超过这个时间之后,服务器会关闭该连接
 41    keepalive_timeout  65;
 42
 43    #gzip  on;
 44  
 45    # 虚拟主机的配置
 46    server {
 47        listen       80; # 虚拟主机的服务端口
 48        server_name  localhost; #用来指定IP地址或域名,多个域名之间用空格分开
 49
 50        #charset koi8-r;
 51
 52        #access_log  logs/host.access.log  main;
 53
 54        #URL地址匹配
 55        location / {
 56            root   html;  # 服务默认启动目录
 57            index  index.html index.htm; #默认访问文件,按照顺序找
 58        }
 59
 60        #error_page  404              /404.html;   #错误状态码的显示页面
 61
 62        # redirect server error pages to the static page /50x.html
 63        #
 64        error_page   500 502 503 504  /50x.html;
 65        location = /50x.html {
 66            root   html;
 67        }
 68
 69        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
 70        #
 71        #location ~ \.php$ {
 72        #    proxy_pass   http://127.0.0.1;
 73        #}
 74
 75        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 76        #
 77        #location ~ \.php$ {
 78        #    root           html;
 79        #    fastcgi_pass   127.0.0.1:9000;
 80        #    fastcgi_index  index.php;
 81        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
 82        #    include        fastcgi_params;
 83        #}
 84
 85        # deny access to .htaccess files, if Apache's document root
 86        # concurs with nginx's one
 87        #
 88        #location ~ /\.ht {
 89        #    deny  all;
 90        #}
 91    }
 92
 93
 94    # another virtual host using mix of IP-, name-, and port-based configuration
 95    #
 96    #server {
 97    #    listen       8000;
 98    #    listen       somename:8080;
 99    #    server_name  somename  alias  another.alias;
100
101    #    location / {
102    #        root   html;
103    #        index  index.html index.htm;
104    #    }
105    #}
106
107
108    # HTTPS server
109    #
110    #server {
111    #    listen       443 ssl;
112    #    server_name  localhost;
113
114    #    ssl_certificate      cert.pem;
115    #    ssl_certificate_key  cert.key;
116
117    #    ssl_session_cache    shared:SSL:1m;
118    #    ssl_session_timeout  5m;
119
120    #    ssl_ciphers  HIGH:!aNULL:!MD5;
121    #    ssl_prefer_server_ciphers  on;
122
123    #    location / {
124    #        root   html;
125    #        index  index.html index.htm;
126    #    }
127    #}
128}

虚拟主机

  • 什么是虚拟主机

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

  • Nginx 虚拟主机配置

 1server {
 2        listen       80;
 3        server_name  aabbcc.com;
 4
 5        location / {
 6            root   /usr/local/nginx/html;
 7            index  index.html;
 8        }
 9  }
10  
11  
12server {
13        listen       80;
14        server_name  aabbccdd.com;
15  
16        location / {
17            root   html;
18            index  xdclass.html index.htm;
19        }
20}

文件服务器

  • 图片服务器

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

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

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

1server {
2        listen       80;
3        server_name  aabbccdd.com;
4        location /app/img {
5          alias /usr/local/software/img/;
6        }
7  }

注意

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

Nginx 访问日志

access.log 日志用处

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

默认配置解析

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

案例

1122.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"

解析

 1$remote_addr 对应的是真实日志里的122.70.148.18,即客户端的IP。
 2
 3$remote_user 对应的是第二个中杠“-”,没有远程用户,所以用“-”填充。
 4
 5[$time_local]对应的是[04/Aug/2020:14:46:48 +0800]。
 6
 7“$request”对应的是"GET /user/api/v1/product/order/query_state?product_id=1&token=xdclasseyJhbGciOJE HTTP/1.1"。
 8
 9$status对应的是200状态码,200表示正常访问。
10
11$body_bytes_sent对应的是48字节,即响应body的大小。
12
13“$http_referer” 对应的是”https://xdclass.net/“,若是直接打开域名浏览的时,referer就会没有值,为”-“。
14
15“$http_user_agent” 对应的是”Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0”。
16
17“$http_x_forwarded_for” 对应的是”-“或者空。

运维平台案例统计

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

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

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

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

基础

1awk 是文本处理工具,默认按照空格切分,$N 是第切割后第N个,从1开始
2
3sort命令用于将文本文件内容加以排序,-n 按照数值排,-r 按照倒序来排
4  案例的sort -n 是按照第一列的数值大小进行排序,从小到大,倒序就是 sort -rn
5
6uniq 去除重复出现的行列, -c 在每列旁边显示该行重复出现的次数。

自定义日志统计接口性能

日志格式增加 $request_time

1从接受用户请求的第一个字节到发送完响应数据的时间,即包括接收请求数据时间、程序响应时间、输出响应数据时间
2
3$upstream_response_time:指从Nginx向后端建立连接开始到接受完数据然后关闭连接为止的时间(用于统计后端接口的响应时间)
4
5$request_time一般会比upstream_response_time大,因为用户网络较差,或者传递数据较大时,前者会耗时大很多(整个请求用户的响应时间)

配置自定义日志格式

 1log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 2                     '$status $body_bytes_sent "$http_referer" '
 3                      '"$http_user_agent" "$http_x_forwarded_for" $request_time';
 4
 5
 6server {
 7        listen       80;
 8        server_name  aabbcc.com;
 9
10        location / {
11            root   /usr/local/nginx/html;
12            index  xdclass.html;
13        }
14        #charset koi8-r;
15        #
16        access_log  logs/host.access.log  main;
17}

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

1cat time_temp.log|awk '($NF > 2){print $7}'|sort -n|uniq -c|sort -nr|head -5
2
3备注:$NF 表示最后一列, awk '{print $NF}'

Nginx 配置集群应用

安装 JDK8 环境

1JAVA_HOME=/usr/local/software/jdk8
2CLASSPATH=$JAVA_HOME/lib/
3PATH=$PATH:$JAVA_HOME/bin
4export 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 是目前多数公司选择使用的

配置案例

 1upstream lbs {
 2   server 192.168.0.106:8080;
 3   server 192.168.0.106:8081;
 4}
 5server{
 6	location /api/ {
 7    		proxy_pass http://lbs;
 8    		proxy_redirect default;
 9	}
10}

访问

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

负载均衡策略解析

Nginx 常见的负载均衡策略

  • 节点轮询(默认)

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

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

ip_hash(固定分发)

  • 简介:根据请求按访问 ip 的 hash 结果分配,这样每个用户就可以固定访问一个后端服务器
  • 场景:服务器业务分区、业务缓存、Session 需要单点的情况
 1upstream lbs {
 2   ip_hash;
 3   server 192.168.159.133:8080;
 4   server 192.168.159.133:8081;
 5}
 6
 7upstream还可以为每个节点设置状态值
 8	down 表示当前的server暂时不参与负载
 9	server 192.168.159.133:8080 down;
10
11backup 其它所有的非backup机器down的时候,会请求backup机器,这台机器压力会最轻,配置也会相对低
12	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 状态不被认为是失败的尝试。

配置实操

 1upstream lbs {
 2                server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ;
 3                server 192.168.0.106:8081 max_fails=2 fail_timeout=60s;
 4}
 5
 6
 7location /api/ {
 8         proxy_pass http://lbs;
 9         proxy_next_upstream error timeout http_500 http_503 http_404;
10}

案例实操

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

作者:Soulboy