秒杀 假如100W 100商品
前台:
做登录、实名认证、会员等认证、
点击确定按钮做分流提交
后台:
假如90W数据到后台
第一个nginx(集群)做负载,直接削峰30W
第二层nginx做反向代理 削峰到几百
使用redis直接 原子操作 如果是预销售,那么就存到kafka等待客户支付的时候在真正去数据库减操作
为什么lua能承受高并发
因为nginx能承受高并发,所以lua能承受
Lua的基础练习
https://gitee.com/Xiaokeworksveryhard/Million-level-flow/tree/master/lua
nginx不适合做集群,适合做高可用
dns
一个域名可以配置多个ip,通过客户访问dns,dns通过一定策略跳转到对应的ip,做到第一层分流
Lua整合Redis
登录redis
[root@ke01 ~]# redis-cli -h ke01 -p 6379 ke01:6379> set aa 1 (error) NOAUTH Authentication required. ke01:6379> auth 123456 OK
redis操作eval
ke01:6379> eval "return 1 + 1" 0 (integer) 2 ke01:6379> eval "return 1 + 2" 0 (integer) 3 ke01:6379> eval "local msg='hello-' return msg .. KEYS[2]" 2 aaa bbb "hello-bbb" ke01:6379> eval "local msg='hello-' return msg .. KEYS[3]" 3 aaa bbb ccc "hello-ccc" KEYS[2] 2代表取第几个参数 后面的3 代表一共有几个数 获取key的value:
local key=KEYS[1]
local list=redis.call("get",key);
return list;
[root@ke01 lua]# redis-cli -h ke01 -p 6379 -a 123456 --eval test02.lua a ? 2>/dev//null
"xiaoke"
读取redis集合中的数据:
local key=KEYS[1]
local list=redis.call("lrange",key,0,-1);
return list;
[root@ke01 lua]# redis-cli -h ke01 -p 6379 -a 123456 --eval test01.lua age ? 2>/dev//null
1) "18"
2) "16"
3) "20"
4) "52"
[root@ke01 lua]# redis-cli -h ke01 -p 6379 -a 123456 --eval test01.lua name ? 2>/dev//null
1) "xiaoke"
2) "xiaowang"
统计点击次数
local msg='count:'
local count = redis.call("get","count")
if not count then
redis.call("set","count",1)
end
redis.call("incr","count")
return msg..count+1
[root@ke01 lua]# redis-cli -h ke01 -p 6379 -a 123456 --eval test03.lua a ? 2>/dev//null
"count:1"
[root@ke01 lua]# redis-cli -h ke01 -p 6379 -a 123456 --eval test03.lua a ? 2>/dev//null
"count:2"
生产环境下部署:
[root@ke01 lua]# redis-cli -a 123456 script load "$(cat test02.lua)"
"43dd2a515754c08fb75f031c56e86986b8659b60"
[root@ke01 lua]# redis-cli -a 123456 evalsha "43dd2a515754c08fb75f031c56e86986b8659b60" 1 a
"xiaoke"
搭建Nginx+lua开发环境(openresty)
参考:https://blog.csdn.net/weixin_37998647/article/details/79826316
测试lua脚本
在Nginx.conf 中写入 location /lua { default_type text/html; content_by_lua ' ngx.say("Hello, World!
") '; } 结果: 访问:ip:80/lua 页面显示:Hello, World!
创建配置文件lua.conf
server { listen 80; server_name localhost; location /lua { default_type text/html; content_by_lua_file conf/lua/hello.lua; } } 创建外部lua脚本 1.conf/lua/hello.lua 2.ngx.say("Hello, World!
") 3.重启/usr/servers/nginx/sbin/nginx -s reload
获取Nginx uri中的所有变量
local uri_args = ngx.req.get_uri_args() for k, v in pairs(uri_args) do if type(v) == "table" then ngx.say(k, " : ", table.concat(v, ", "), "
") else ngx.say(k, ": ", v, "
") end end http://192.168.244.181/lua1?a=test&b=ccc 结果: b: ccc a: test 其他功能: a.获取Nginx请求头信息 b.获取Nginx请求头信息 c.获取post请求参数 d.http协议版本 e.请求方法 f.原始的请求头内容 g.body内容体
OpenResty关联redis
get请求: location = /get { default_type text/html; redis2_pass 192.168.199.161:6379; redis2_query auth 123123; set_unescape_uri $key $arg_key; # this requires ngx_set_misc redis2_query get $key; } 测试:http://192.168.244.181/get?key=a +OK $6 xiaoke
页面单线程串行执行,比如拉取价格系统、商品系统、推荐系统、广告系统
优化: 并发执行,可以通过js、ajax异步去执行,拉取数据
页面application参数
localStore: 能存5M ,以域名为key,打开浏览器可以存在 session storage: 能存5M ,以域名为key,关掉浏览器打开就没了 cookies:只能存4K frame:可以存磁盘、存内存,第二次取从磁盘或者内存中取数据 via : 是哪台cdn服务器 是否缓存命中
拉取数据流程:
1.浏览器 -> server
2.server 生成etag=xxoo
3.浏览器二次请求 uri+etag=xxoo
4.server判断是否存在etag
5.server返回状态码
1.etag生成用算法 2.etag使用原始数据的最后修改时间
浏览器和server之间遵循的是http协议
etag请求 第一次状态200 以后就是304 是从tomcat中拿取的,有etag直接返回304状态
适合:1.大文件缓存 2.频繁更新的文件.3.后台可以在过滤器、拦截器中修改etag