微服务API网关能力调用 微服务api网关选择nginx_nginx

 

一、单节点场景

微服务API网关能力调用 微服务api网关选择nginx_nginx_02

微服务API网关能力调用 微服务api网关选择nginx_nginx_03

 网关的作用:

  • 统一入口
  • 安全:黑名单、权限身份认证
  • 限流:实现微服务访问流量计算,基于流量计算分析进行限流,可以定义多种限流规则
  • 缓存:数据缓存
  • 日志:日志记录
  • 监控:记录请求响应数据,api耗时分析,性能监控
  • 重试:异常重试
  • 熔断:降级

现有网关框架:

微服务API网关能力调用 微服务api网关选择nginx_服务器_04

二、网关技术选型

微服务:dubbo,spring cloud

反向代理框架:nginx

kong、orange(nginx + lua)技术

lua脚本开发,游戏开发--lua脚本,

nginx,  openresty升级版本的nginx,lua类库

---------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------

nginx + lua:黑/白名单、限流

zuul: 重试、熔断

微服务API网关能力调用 微服务api网关选择nginx_服务器_05

 nginx的安装:

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_06

 

微服务API网关能力调用 微服务api网关选择nginx_nginx_07

三、正向代理和反向代理

正向代理:

        用户知道网站C的地址,但是因为网络原因访问不了;但服务器A可以访问服务器C, 这样用户可以把服务器A设置为正向代理服务器。由服务器A去请求服务器C,然后服务器A把数据返回给用户;

微服务API网关能力调用 微服务api网关选择nginx_nginx_08

反向代理:

        用户需要访问一些服务器应用,但对方不想把服务器地址暴露给用户,这样可以确保安全。

那用户怎么访问呢?可以通过反向代理服务器,用户只需要知道反向代理服务器地址就可以 ,最后反向代理服务器去访问服务器的应用;

微服务API网关能力调用 微服务api网关选择nginx_spring_09

 总结:

正向代理服务器和反向代理服务器的区别:

  • 1. 正向代理:是需要在用户的电脑上,配置正向代理服务器的;而反向代理不需要,因为用户是直接访问的反向代理服务器
  • 2. 应用场景:

        正向代理的应用场景:  用户是知道目标服务器的地址,如:www.google.com,但是不能直接访问,那么就需要在用户电脑配置一个正向代理服务器,用户再次访问的地址:www.google.com;

        反向代理的应用场景:用户本来就不知道目标服务器的地址;而是由平台方提供一个反向代理服务器的地址,用户直接访问反向代理服务器的地址就行;不管目标服务器有多少,用户不需要关心,只要访问反向代理服务器就ok;由反向代理服务器去解析访问目标服务器;

  • 3. 反向代理:极大的保护了应用的安全性,而且此结构可以很好的搭建负载均衡;

四、nginx命令和信号控制:

4.1、nginx命令: 

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_10

4.2、nginx检查配置文件

检查配置文件是否正确:

第一种:  进入nginx可执行程序的目录

# cd /usr/local/nginx/sbin/
# ./nginx -t

第二种:

# /usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf

4.3、nginx的信号控制

Nginx支持2种进程模型:Single和Master-Worker

Single是单进程,一般不适用

Master-Worker是主进程和工作进程模型运行,主进程对工作进程管理。

Nginx允许我们通过信号来控制主进程,用信号的方式可以达到不影响现有连接的目的。

信号类型:

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_11

  

微服务API网关能力调用 微服务api网关选择nginx_服务器_12

 4.3.1、nginx平滑升级

1.平滑升级

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_13

2. 执行信号平滑升级

微服务API网关能力调用 微服务api网关选择nginx_spring_14

3.kill -WINCH 旧的主进程号

 

微服务API网关能力调用 微服务api网关选择nginx_spring_15

4. #kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin` 优雅的关闭

给旧的主进程发送QUIT信号后,旧的主进程退出,并移除logs/nginx.pid.oldbin文件,nginx的升级完成;

 查看一下升级后的版本:

./nginx -V

4.3.2 中途停止升级,回滚到旧的nginx

