【后端】Nginx+lua+OpenResty高性能实践


【后端&网络&大数据&数据库目录贴】

1.介绍

1.1 常用版本

常用版本分为四大阵营

在这里插入图片描述

1.2 其他web服务器

IIS、Apache Httpd1/2、lighttpd

1.3 nginx安装

1.3.1 离线安装

  • 普通(需联网)

将nginx包解压到linux中
./configure --prefix=/usr/local/nginx
报错:安装pcre: yum install -y pcre pcre-devel
报错安装zlib:yum install -y zlib zlib-devel
make & make install
**重新构建要 make clean清空缓存**

  • 普通(无需联网)

https://blog.csdn.net/achi010/article/details/106392040
./configure --prefix=/usr/local/nginx --with-http_ssl_module
--with-pcre=../pcre-8.37
--with-zlib=../zlib-1.2.11
--with-openssl=../openssl-1.1.0e
make && make install
其他说明:
(prefix用绝对路径,不然后面访问出错)
--without-http_rewrite_module忽略pcre包
--without-http_gzip_module忽略zlib包
如果配置https的网站,需要配置ssl命令--with-http_ssl_module
ssl:--with-http_ssl_module 一般和--with-openssl=xxx共用,否则会使用系统的openssl
nginx -V 可以查看各个模块
如果忘记配置ssl,则可以用另一种方式
在这里插入图片描述

  • 普通(无需联网)

2. 命令

启动 ./nginx
快速停止:./nginx -s stop
优雅关闭,在退出前完成已经接受的连接请求:./nginx -s quit
重新加载配置:./nginx -s reload
检查配置文件正确性: ./nginx -t
总结常用命令
nginx -v 查看版本号
./nginx //启动命令
./nginx -s stop //关闭命令
./nginx -s reload //重启命令
查看模块配置:./nginx -V
指定配置文件:./nginx -c conf/nginx-88.conf
指定配置文件检测:./nginx -c /app/openresty/11581/nginx/conf/nginx_http_9060_101.conf -t
/user/opt/openresty/nginx/sbin/nginx -c /user/opt/openresty/nginx/conf/nginx_http_9061.conf -t
指定配置文件重启./nginx -c /app/openresty/11581/nginx/conf/nginx_http_9060_101.conf -s reload
/user/opt/openresty/nginx/sbin/nginx -c /user/opt/openresty/nginx/conf/nginx_http_9061.conf -s reload

4. DNS解析过程

在这里插入图片描述

3. 配置

3.1 详解

配置详解
########### 每个指令必须有分号结束。#################
`#user administrator administrators;` #配置用户或者组,默认为nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为1
`#pid /nginx/pid/nginx.pid`; #指定nginx进程运行文件存放地址
`error_log log/error.log debug`; #制定日志路径,级别。这个设置可以放入全局块,`http`块,`server`块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
#use epoll; #事件驱动模型,
select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大连接数,默认为512
}
http {
	include mime.types; #文件扩展名与文件类型映射表
	default_type application/octet-stream; #默认文件类型,默认为	   text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request
$status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
#自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,
location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上
限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小
写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip

add_header 'Access-Control-Allow-Origin' *;//添加响应头header,解决跨域问题,可以放在server中,也可以放在localhost中
}
}
}

3.2 代理一个虚拟机

