SpringCloud商城day05 网站首页广告高可用 - 2021-10-10

一. Lua语言

1. C编写脚本语言

2. 作用: 灵活嵌入应用 -> 扩展和定制功能

3. 不提供库, 不适合作为开发独立应用的语言

4. 即时编译: JIT项目

5. 特点:
    (1) 面向过程 procedure-oriented
    (2) 函数式编程 functional-programming
    (3) 自动内存管理: 通用类型的表table -> 实现数组, 哈希表, 集合, 对象
    (4) 语言内置模式匹配
    (5) 闭包
    (6) 函数也可以看做是一个值
    (7) 多线程 -> 协同线程
    (8) 闭包和table -> 支持数据抽象, 虚函数, 继承和重载

6.应用场景:
    (1) 游戏开发
    (2) 独立应用脚本
    (3) Web应用脚本
    (4) 扩展和数据库插件: MySQL Proxy
    (5) 安全系统: 入侵检测系统
    (6) Redis嵌套调用实现类似事务的功能
    (7) Web容器中应用处理 过滤, 缓存逻辑

7. 安装步骤:
    (1) yum install -y gcc
    (2) yum install libetermcap-devel ncurses-devel libevent-devel readline-devel
    (3) curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
    (4) tar -zxf lua-5.3.5.tar.gz
    (5) cd lua-5.3.5
    (6) make linux test
    (7) make install
8. lua基本语法:
        (1)交互式编程: 直接输入语法执行
        (2) 脚本式编程: 编写脚本文件, 再执行
        (3) 注释:
                1) 单行注释: --
                2) 多行注释: --[[]]--
        (4) 关键字:
                1) nil  ->  声明变量值无效
                2) and / break / do / else / elseif / end / false / for / function / if / in / local / not / or / repeat / return / then / true / until / while

        (5) 变量:
                1) 全局变量: a=1
                2) 局部变量: local b=2
                3) 动态类型 -> 不用定义变量类型
                4) nil -> 无效值
                5) boolean -> true/false
                6) number -> 双精度类型的实浮点数
                7) string -> 由 '' 或 "" 表示
                8) function -> 函数
                9) userdata -> 储存在变量中的C数据结构
                10) thread -> 独立线路, 执行协同程序
                11) table -> 表 -> 关联数组associatIve array -> index=number/string/table

        (6) 流程控制:

                1) if(o) then
                    print('0为true')
                    else
                    print('o不为true')
                    end
        (7) 函数:
                --定义函数比较两个值的大小
                function max(num1, bum2)
                  if(num1>num2) then
                    result=num1;
                  else
                    result=num2;
                  end
                  return result;
                  end
                --调用函数
                print(max(10,5));

       (8) require函数: //引入其他模块
            require "<模块名>"

二. NGinx+Lua+Redis实现广告缓存[部署在Linux虚拟机上]

1. nginx: 高性能http服务器, 5万并发

2.Tomcat集群超过5台服务器后, 性能不升反降

3. nginx功能:
    (1) 负载均衡器load balance: 接收请求 -> 分发 -> Tomcat集群
    (2) 反向代理:   客户端请求nginx服务器 -> nginx根据请求的url地址判断 -> 去访问代理的目标服务器
    (3) HTTP服务器: 存放静态资源(html, css, js, img) -> 放在nginx/html目录下

4. Openresty

(1) 含义: ngx_openresty. 基于NGinx的web平台

(2) Openresty = NGinx+Lua

(3) 作用: 
    1) 支持Lua模块
    2) 调动NGinx支持的C模块
    3) web服务器跑在nginx服务器内部
    4) 1万-100万的并发

(4) Linux安装Openresty:
    1) 执行仓库命令:
        yum install yum-utils
        yum-config-manager --add--repo
        https://openresty.org/package/centos/openresty.repo
    2) 执行安装:
        yum install openresty
    3) 默认安装目录:
        /usr/local/openresty
    4) 默认携带nginx: 
        目录 /usr/local/openresty/nginx
    5) 修改nginx.conf配置文件: /usr/local/openresty/nginx/conf/nginx.conf
        #配置文件第一行改为
        user root root   //执行nginx时, 会加载根目录root下的Lua脚本
            
        #在80端口的server中 添加访问的lua文件
        location/ad_update{
            content_by_lua_file /root/lua/ad_update.lua;  #基于content属性加载lua文件
        }    
        
        
        location/ad_read{
            content_by_lua_file /root/lua/ad_read.lua;
        }
        

 5. 实现加载广告数据:

1. tb_ad表: position字段 -> 区分广告位置