在步骤(3)时,如果想回到旧的nginx不再升级:

1. 给旧的主进程号发送HUP命令,此时nginx不重新读取配置文件的情况下,重新启动旧主进程的工作进程。

kill -HUP 9944    -- 旧主进程号

重启工作进程

2. 优雅的关闭新的主进程

kill -QUIT 10012     --新主进程号

五、nginx的配置文件

nginx.conf文件

-- 以什么样的用户权限去运行程序,nobody是个低权限用户,为了安全,下面注释掉
#user  nobody;
-- worker的进程数(根据CPU的内核数设置,一般设置为CPU核数),nginx启动的时候会开两种进程,master进程用来管理调度,worker进程用来处理请求
worker_processes  1; 
#查看CPU核数
#cat /proc/cpuinfo


--全局错误日志输出(nginx的error_log类型如下:从左到右:debug最详细,crit最少)
#[ debug | info | notice | warn | error | crit ]
#例如:error_log  logs/error.log  crit;
#解释:日志文件存储在nginx安装目录下的 logs/error.log, 错误类型为 crit,也就是记录最少错误信息;

#error_log  logs/error.log;  
#error_log  logs/error.log   notice;
--info 日志输出等级
#error_log  logs/error.log   info;  

--PID文件,记录当前启动的nginx的进程ID
#pid           logs/nginx.pid;  


events {
        --单个worker进程最多开启的线程数(默认:1024),如1个word能同事允许多少连接,一个子进程最大允许连接1024个连接(优化设置应该等同于worker_rlimit_nofile设置值,表明一个线程处理一个http请求,同时可以处理一个文件数,各个模块之间协调合作不等待)
        worker_connections  1024;
}

--设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
        -- 默认打开的文件类型
        --设定mime类型,类型由mime.type文件定义
        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_referer"   '
        #                     ' "$http_user_agent"  "$http_x_forwarded_for"   ';


        --对应上面的日志格式
        #access_log           logs/access.log   main;
        --开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统负载。注意:如果图片显示不正常,把这个改为off
        sendfile          on;
        tcp_nopush        on; --防止网络阻塞
        tcp_nodelay       on; --防止网络阻塞

        --长链接超时时间(秒)
        #keepalive_timeout   0;

        keepalive_timeout   65;
        --开启gzip压缩
        #gzip  on;
        #gzip_disable    "MSIE [1-6]\."; --IE6及以下禁止压缩
        #gzip_min_length   1k; --最小压缩文件大小
        #gzip_buffers  4  16k; -- 压缩缓存区
        #gzip_http_version    1.0; -- 压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
        #gzip_comp_level    2; --压缩等级
        #gzip_types    text/plain    application/x-
        #gzip_vary    on; --给CDN和代理服务器使用,针对相同url,可以根据头信息返回压缩和非压缩副本
        
        
        
        #设定请求缓存
        client_header_buffer_size    1k; --上传文件大小限制
        large_clinet_header_buffers  4  4k; --设定请求缓存


        #设定负载均衡的服务器列表(可以配置多个)(不配置也可以)
        upstream mysvr {
            #weight参数表示权值,权值越高被分配到的几率越大
            server  92.168.8.1x:3128  weight=5;
            server  92.168.8.2x:80    weight=1;
            server  92.168.8.3x:80    weight=6;

        }

        upstream mysvr2 {
            #weight参数表示权值,权值越高被分配到的几率越大
            server  92.168.8.x:80    weight=1;
            server  92.168.8.x:80    weight=6;

        }

        --配置虚拟主机段
        server  {
            --监听的端口
            listen        80;
            --访问的域名(域名可以有多个,用空格隔开)
            server_name    localhost;
            --设置编码
            #charset        koi8-r;
            --设定本虚拟主机的访问日志
            #access_log    logs/localhost.access.log    main;

            --路由(定位:把特殊的路径或文件再次定位)
            location / {
                --定义服务器的默认网站根目录位置
                root    /root;
                --定义首页索引文件的名称
                index   index.html    index.html;
                --请求转向mysvr 定义的服务器列表
                proxy_pass    http://mysvr;
            }

            # 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  /root;
            }

            --本地动静分离反向代理配置(所有jsp的页面均交由tomcat或resin处理)
            location ~ .(jsp|jspx|do)?$ {
                proxy_set_header  Host  $host;
                proxy_set_header  X-Real-IP  $remote_addr;
                proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_pass  http://127.0.0.1:8080;
            }

            --静态文件,nginx自己处理
            location ~ ^/(images|javascript|js|css|flash|media|static)/ {
                root /var/www/virtual/htdocs;
                --过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置的小一点
                expires  30d;
            }

            --设定查看Nginx状态的地址
            location /NginxStatus {
                stub_status  on;
                access_log   on;
                auth_basic   "NginxStatus";
                auth_basic_user_file  conf/htpasswd;
                --htpasswd文件的内容可以用apache提供的htppasswd工具来产生;

            }

            --禁止访问  .htxxx文件
            location ~ /\.ht {
                deny all;
            }

            # proxy the PHP scripts to Apache listening on 127.0.0.1:80
            #
            # location ~ \.php${
                proxy_pass    http://127.0.0.1;
            #}

            # proxy the PHP scripts to FastCGI server listening on 127.0.0.1:9090
            #
            # location ~ \.php${
            #    root            html;
            #    fastcgi_pass    http://127.0.0.1:9000;
            #    fastcgi_index   index.php;
            #    fastcgi_param   SCRIPT_FILENAME    /scripts$fastcgi_script_name;
            #    include         fastcgi_params;
            #}

        }

        server {
        
        }
}