server{
		listen 8099;
		server_name 1.117.164.90;
		location / {
			proxy_pass https://123.sogou.com/?121264;

}

3.3 代理集群

upstream mm{
    	server 1.117.164.90:8080;
    	server 1.117.164.91:8080

}
server {
 listen 8099;
		server_name 1.117.164.90;
		location / {
			proxy_pass http://mm;
		}	 
}
 location / {        
 #/代表所有https://baidu.com后面拼接的应用服务都会转发到改server
	proxy_pass https://baidu.com;
    root   html;
    index  index.html index.htm;
}

3.4 负载均衡

#负载均衡策略
# 1 轮询(默认)
# 2 weight
# 3 ip_hash
# 4 least_conn 最少连接方式
# 5 fair(第三方) 响应时间
# 6 url_hash (第三方)

eg:
server 192.168.45.151:8080 weight=2;
server 192.168.45.151:8081 weight=1;

3.5 pid

注意:配置pid,否则多个配置文件,stop,reload都针对是…/logs/nginx.pid中的nginx
pid nginx8099.pid;//会放在logs下
或者
pid /easkapp/opt/openresty/nginx/nginx8099.pid;//绝对路径

3.6 虚拟主机

nginx支持三种类型的虚拟主机配置

  • 基于ip的虚拟主机, (一块主机绑定多个ip地址)
  • 基于域名的虚拟主机(servername)
  • 基于端口的虚拟主机(同一ip不同的端口)

3.7 相同端口号,不同访问域名

https://blog.csdn.net/qq_40737025/article/details/85053164

server {
        listen       82;
        server_name  jieyan22.com;
        location / {
            root   html/chen;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

server {
        listen       82;
        server_name  yanjie22.com;
        location / {
            root   html/yan;
            index  index.html index.htm;
        }  
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

3.8 一台主机开多个nginx(转发)

 upstream mysvr{
        server localhost:88;
        server localhost:99;


    }
    server {
        listen       84;
        server_name  localhost; 
        location / {
            proxy_pass http://mysvr;
            root   html/88;
            index  index.html index.htm;
        }
        
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    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;

    sendfile        on;
    #tcp_nopush     on;

    
    keepalive_timeout  65;

    

    upstream mysvr{
       # server localhost:88;
        #server localhost:99;
        server  localhost:87;

    }
    server {
        listen       84;
        server_name  localhost; 
        location / {
            proxy_pass http://mysvr;
            root   html/88;
            index  index.html index.htm;
        }

      
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

      
    }

  server {
        listen       87;
        server_name  jieyan33.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass https://baidu.com;
            root   /usr/local/ex/nginxone/nginxinstall_eight_ssl/conf/html/chen;
            index  index.html index.htm;
        }

      
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

      
    }

server {
        listen       82;
        server_name  yanjie33.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
           # proxy_pass https://baidu.com;
            root   html/yan;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

3.9 代理服务的安全问题

  • 反向代理安全问题
    在这里插入图片描述

  • 正向代理安全问题
    在这里插入图片描述

3.10 proxy_pass

两种方式

  • 方式一

proxy_pass 后面只有IP+端口,其他什么都没有,也不能以“/”结尾(以/结尾,则变为第二种匹配方式)。此时代理的路径,是将请求路径IP+端口后面的部分,追加到 proxy_pass 后面

server {
    listen  9003;
    server_name    192.168.25.131;

    location /first {
        proxy_pass http://localhost:8080;
    }
访问http://192.168.25.131:9003/first/a.html,实际访问的是http://192.168.25.131:8080/first/a.html    
  • 方式二

proxy_pass后面除了IP+端口,还有其他内容。此时的匹配逻辑,是将 location 未匹配到的内容,追加到 proxy_pass 后面

server {
   listen  9003;
   server_name    192.168.25.131;

   location /first2 {
       proxy_pass http://localhost:8080/first;
   }
}
如下配置,当我们请求 http://192.168.25.131:9003/first2/a.html,实际nginx代理地址为http://192.168.25.131:8080/first/a.html

3.11 root

root 的作用是将 location 的内容拼接到 root 后面
root 配置的是本地文件夹路径,而不是http路径
如下配置,浏览器打开 http://192.168.25.131:9003/html2/index.html
实际请求的是 /usr/local/nginx/html2/index.html

server {
    listen  9003;
    server_name    192.168.25.131;

    location /html2 {
        root /usr/local/nginx/;
        #root /usr/local/nginx; 结果一样
    }
}

3.12 alias

alias 作用是将请求地址剔除 location 配置的部分,然后拼接到 root 后面
如下配置,当请求地址是 http://192.168.25.131:9003/appeaskcommon/order/index.html
实际访问路径是/easka/eask-front/appeaskcommon/order/index.html

server {
    listen  9003;
    server_name    192.168.25.131;

    location /appeaskcommon {
        alias /easka/eask-front/appeaskcommon;
    }
}

3.13 location

location /aaa/ {
            root   /eask/test;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
}
//location匹配 → (root/alias确定基础路径) → try_files检查并提供资源 → (若涉及目录,应用index指令)
当location匹配发生后,$uri会被用来与root或alias
设置的基础路径组合(具体方式取决于使用的指令),以定位到实际的文件系统位置。例如,如果
root设置为/data/www,$uri 为/path/to/resource,那么实际查找的文件系统路径将是
 /data/www/path/to/resource。

3.14 动静分离

在这里插入图片描述

 location /test {
            proxy_pass http://1.117.164.90:8080/test2;
            
        }
        location /test/jsp{
            
            alias   /usr/static/jsp;
           index  index.html index.htm;
        }

3.15 正则匹配

location ~*(css|images|js)   匹配css,images,js请求
  • location 前缀

没有前缀 匹配以指定模式开头的location
= 精准匹配,不是以指定模式开头
~ 正则匹配,区分大小写
~* 正则匹配,不区分大小写
^~ 非正则匹配,匹配以指定模式开头的location
location匹配顺序

location匹配顺序
多个正则location直接按书写顺序匹配,成功后就不会继续往后面匹配
普通(非正则)location会一直往下,直到找到匹配度最高的(最大前缀匹配)
当普通location与正则location同时存在,如果正则匹配成功,则不会再执行普通匹配 
所有类型location存在时,“=”匹配  >  “^~”匹配  >  正则匹配  >  普通(最大前缀匹配)

3.16 rewrite重写

在这里插入图片描述

rewrite 作用是地址重定向,语法:rewrite regex replacement[flag];
根据 regex(正则表达式)匹配请求地址,然后跳转到 replacement,结尾是flag标记
在这里插入图片描述
在这里插入图片描述

server {
            listen       88;
            server_name  localhost;
            rewrite ^/test/(first|two)$ /test/$1Servlet last;
            location / {
            proxy_pass http://1.117.164.90:8080;
            }
        }

在这里插入图片描述

3.17 配置跨域

https://blog.csdn.net/wangshui898/article/details/124950235

server {
	listen 80; # 监听的端⼝
	server_name localhost; # 域名或ip
	location / { # 访问路径配置
		#允许跨域请求的域,* 代表所有
		add_header 'Access-Control-Allow-Origin' *;
		#允许带上cookie请求
		add_header 'Access-Control-Allow-Credentials' 'true';
		#允许请求的方法,比如 GET/POST/PUT/DELETE
		add_header 'Access-Control-Allow-Methods' *;
		#允许请求的header
		add_header 'Access-Control-Allow-Headers' *;
		root /usr/share/nginx/html;# 根⽬录
		index index.html index.htm; # 默认⾸⻚
		}
		error_page 500 502 503 504 /50x.html; # 错误⻚⾯
		location = /50x.html {
		root html;
	}

说明:

#允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;

3.18 常用配置

3.18.1 日志

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"'
                     '"$upstream_response_time" "$upstream_addr" "$upstream_status" "$request_time"';
access_log  logs/http_access.log  main;

4.NG构建PHP站点

使用条件:LMNP (linux+mysql+nginx+php)
https://oneinstack.com

9. HTTPS安全认证

http协议问题:

  • 明文传输,有被第三方截取到数据信息的风险 (加密处
    理)
  • 对于数据完整性:篡改数据(校验码)
  • 身份验证:无法确认发送者身份(密钥对)

9.1 证书

证书可以对身份进行验证,密钥对存在漏洞,黑客可以伪装
为发送者,生成密钥对,发送给接受者。
引入第三方证书,证书通过加密算法对内容进行加密,并且
证书可以明确的记录证书颁发机构的信息,证书使用者的相
关信息,从而接受者接收到证书,对证书信息通过公钥进行
验证,能够识别真实的发布者身份。

9.2 证书获取方式

  1. 通过官方机构购买证书
  2. 通过证书签发工具,自签证书。

9.3 自签证书-openssl工具

还有cfssl工具等等
免费签名 https://freessl.cn

  • SSL数据传输原理
    在这里插入图片描述
  • Openssl自签发证书

证书包含的内容:

  • 一对密钥对
  • 颁发者和使用者信息
  • 证书的相关信息
  • Openssl命令应用

yum install openssl -y
-in filename 指定要加密的文件的路径
-out filename 指定加密后的文件的存放位置
-salt 自动插入一个随机数到文件中
-e 指定加密算法
-d 解密算法

  • 自签发证书

openssl genrsa -out private.pem #生成私钥
openssl rsa -in private.pem -pubout -out key.pem # 根据生成对应公钥
openssl req -new -x509 -key private.pem -out ca.crt -days 36500 # 生成自签证书
(common name随便写即可)
在这里插入图片描述

9.4 Nginx配置HTTPS

server {
        listen 81 ssl;
        server_name localhost;
        ssl_certificate /usr/local/https/ca.crt;
        ssl_certificate_key /usr/local/https/private.pem;


        location / {
            root   html;
            index  index.html index.htm;
        }
    }
  • 可以将http转化成https的输入,自动跳转
server {
        listen 443 ssl;
        server_name localhost;
        ssl_certificate /usr/local/https/ca.crt;
        ssl_certificate_key /usr/local/https/private.pem;  
      

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            #root   html;
            #index  index.html index.htm;
            rewrite (.*) https://114.115.185.179/$uri redirect;
        }
   }     

9.5 springboot工程配置HTTPS

参考文章

  1. 需要生成SSL证书。这里为了简化操作,我们使用Java的keytool工具生成自签名的证书。在命令行中执行以下命令:
    keytool -genkey -alias tomcat -keyalg RSA -keystore ./keystore.jks -keysize 2048
  2. 配置Spring Boot服务器
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=your_keystore_password
server.ssl.key-alias=tomcat
  1. 将生成的keystore.jks文件复制到Spring Boot项目的src/main/resources目录下,以便服务器能够加载到它。
  2. 测试HTTPS连接
    启动Spring Boot应用。现在,你的应用已经支持HTTPS了

11. websocket转发配置

server {
    listen 80;
    server_name example.com;  # 你的域名
 
    location /ws/ {
        proxy_pass http://websocket_backend;  # websocket_backend 是你的 WebSocket 服务器的 upstream 名称
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
类似于 HTTP 转发,websocket_backend 应该是一个 upstream 指令定义的服务器组。
上面的配置中proxy_set_header Upgrade $http_upgrade 和 proxy_set_header Connection "upgrade" 
是 WebSocket 协议升级所需的标头。

100.常遇的问题

100.1 host

在 Nginx 中,当使用 proxy_pass 指令将请求转发到上游服务器时,默认情况下Host 头部字段的值会被设置为 proxy_pass 指令中指定的上游服务器的地址(通常是上游服务器的域名或 IP 地址和端口)。这是为了防止上游服务器无法识别原始请求的 Host 头部字段值。

然而,如果你希望保持原始请求的 Host 头部字段值不变,你可以使用 proxy_set_header 指令来明确设置 Host 头部字段的值。通常,你会这样做来保持原始请求的 Host 值:

location / {  
    proxy_pass http://your_upstream;  
    proxy_set_header Host $host;  
    # 其他可能的设置...  
}
// location ~^/(api/|socket.io/) { 正则
 location /baidu {
            proxy_pass  http://ragattu:3000/;
             proxy_set_header Host $http_host;
             proxy_set_header Cookie $http_cookie;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header X-Forwarded-Proto $scheme;
             proxy_set_header Access-Control-Allow-Origin *;
             proxy_connect_timeout    18000;
             proxy_read_timeout       18000;
             proxy_send_timeout       18000;
             client_max_body_size 300m;
             proxy_buffering off;
        }

101.2 proxy_set_header

指令用于修改转发到代理服务器(通常是后端应用服务器)的 HTTP 请求头

  • proxy_set_header Host $http_host

转发时会完整转发ip+port (80不会携带)

  • proxy_set_header Host $proxy_host

转发时会完整转发转发ip+port(80不携带)

  • proxy_set_header Host $host

仅携带host

101.3. nginx关闭server信息

https://cloud.tencent.com/developer/article/1182300

101.4 隐藏 版本号

  • 方式一

隐藏Nginx服务器在HTTP响应头或错误页面中返回的版本号(如您提供的示例中的“nginx/1.23.2”)
http {

server_tokens off;

}
最后,同样需要重启Nginx服务
这里,server_tokens off; 指令会关闭Nginx在响应头中发送其版本信息。

  • 方式二

如果即使设置了 server_tokens off;,您仍然在自定义的403错误页面中看到版本号(如 nginx/1.23.2),那是因为错误页面本身包含了这个信息。在这种情况下,您需要修改或替换对应的错误页面文件,移除版本号相关文本。
首先,确定您的Nginx配置中自定义403错误页面的位置。通常,这会在某个 server 或 location 块内的 error_page 指令定义:
error_page 403 /custom_error_pages/403.html;
然后,找到实际的HTML文件(例如 /usr/share/nginx/html/custom_error_pages/403.html 或其他指定路径下的文件),打开它并删除包含版本号的部分,即

nginx/1.23.2
或类似的代码片段。保存修改后的错误页面文件。
最后,同样需要重启Nginx服务

101.5 301 Moved Permantly

访问 http://localhost:80/app 报错
改成 http://localhost:80/app/

101.6 nginx自定义变量和引用

   set $apiserver api-server-svc.xxx.svc.cluster.local;#定义变量

  location /api {
      proxy_set_header   X-Forwarded-Proto $scheme;
      proxy_set_header   Host              $http_host;
      proxy_set_header   X-Real-IP         $remote_addr;
      rewrite /api/(.*) /$1 break;
      proxy_pass http://$apiserver:8080;
  }

101.7 k8s部署nginx自动更新域名及解除后端依赖

【nginx】解决k8s中部署nginx转发不会自动更新域名解析&启动失败的问题

101.8 set自定义变量

set $ingress xx.xx.xx.xx:8000;
如果直接在proxy_pass中使用http://$ingress会报错,因为Nginx 并不直接支持在 proxy_pass 中使用包含端口号的变量作为完整的 URL
在这里插入图片描述

101.9前端某些页面白屏问题

可能是nginx没有配置ssi功能

 server {
        listen       8099;
        server_name  localhost;
        ssi    on;
 }       

当你在Nginx配置文件中为某个位置(location)或服务器(server)块启用SSI时,Nginx会查找并处理这些块中文件的SSI指令。SSI指令通常以特定的注释形式出现,比如<!--#include file="filename.html" -->,用于在页面中包含其他文件的内容。
要在Nginx中启用SSI,你需要在Nginx的配置文件中(通常是nginx.conf或某个*.conf文件,位于/etc/nginx/conf.d/、/etc/nginx/sites-available/等目录)设置ssi on;。这个指令可以放在http、server或location块中,具体取决于你希望在哪里启用SSI。

当在Nginx配置中启用了SSI(ssi on;)之后,Nginx会在处理包含SSI指令的文件时执行这些指令。这通常发生在Nginx将文件发送给客户端之前,即在HTTP响应被发送出去之前

101.10 打印所有headers信息

修改日志打印级别:error_log  logs/error.log  info;

location /aaa/{
            proxy_pass  http://nginx:9999;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Access-Control-Allow-Origin *;
            proxy_connect_timeout    18000;
            proxy_read_timeout       18000;
            proxy_send_timeout       18000;
            client_max_body_size 300m;
            proxy_buffering off;
            access_by_lua_block {
                     local req = ngx.req
                     local headers = req.get_headers()
                     local header_str = ""
                     for header, value in pairs(headers) do
                         header_str = header_str .. header .. ": " .. value .. "\n"
                     end
                    ngx.log(ngx.INFO, "Request Headers:\n" .. header_str)
            }
        }

101.11 header默认规则

在这里插入图片描述

101.12 underscores_in_headers on;

Nginx能够识别并转发包含下划线的header
默认会删除下划线的

102.13 ingress配置

ingress默认也会忽略下划线header,需要在configMap中添加

enable-underscores-in-headers: true在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值