2. 实现步骤:
    (1) 缓存预热: Lua预加载广告数据 -> 从MySQL取出数据 -> 存入Redis
        1) 基于Lua连接MySQL:
            a. 查询广告分类id -> 读取广告列表 -> 转换json字符串
            b. 创建 ad_update.lua
                nginx.header.content_type="application/json;charset=utf8"  #传递json数据
                local cjson = require("cjson")      #引入json支持
                local mysql = require("resty.mysql")  #引入mysql支持
                local uri_args = ngx.req.get_uri_args()  #获取请求路径的参数 赋值给局部变量
                local position = uri_args["position"]    #获取请求参数的特定字段 "position"
                
                local db = mysql:new()  #开启mysql的新连接
                db:set_timeout(1000)    #设置数据库连接超时时间
                local_props = {
                    host = "192.168.200.128",
                    port = 3306,
                    database = "changgou_business",
                    user = "root",
                    password = "root"
                }

                local res = db:connect(props)   #基于四大参数连接mysql
                local select_sql = "select url, image from tb_ad status ='1' and position='"..position.."' and start_time<=NOW() AND end_time>=NOW()"
                res = db:query(select_sql)   #传递执行的SQL语句
                db:close()    #关闭连接池 

                local redis = require("resty_redis")   #引入redis模块
                local red = redis:new()               #开启redis连接
                red:set_timeout(2000)      #设置redis连接超时时间
                local ip = "192.168.200.128"   #设置连接ip地址
                local port = 6379              #redis端口号
                red:connect(ip, port)          #连接redis

                res:set("ad_"..position, cjson.encode(res))    #设置存入redis的内容
                res:close()                    #关闭redis连接     
                
                ngx.say("{flag:true}")   #返回信息

            c. 重启测试: systemctl restart openresty
                    或:  cd nginx/sbin -> ./nginx -s reload

        2) 基于Luq连接Redis: 
            a. 创建 ad_read.lua文件
                ngx.header.content_type="application/json;charset=utf8
                local uri_args = ngx.req.get_uri_qrgs();
                local position = uri_args["position"];
                local redis = require("resty.redis");
                local red = redis:new()
                red:set_timeout(2000)
                local ok, err = red:connect("192.168.200.128", 6379)
                local rescontent = red:get("ad_"..position)  #查询redis的广告数据存入变量
                nginx.say(rescontent)     #输出变量
                red:close()
                
    (2) 二级缓存查询: 客户端查询 -> 先查询openresty本地缓存 -> 无则查询Redis -> 再存入本地缓存
        -> 再返回到客户端
        1) 修改ad_read.lua: 
            ngx.header.content_type="application/json;charset=utf8
            local uri_args = ngx.req.get_uri_qrgs();
            local position = uri_args["position"];
            local cache_ngx = ngx.shared.dis_cache;   #开启本地缓存
            local adCache = cache_ngx:get('ad_cache_'..position);   #在本地缓存中查询数据
            if(adCache==""or addCache==nil then    #判断当前结果为空或无效
                local redis = require("resty.redis");
                local red = redis:new()
                red:set_timeout(2000)
                local ok, err = red:connect("192.168.200.128", 6379)
                local rescontent = red:get("ad_"..position)
                nginx.say(rescontent) 
                red:close()
                
                cache_ngx:set('ad_cache_'..postition, rescontent, 10*60); #存入本地缓存
            else
                ngx.say(addCache)
            end
    (3) 修改nginx.conf:  
        添加: lua_shared_dict dis_cache 5m;   #共享内存开启, 包含redis初始化模块


    (4) 上传静态资源到nginx -> 本地缓存需加载: 
        1) 使用MobaXterm 
        2) 保存到 usr/local/openresty/nginx/html

三. NGinx限流

1. 使用场景: 首页并发量大, 避免宕机  -> nginx控制速率和并发连接数

2. 网关令牌桶算法 -> 控制填充令牌 -> 访问消耗令牌 -> 够则访问 -> 不够则拒绝

3. nginx控制速率: 漏桶算法 -> 请求流入桶中 -> 控制请求流出桶的速率 -> 大于接口响应速率时拒绝

4. 令牌桶控制令牌进入的速度, 漏桶控制访问流出的速度

5.实现: 添加配置到nginx.conf

#在nginx.conf中添加以下配置
#声明进行限流控制 -> zone代表桶的大小1MB=16000个IP地址 -> rate每秒访问2次 即每500毫秒处理一个请求
limit_req_zone $binary_remote_addr zone=myRateLimit: 10m rate=2r/s
server{
    listen       8081;
    server_name  localhost;
    charset utf-8;
    location / {
        limit_req zone=myRateLimit;  #把上面的配置放入属性中
        root   html;
        index  index.html index.htm;
    }
}

6. 处理突发流量:

        (1). 场景: 正常流量 -> 突然增大 -> 请求被拒绝

        (2) 添加 burst属性:  

limit_req zone=myRateLimit burst=5;  #添加burst属性, 正常访问速率外可以额外处理5个

        (3) 6个请求同时到达 -> 先处理1个 -> 剩下5个放入队列 -> 每500ms取出1个;

        (4) 请求数>6个, 则直接返回503

        (5) 添加 nodelay属性: 不会每500毫秒处理突发的请求, 而是无延迟处理

limit_req zone=myRateLimit burst=5 nodelay;   #添加nodelay属性, 无延迟处理突发流量

7. 每次修改配置后记得重启nginx:

       systemctl restart openresty
       或:  cd nginx/sbin -> ./nginx -s reload

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值