微服务API网关能力调用 微服务api网关选择nginx_spring_16

六、nginx配置连接数

 处理高并发等

 worker_processes: 表示开启nginx的worker进程的个数,nginx启动会开两种进程,master进程用来管理调度,worker进程用来处理请求;

下面表示两种设置方法,比如:

微服务API网关能力调用 微服务api网关选择nginx_服务器_17

 注: 如果服务器CPU有限,

比如:2核CPU,开启2个进程,设置如下:

        worker_processes  2

        worker_cpu_affinity  01  10;

比如:2核CPU,开启4个进程,设置如下:

        worker_processes  4

        worker_cpu_affinity  0001  0010  0100  1000;

比如:8核CPU,开启4个进程,设置如下:

        worker_processes  8

1个worker进程能够最大打开的文件数(线程数)worker_connections=65535(参考worker_rlimit_nofile)

--------------------------------------------------------------------------------------------------------------

#nginx作为http服务器

请求模型: client <----------> nginx

#max_clients = worker_processes * worker_connections/2

#nginx作为反向代理服务器的时候

请求模型: client <----------> nginx <-------------> web server

#max_clients = worker_processes * worker_connections/4

微服务API网关能力调用 微服务api网关选择nginx_服务器_18

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_19

七、nginx的虚拟主机

原始客户端访问不同的网站,需要部署多台主机:

微服务API网关能力调用 微服务api网关选择nginx_服务器_20

 配置nginx虚拟主机后:

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_21

