1.Lua
1.1 在linux安裝lua
1.1.1 先安裝lua相關依賴庫的支援
yum install libtermcap-devel ncurses-devel libevent-devel readline-devel
1.1.2 再安裝
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar zxf lua-5.3.5.tar.gz
cd lua-5.3.5
make linux test
1.2 文法
1.2.1 互動式程式設計 Lua 互動式程式設計模式可以通過指令 lua -i 或 lua 來啟用,然後輸入指令直接輸出結果 print(“hello”);
1.2.2 腳本式程式設計
編輯檔案hello.lua vi hello.lua
在檔案中輸入 print(“hello”); 儲存并退出
執行指令 lua hello.lua 輸出:hello
1.3 變量
– 全局變量指派
a=1
– 局部變量指派
local b=2
1.4子產品
建立一個檔案叫module.lua
-- 檔案名為 module.lua
-- 定義一個名為 module 的子產品
module = {}
-- 定義一個常量
module.constant = "這是一個常量"
-- 定義一個函數
function module.func1()
print("這是一個公有函數")
end
local function func2()
print("這是一個私有函數!")
end
function module.func3()
func2()
end
return module
1.3.1:
require 函數
require 用于 引入其他的子產品,類似于java中的類要引用别的類的效果
1.3.2 引用
建立一個test_module.lua檔案
-- test_module.lua 檔案
-- module 子產品為上文提到到 module.lua
require("module")
print(module.constant)
module.func3()
輸出 lua test_module.lua
2.OpenResty介紹
2.1 安裝
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
2.2 安裝nginx
修改/usr/local/openresty/nginx/conf/nginx.conf,将配置檔案使用的根設定為root,目的就是将來要使用lua腳本的時候 ,直接可以加載在root下的lua腳本。
cd /usr/local/openresty/nginx/conf
vi nginx.conf
查詢資料放入redis中
a.連接配接mysql ,按照廣告分類ID讀取廣告清單,轉換為json字元串。
b.連接配接redis,将廣告清單json字元串存入redis 。
步驟
1.
移到 /root/lua目錄,在該目錄下建立update_content.lua: 目的就是連接配接mysql 查詢資料 并存儲到redis中。
先查詢openresty本地緩存 如果 沒有
再查詢redis中的資料,如果沒有
再查詢mysql中的資料,但凡有資料 則傳回即可。
ngx.header.content_type="application/json;charset=utf8"
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
--擷取本地緩存
local cache_ngx = ngx.shared.dis_cache;
--根據ID 擷取本地緩存資料
local contentCache = cache_ngx:get('content_cache_'..id);
if contentCache == "" or contentCache == nil then
local redis = require("resty.redis");
local red = redis:new()
red:set_timeout(2000)
red:connect("192.168.211.132", 6379)
local rescontent=red:get("content_"..id);
if ngx.null == rescontent then
local cjson = require("cjson");
local mysql = require("resty.mysql");
local db = mysql:new();
db:set_timeout(2000)
local props = {
host = "192.168.211.132",
port = 3306,
database = "changgou_content",
user = "root",
password = "123456"
}
local res = db:connect(props);
local select_sql = "select url,pic from tb_content where status ='1' and category_id="..id.." order by sort_order";
res = db:query(select_sql);
local responsejson = cjson.encode(res);
red:set("content_"..id,responsejson);
ngx.say(responsejson);
db:close()
else
cache_ngx:set('content_cache_'..id, rescontent, 10*60);
ngx.say(rescontent)
end
red:close()
else
ngx.say(contentCache)
end
測試位址:
http://192.168.211.132/update_content?id=1
此時會将分類ID=1的所有廣告查詢出來,并存入到Redis緩存。
測試位址:
http://192.168.211.132/read_content?id=1
此時會擷取分類ID=1的所有廣告資訊。
nginx的限流
nginx提供兩種限流的方式:
- 一是控制速率
- 二是控制并發連接配接數
1 控制速率
控制速率的方式之一就是采用漏桶算法。
(1)漏桶算法實作控制速率限流
漏桶(Leaky Bucket)算法思路很簡單,水(請求)先進入到漏桶裡,漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(通路頻率超過接口響應速率),然後就拒絕請求,可以看出漏桶算法能強行限制資料的傳輸速率.示意圖如下:
(2)nginx的配置
修改/usr/local/openresty/nginx/conf/nginx.conf:
user root root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#cache
lua_shared_dict dis_cache 128m;
#限流設定
limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
location /update_content {
content_by_lua_file /root/lua/update_content.lua;
}
location /read_content {
#使用限流配置
limit_req zone=contentRateLimit;
content_by_lua_file /root/lua/read_content.lua;
}
}
}
配置說明:
binary_remote_addr 是一種key,表示基于 remote_addr(用戶端IP) 來做限流,binary_ 的目的是壓縮記憶體占用量。
zone:定義共享記憶體區來存儲通路資訊, contentRateLimit:10m 表示一個大小為10M,名字為contentRateLimit的記憶體區域。1M能存儲16000 IP位址的通路資訊,10M可以存儲16W IP位址通路資訊。
rate 用于設定最大通路速率,rate=10r/s 表示每秒最多處理10個請求。Nginx 實際上以毫秒為粒度來跟蹤請求資訊,是以 10r/s 實際上是限制:每100毫秒處理一個請求。這意味着,自上一個請求處理完後,若後續100毫秒内又有請求到達,将拒絕處理該請求.我們這裡設定成2 友善測試。
測試:
重新加載配置檔案
cd /usr/local/openresty/nginx/sbin
./nginx -s reload
(3)處理突發流量
上面例子限制 2r/s,如果有時正常流量突然增大,超出的請求将被拒絕,無法處理突發流量,可以結合 burst 參數使用來解決該問題
burst 往往結合 nodelay 一起使用
完整代碼如下
user root root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#cache
lua_shared_dict dis_cache 128m;
#限流設定
limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
location /update_content {
content_by_lua_file /root/lua/update_content.lua;
}
location /read_content {
limit_req zone=contentRateLimit burst=4 nodelay;
content_by_lua_file /root/lua/read_content.lua;
}
}
}
平均每秒允許不超過2個請求,突發不超過4個請求,并且處理突發4個請求的時候,沒有延遲,等到完成之後,按照正常的速率處理。
控制并發量(連接配接數)
http {
include mime.types;
default_type application/octet-stream;
#cache
lua_shared_dict dis_cache 128m;
#限流設定
limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;
#根據IP位址來限制,存儲記憶體大小10M
limit_conn_zone $binary_remote_addr zone=addr:1m;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#所有以brand開始的請求,通路本地changgou-service-goods微服務
location /brand {
limit_conn addr 2;
proxy_pass http://192.168.211.1:18081;
}
location /update_content {
content_by_lua_file /root/lua/update_content.lua;
}
location /read_content {
limit_req zone=contentRateLimit burst=4 nodelay;
content_by_lua_file /root/lua/read_content.lua;
}
}
}
limit_conn_zone $binary_remote_addr zone=addr:10m; 表示限制根據使用者的IP位址來顯示,設定存儲位址為的記憶體大小10M
limit_conn addr 2; 表示 同一個位址隻允許連接配接2次。
canal同步
canal可以用來監控資料庫資料的變化,進而獲得新增資料,或者修改的資料
Canal工作原理
原理相對比較簡單:
- canal模拟mysql slave的互動協定,僞裝自己為mysql slave,向mysql master發送dump協定
- mysql master收到dump請求,開始推送binary log給slave(也就是canal)
- canal解析binary log對象(原始為byte流)