当前位置:   article > 正文

nginx+lua+redis实践_nginx lua redis

nginx lua redis

nginx+lua+redis实践

1.概述

nginx、lua访问redis的三种方式:

  1. HttpRedis模块。

指令少,功能单一,适合简单的缓存。只支持get 、select命令。

  1. HttpRedis2Module模块。

功能强大,比较灵活。

  1. lua-resty-redis库

OpenResty。api。适合复杂业务,节省内存。

OpenResty:基于nginx开源版本的一个扩展版本。集成了大量的精良的lua库。

2.OpenResty安装

安装wget

 yum install wget
  • 1

下载资源库

wget https://openresty.org/package/centos/openresty.repo
  • 1

得到文件: openresty.repo

安装OpenResty

 yum install openresty
  • 1

启动OpenResty,也可以进去到sbin目录下,执行./nginx进行启动

/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/nginx/
  • 1

OpenResty安装失败参考:https://blog.csdn.net/weixin_57147852/article/details/132800949

测试访问:

image-20231220095827356

初试测试lua,修改conf

server {
        listen 8080;
        location / {
          default_type text/html;
          content_by_lua 'ngx.say("hello my openresty")';
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

image-20231220100723342

3.redis安装

安装epel:第三方的源(软件安装包)

yum install epel-release
  • 1

安装redis

yum install redis
  • 1

启动redis

systemctl start redis
  • 1

测试redis

redis服务端和redis客户端

which redis-cli
# /usr/bin/redis-cli
cd /usr/bin/
./redis-cli
  • 1
  • 2
  • 3
  • 4

image-20231220101204634

4.HttpRedis

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-httpredis.conf文件,修改该文件并使用该文件进行启动

nginx-httpredis.conf

worker_processes  1;



events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  www.cpf.com;
	root html;
	index index.html;

        location / {
	    default_type text/plain;
    	    set $redis_key "m";
            redis_pass 127.0.0.1:6379;
	    	error_page 404 = @fetch;
        }

	location @fetch {
 	    root html;
 	}


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

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

在sbin目录下执行

./nginx -c /usr/local/openresty/nginx/conf/nginx-httpredis.conf
  • 1

测试一下:

  1. redis中没有 key为m的 键值对,在/usr/local/openresty/nginx/html目录下创建1.html内容如下

    hello llp
    
    • 1

    image-20231220105623277

  2. 我们通过redis,设置key为m的value是:“llp”(m=llp)

img

扩展:用于降级,当redis中存在某个key时,就访问缓存中的数据,不存在则正常访问页面,当流量过大时我们将redis对应的限流的key进行赋值就可以实现限流

5.HttpRedis2Module

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-httpRedis2Module.conf文件,修改该文件并使用该文件进行启动

nginx-httpRedis2Module.conf

worker_processes  1;



events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  www.cpf.com;
	root html;
	index index.html;

	
	location /get {
 		redis2_query get $key;
 		redis2_pass 127.0.0.1:6379;
 	}
	location /set {
 		redis2_query set $key 'nValue';
 		redis2_pass 127.0.0.1:6379;
 	}

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

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

image-20231220124845461

6.openresty-lua-redis

参考地址:https://github.com/openresty/lua-resty-redis

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-openresty-lua-redis.conf文件,修改该文件并使用该文件进行启动

nginx-openresty-lua-redis.conf

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

	location / {
	    # 请求没有指定内容类型,Nginx会返回HTML内容。
 	    default_type text/html;
 	    content_by_lua_file /usr/local/openresty/nginx/lua/lua-openresty-redis.lua;
	 }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

lua-openresty-redis.lua

-- 引用resty的redis
local redis = require "resty.redis";
local red = redis:new();

-- 连接redis
local ok,err = red:connect("127.0.0.1",6379);
if not ok then
 ngx.say("faild to connect",err);
 return
end

ok,err = red:set("dKey","dValue");
if not ok then
 ngx.say("failed to set dKey",err);
 return
end
ngx.say("dKey set dValue success")
return
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

测试效果

image-20231220143958447

image-20231220144013862

分析OpenResty响应信息:

目的:为了修改以后的响应信息。

 server {
 listen 8081;
 location / {
 	default_type text/html;
 	content_by_lua_block {
 		ngx.say("hi block");
 		}
 	}
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

7.获取请求参数信息

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-param.conf文件,修改该文件并使用该文件进行启动

nginx-param.conf

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
            # 请求没有指定内容类型,Nginx会返回HTML内容。
            default_type text/html;
            content_by_lua_file /usr/local/openresty/nginx/lua/lua-http-param.lua;
         }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

编写lua脚本,在/usr/local/openresty/nginx/lua目录下创建lua-http-param.lua文件

lua-http-param.lua

-- 获取get请求的参数
local arg = ngx.req.get_uri_args();
for k,v in pairs(arg)
do
 ngx.say("key:",k," value:",v);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

将请求参数保存到redis中:

-- 获取get请求的参数
local redis = require "resty.redis";
local red = redis:new();
red:connect("127.0.0.1",6379);
-- 省去链接错误的判断,前面课程中有
local arg = ngx.req.get_uri_args();
for k,v in pairs(arg)
do
 ngx.say("key:",k," value:",v);
 red:set(k,v);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

测试: http://192.168.182.111/?id=1

8.获取请求头参数

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-header.conf文件,修改该文件并使用该文件进行启动

nginx-header.conf

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
            # 请求没有指定内容类型,Nginx会返回HTML内容。
            default_type text/html;
            content_by_lua_file /usr/local/openresty/nginx/lua/lua-http-header-param.lua;
         }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

编写lua脚本,在/usr/local/openresty/nginx/lua目录下创建lua-http-header-param.lua文件

lua-http-header-param.lua

-- 获取header参数
local headers = ngx.req.get_headers();
for k,v in pairs(headers)
do
 ngx.say("[header] key:",k," value:",v);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

测试:

image-20231220163450595

9.获取post body 键值对 参数

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-body.conf文件,修改该文件并使用该文件进行启动

nginx-body.conf

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
            # 请求没有指定内容类型,Nginx会返回HTML内容。
            default_type text/html;
            content_by_lua_file /usr/local/openresty/nginx/lua/lua-body.param.lua;
         }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