7.1 虚拟主机

        虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台"虚拟"的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Internet服务器功能(WWW、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。

        从网站 访问者来看,每一台虚拟主机和一台独立的主机完全一样。利用虚拟主机,不用为每个要运行的网站提供一台单独的Nginx服务器或单独运行一组Nginx进程。虚拟主机提供了在同一台服务器、同一组Nginx进程上运行多个网站的功能;

7.2 配置虚拟主机

        我们先配置在一个nginx中配置一个虚拟主机,编辑nginx.conf配置文件,在http模块中,配置server模块,一个server模块就针对一个虚拟主机;

        我们模拟一个独立的网站,此网站域名访问www.server1.com;网站的根目录放到nginx目录下html/server1目录,我们创建一个首页index.html到server1中,编辑index.html

<!DOCTYPE html>
<html>
<head>
    <title>server1 首页 </title>
</head>
<body>
    <h1>server1 首页</h1>
</body>
</html>

下面我们回到nginx.conf配置文件中,配置server模块

#虚拟主机server1模板
server {
    #监听80端口
    listen  80;
    #虚拟主机名称,可以为域名或Ip地址
    server_name    www.server1.com;

    charset  utf-8;
    
    #默认请求路由
    location / {
        root html/server1;
        index index.html  index.htm;
    }
}

#虚拟主机server2模板
server {
    #监听80端口
    listen  80;
    #虚拟主机名称,可以为域名或Ip地址
    server_name    www.server2.com;

    charset  utf-8;
    
    #默认请求路由
    location / {
        root html/server2;
        index index.html  index.htm;
    }
}

注:       

1. nginx.conf 每次更新,都需要重启nginx

2. 配置server模块时,监听的端口 listen 和 server_name 组合起来是唯一的,如果server_name一样,那么listen监听的端口就不一样;

        如端口一样,server_name就不一样;

        虚拟主机的请求映射系统才能够判别;

访问server1的网址:

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_22

更新hosts文件:

添加server2的网址

微服务API网关能力调用 微服务api网关选择nginx_spring_23

访问server2的网址: 

 

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_24

 八、nginx日志以及切割

error_log  logs/error.log :nginx启动时,监听nginx状态的输出日志
 

--全局错误日志输出(nginx的error_log类型如下:从左到右:debug最详细,crit最少)
#[ debug | info | notice | warn | error | crit ]
#例如:error_log  logs/error.log  crit;
#解释:日志文件存储在nginx安装目录下的 logs/error.log, 错误类型为 crit,也就是记录最少错误信息;

#error_log  logs/error.log;

微服务API网关能力调用 微服务api网关选择nginx_服务器_25

 http里面的access.log 负责输出客户访问网站服务器时的日志

--设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
        -- 默认打开的文件类型
        --设定mime类型,类型由mime.type文件定义
        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_referer" '
        #                     '"$http_user_agent"  "$http_x_forwarded_for" ';

        --对应上面的日志格式
        #access_log           logs/access.log   main;
        --开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统负载。注意:如果图片显示不正常,把这个改为off
        sendfile          on;
       
}

8.1 日志文件格式配置

微服务API网关能力调用 微服务api网关选择nginx_nginx_26

$http_x_forwarded_for : 是反向代理服务器转发客户端地址的参数

 

        假设将nginx服务器作为web服务器,位于负载均衡设备、Squid、Nginx,反向代理之后,不能获取到客户端的真实IP地址了;

        原因:经过反向代理之后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的IP;

        解决:通过$remote_addr变量拿到的将是反向代理服务器的IP地址,但是,反向代理服务器在转发请求的HTTP头信息中,可以增加X-Forward-For信息,用以记录原有的客户端IP地址和原来客户端请求的服务器地址;

        这时候,要用log_format指令设置日志格式,让日志记录X-Forearded-For信息中的IP地址,即客户的真实IP

微服务API网关能力调用 微服务api网关选择nginx_服务器_27

8.2 access_log 指令

语法:access_log path [format [buffer=size [flush=time] ] ]

access_log  path  format  gzip[=level]  [buffer = size] [flush = time]

access_log off;

默认值:access_log  logs/access.log  combined;

配置段:

  • gzip 压缩等级
  • buffer 设置内存缓存区大小
  • flush 保存在缓存区中的最长时间

不记录日志:access_log off;

使用默认combined格式记录日志:access_log logs/access.log  或 access_log  logs/access.log  combined;

值得注意的是:Nginx进程设置的用户和组必须对日志路径有创建文件的权限,否则,会报错;

此外,对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭。可以使用open_log_file_cache来设置日志文件缓存(默认是off);

8.3 日志文件切割

        nginx日志默认情况下统一写入一个文件中,文件会变得越来越大,非常不方便查看分析。以日期来作为日志的切割是比较好的,通常我们是以每日来做统计的;

下面说一下nginx日志切割:

一般以日期作为名称来分割存储

access.log  -------->access-2022-07-03.log -------->access-2022-07-04.log

通过mv命令,把当前log文件重命名

        mv logs/access.log  logs/access-2022-07-03.log

系统自动切割:

利用sh脚本的方式执行刚才的手动操作,在每天凌晨执行一个计划任务,调用sh脚本,就完成的系统自动切割日志文件

编写脚本:

微服务API网关能力调用 微服务api网关选择nginx_spring_28

 

微服务API网关能力调用 微服务api网关选择nginx_服务器_29

 

九、nginx的location详解

9.1 语法规则:

构成:

指令                         前缀                uri

location                    [=|~|~*|^~]       /uri

9.2 location 区分普通匹配和正则匹配

微服务API网关能力调用 微服务api网关选择nginx_服务器_30

 location 作用于server模块,且支持多个location模块

server {
    ....
    location /p {
        root  html/p;
        index  index.html  index.htm;

    }
    location = /50x.html {
        root  html;
    }
    location / {
        root  html/server1;
        index  index.html  index.htm;

    }


}

在多个location 情况下,是按照什么原则进行匹配的?

1. 匹配的原则:

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_31

 2. 正则匹配:

为顺序匹配

微服务API网关能力调用 微服务api网关选择nginx_spring_32

 3. 如果location有普通匹配也有正则匹配,那匹配的原则为:

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_33

例子:有如下匹配的规则: 

    

微服务API网关能力调用 微服务api网关选择nginx_nginx_34

 

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_35

 4. 在实际场景中,通常至少有三个匹配规则定义,如下:

#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理。

这里是直接转发给后端应用服务器了,也可以是一个静态首页

微服务API网关能力调用 微服务api网关选择nginx_服务器_36

 

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_37

 

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_38

 

 十、nginx的负载均衡

当一台服务器单位时间内访问量很大的时候,服务器压力就会很大,当达到这台服务器的极限,就会奔溃,

怎么解决?

可以通过nginx的反向代理设置,添加几台同样功能的服务器,分担压力;

nginx实现负载均衡的原理:

        用户首先访问到nginx服务器,然后nginx服务器再从应用服务器集群中选择压力比较小的服务器,然后将该访问请求引向该服务器。

        如应用服务器集群中某一台服务器奔溃,那么从待选择服务器列表中将该服务器删除,也就是说一个服务器奔溃了,那么nginx服务器不会把请求引向到该服务器;

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_39

 

三种负载均衡方案:

#随机轮询
upstream mypro {
    server 192.168.5.140:8080;
    server 192.168.5.141:8080;
}

#权重值
upstream mypro {
    server 192.168.5.140:8080 weight=5;
    server 192.168.5.141:8080 weight=10;
}

ip_hash
upstream mypro {
    ip_hash;
    server 192.168.5.140:8080;
    server 192.168.5.141:8080;
}

 十一、nginx 的echo模块安装

十二、openresty 

12.1 openresty 背景

微服务API网关能力调用 微服务api网关选择nginx_服务器_40

 

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_41

 

12.2 openresty 安装

1. 下载安装 

微服务API网关能力调用 微服务api网关选择nginx_nginx_42

 #选择模块: ./configure  -- help

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_43

2. 安装成功后,默认会在 /usr/local/openresty/

 

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_44

3. 设置环境变量

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_45

 

12.3 openresty 的hello world

1. ngx_lua模块的hello world 

编辑nginx下conf配置文件nginx.conf

微服务API网关能力调用 微服务api网关选择nginx_nginx_46

 

微服务API网关能力调用 微服务api网关选择nginx_spring_47

 2. nginx的内部变量

微服务API网关能力调用 微服务api网关选择nginx_spring_48

 

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_49

 

微服务API网关能力调用 微服务api网关选择nginx_nginx_50

 

微服务API网关能力调用 微服务api网关选择nginx_spring_51

结果:

微服务API网关能力调用 微服务api网关选择nginx_虚拟主机_52

 

十三、lua

13.1 lua介绍

微服务API网关能力调用 微服务api网关选择nginx_微服务API网关能力调用_53

 

微服务API网关能力调用 微服务api网关选择nginx_nginx_54

 

13.2lua基本语法一

13.3 lua基本语法二

13.4 lua基本语法三

13.5 lua基本语法四

13.6 lua运算符