编写lua脚本,在/usr/local/openresty/nginx/lua目录下创建lua-body.param.lua文件

lua-body.param.lua

-- 获取post body kv参数
-- 重要:读取body
ngx.req.read_body();
local postArgs = ngx.req.get_post_args();
for k,v in pairs(postArgs)
do
 ngx.say("[post] key:",k," value:",v);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试:

10.nginx+lua+redis限流实战

限流业务

需求:系统每秒限流2个请求,如果超过 阈值(每秒2个请求),则系统限制10秒内,不能被访问。

image-20231225102945101

修改配置文件,在配置文件目录下cp一份 nginx.conf 得到nginx-lmit-ip.conf文件,修改该文件并使用该文件进行启动

nginx-lmit-ip.conf

worker_processes  1;
error_log  logs/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       8083;
        server_name  localhost;
        location / {
                default_type text/html;
                #限流脚本
                access_by_lua_file /usr/local/openresty/nginx/lua/ip-limit-access.lua;
                #日志记录
                log_by_lua_file /usr/local/openresty/nginx/lua/ip-limit-log.lua;
                proxy_pass http://localhost:8080/;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

限流脚本ip-limit-access.lua

ngx.log(ngx.INFO,"ip limit access");
local redis = require "resty.redis";
local red = redis:new();
--链接redis
local ok,err = red:connect("127.0.0.1",6379);
-- 需要写链接成功的判断。
if not ok then
 ngx.say("faild to connect",err);
 return
end

--判断是否限流,limit为限流标记1表示需要进行限流
limit = red:get("limit");
if limit == '1' then
 return ngx.exit(503);
end
inc = red:incr("testLimit");
if inc <= 2 then
 red:expire("testLimit",1);
else
 red:set("limit",1);
 red:expire("limit",10);
end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

编写日志脚本ip-limit-log.lua

ngx.log(ngx.INFO,"ip limit log");
  • 1

测试限流:

每秒两个请求以内

image-20231225103650098

每秒请求超过两次请求,则会进行限流

image-20231225103720230

11.防爬虫

概述

当爬虫影响到我们网站的性能。

爬虫的种类:

  1. 善意的。百度,google。

  2. 恶意的。恶意窃取网站内容。

robots协议:

防爬虫的方法:现在爬虫ip,对我们系统的请求。

扩展:限制爬虫的方法:

  1. 限制user-agent。

  2. 限制ip。

  3. 添加验证码。

  4. 限制cookie

这里以限制ip为例:

image-20231225104400262

需求&步骤分解

  1. 收集黑名单IP

  2. 存储到redis的set集合中

  3. nginx定期(2s)去从redis取 黑名单 ip 集合

  4. 当请求来的时候,进行判断。请求来源的ip是否在ip黑名单中

Redis黑名单准备

用set类型

key:ip-black-list

192.168.25.69

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/921551
推荐阅读
相关标签
  

闽ICP备14008679号