“This is the 21st day of my participation in the First Wen Challenge 2022.First challenge in 2022”
Nginx advanced applications
Application Scenarios:
This technology is not just used for AD caching, it’s just a cache that is often used for advertising!
AD cache loading and reading
For an application to more, every day there will be a lot of users to visit, then the most visited is the home page! And for the home page, high access, andPage data is not constantly changing! To take the strain off the server, make it oneStatic page for display!
Basic process:
- Nginx has learned: can be implemented through the reverse proxy, gateway load balancing server! Users send requests, first through Nginx, through nginx proxy, load balancing, request corresponding gateway.. The module.
- This is in the user login/common operation, request after nginx request, in nginx complete call redis data operation, direct return results! But niginx doesn’t have that
Features of a programming language
If else, access database redis; It’s just a load balancer;So, you need to passLua embedded language
To complete the - First access to nginx, we can use caching, first from the nginx local cache, to get the direct response
- If not, access Redis again, we can retrieve data from Redis, return if there is, and cache it in nginx
- If not, go back to mysql and get the data from mysql and store it in Redis.
- We can use LUA scripts embedded in the program to perform these queries.
Lua
Brief introduction:
- Lua is a lightweight scripting language written in standard C and open source
C as the underlying language, writing things are fast!
It is designed to be embedded in applications to provide flexible extension and customization capabilities for applications.
features
-
Lightweight: the use of C language and open source code form, compiled only one hundred K, can be very convenient embedded in other programs.
-
Extensible: ** Lua provides very easy to use extension interfaces and mechanisms ** built in a large number of developed, script files mysql redis…. (usually C or C++) provide these features and Lua can use them as if they were already built in.
-
Other features: Support for procedure-oriented programming and functional programming automatic memory management; A table implementation that provides only a generic type of array, hash, collection, and object can easily support some of the key mechanisms required by object-oriented programming, such as data abstraction, virtual functions, inheritance, and overloading, through closures and tables
Application scenarios
Game development, standalone application scripts, Web application scripts, extensions and database plug-ins such as MySQL Proxy and MySQL WorkBench
The installation
Windows does not need to be installed, just need to configure the system environment variables: Environment variables are only for use in any other part of the system!
Path: D:\WSMwork\lua
(My installation path Lua53 or lua53 – I Can start Lua
An introduction to the Lua
Create the hello.lua file
Print:Print (" Print content!" );
- To create a file, enter
print("hello");
- Run CMD directly:
Execute command:Lua53 File name lua
Basic syntax of LUA
Introduction:
-
Lua has interactive programming and scripted programming:
-
Interactive programming is launching Lua
Enter the syntax directly, and you can execute it directly
. -
Scripting requires writing scripts and then executing commands to execute the scripts. Scripting is generally used. (For example, write a hello.lua file, enter the contents of the file, and execute lua53 hell.lua.)
-
The syntax is the same, just the way it works… Here’s the basic syntax of Lua!
Scripted programmingCreate.lua file and execute...
Note:
hello.lua
-- single-line comment --[[multi-line comment]]--Copy the code
Define variables
As in Java, there are global and local variables:
- Global whole file available!
- localCan be used within specified methods!
hello.lua
-- Global variable assignment
a=1
-- Local variable assignment
local b=2
-.. Joining together
print(a.. b)print(a..':'..b)
Copy the code
The a=’ triple ‘character can be represented by single or double quotation marks, utF-8 can be garble, recommend file encoding ANSl If the variable is not initialized: then its value is nil which is different from null in Java.
case
The numerical operation still passes + - * /
Data types in Lua
- Lua is a dynamically typed language. Variables do not need to be typed, only assigned values.
- Values can be stored in variables and passed as arguments or returned as a result.
- There are eight basic types in Lua:Nil, Boolean, number, String, userData, function, Thread, and table.
Type (value) The type of the returned value
print(type("Hello world")) --> string
print(type(10.4*3)) --> number contains double int
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
Copy the code
Process control
If statementOrcal-like stored procedures!
- The if statement consists of a Boolean expression as a condition, followed by other statements.
Conditional parentheses, optional: plus or minus
if(Boolean expression)then
--[statement executed when Boolean expression is true --]
end
Copy the code
if.. elseif… eles… End statement
- If statements can be paired with elseif statements, else statements, and else statement blocks are executed if the if condition expression is false.
If - else
If (Boolean expression)then --[Boolean expression true to execute the block --] else --[Boolean expression false to execute the block --] endCopy the code
If - esleif - elseif - else - end
local age =15
if (age>=18) then
print('Adult')
elseif age<18 then
print('minor')
else
print('unborn')
end
Copy the code
Testing:
cycle
The while loop [And then we loop] do …. end
- The while loop repeats the body of the loop when it judges that the condition is true.
while(conditionstrueExecute)do
print(' Execute loop content... ')end
Copy the code
The for loop
- A for loop can execute a specified statement repeatedly, with a number of repetitions controlled within the for statement.
for var=exp1,exp2,exp3 do
print(' Execute loop content... ')end
--[[var increments from exp1 to exp2 by exp3 and executes "body" once. Exp3 is optional. If not specified, default is 1.--
Copy the code
Repeat… Until the statement [Conditions met End]
- Repeat… Until loop statements are different from for and while loops
- Conditional statements for and while loops are judged at the start of the current loop execution
Repeat will be executed once anyway, okay
Until the condition is true
End the loop!
repeat
print(' Execute loop content... ')until( trueExit loop)Copy the code
function
- Functions can also be defined in Lua, similar to methods in Java.
--[[function returns the maximum value of two values --]]
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
Call function
print("The maximum value between the two values is.max(10.4))
print("The maximum value between the two values is.max(5.6))
Copy the code
Results after execution:
tabletable
- Table is a Lua data structure that helps us create different data types, such as arrays, dictionaries, objects, etc.
Alter table mytable = {}
Mytable [1]= "Lua"
-- Remove reference mytable = nil
Copy the code
Test the Demo
table= {}table[0] ="Zhang SAN 1"
table[1] ="Zhang SAN 2"
table[2] ="Zhang SAN 3"
-- Table is an object
print(table)
Get the value by subscript
print(table[0])
--table = nil to clear tables/objects
table = nui
print(table)
print(table[0])
Copy the code
The module
The module definition
- Since Lua 5.1, Lua has added a standard module management mechanism, which can put some common code in a file. Calling in the form of an API interface elsewhere facilitates code reuse and reduces code coupling.
Create a file calledmodule.lua
Don’t forget Chinese garble, file format set ASCII module.lua
-- The file name is module.lua
Define a module named module, the same as the file name!
module = {}
Define a constant
module.constant = "This is a constant."
Func1 -- Define a function module.func1
function module.func1(a)
print("This is a public function")
end
Define a local (private) method
Therefore, the private function in the module cannot be accessed externally. It must be called through the public function in the module
local function func2(a)
print("This is a private function!")
end
Simulate calling private methods...
function module.func3(a)
func2()
end
return module
Copy the code
- The structure of a module is the structure of a table,
- So you can manipulate constants or functions in the module as if you were calling elements in the table
The require function
Require is used to introduce other modules, similar to Java classes that reference other classes. The module to be imported should be placed in a folder, which can be a subfile! Otherwise we can’t find it!
require("< module name >")
- or
require "< module name >"
Copy the code
OpenResty
Introduction to the
- OpenResty® is a high-performance Web platform based on Nginx and Lua with a large number of excellent Lua libraries, third-party modules, and most of the dependencies internally integrated. It is used to easily build dynamic Web applications, Web services and dynamic gateways that can handle ultra-high concurrency and scalability.
- To put it simply: OpenResty is Niginx, and Niginx integrates Lua with programming features developed by the OpenResty team
The system configuration
Directory structure:
D: WSMwork openresty-1.15.8.2-win64 lualib resty contains a lot of luAThe module
Configuration:
Configuring the lua library location: modifiedOpenresty - 1.15.8.2 - win64 \ conf \ nginx. Conf
file
Most of the following operations are in: customConf file
lua.conf
Custom lua.conf
# Give nginx 128 MB cache size! Used to store hot data (frequently used data!)
lua_shared_dict my_cache 128m;
# nginx service
server {
listen 9090; # specify port 9090, default 80
server_name _;
# static template address set...
set $template_location "/templates";
set $template_root "D:/templates"; # Fill in the corresponding address...
#nginx stream request path...
location /mylua{
default_type text/html;
# pass content_by_lua_block{lua execution code} ngx.say(' is lua browser output method! ')
content_by_lua_block{
local age = 20
if age>=18 then
ngx.say('> = 18');
else
ngx.say('< 18');
end
}
}
}
Copy the code
- This is a normal nginx configuration code:
- content_by_lua_block{ }
The lua execution is written here
Nginx has the features of a programming language!OpenResty1.9.3.2 used to becontent_by_lua{ }throughnginx -v
Check the version number! - Ngx. say(‘ is lua’s browser output method! ‘)
Just like Java's Out print stream!
Start/refresh nginx
Start the command
OpenResty directorycmd
- nginx.exe
No exception is successful!
restartThe refresh
The command
When modifying files, frequent calls to nginx.exe are started, open to carry out causing congestion! The correct way is to refresh and restart CMD in the OpenResty directory
- nginx.exe -s reload
test
Bind () to 0.0.0.0:80 failed (10013: An attempt was made to access a……..)
The nginx.conf file also has a default port 80 boot.. May conflict with a port in the computer, direct change can!
Or: Stop the processWindows!
netstat -aon | findstr :80
80 indicates a port.Tasklist | findstr searches "process"
OpenResty imports lua files:
Writing lua code in nginx configuration is not easy to write, you can directly write outside, call it!
location /mylua2{
default_type text/html;
content_by_lua_file D:/WSMwork/myweb.lua;
}
#content_by_lua_file introduces the external lua file, ending with a semicolon;
Copy the code
content_by_lua_file
Import external.lua files
Define a file myweb.luaExternal file ~
Refresh the nginx
Initiate HTTP requests in openResty
- Some scenarios require Nginx to forward requests
This requires nginx to have the ability to make HTTP requests
- The Nginx service makes a distinction between internal and external HTTP requests
To facilitate testing, launch a micro suit to view
The lua script
myweb.lua
Set the encoding format!
ngx.header.content_type="text/html; charset=utf8"
Call a method in the NGX module that returns the request URL
local uri_args = ngx.req.get_uri_args()
Get request parameters!
local zz = uri_args["zz"]
-- get HTTP module, require();
local http = require("resty.http")
The HTTP module new() is an HTTPC object
local httpc = http.new()
-.. Splicing parameter WD
local resp = httpc:request_uri("http://127.0.0.1:9002/info/hello/"..zz,{
method = "GET".- get request;
keepalive=false -- Ask anyway;
})
Return parameter result, print result!
local val = resp.body
ngx.say(val)
Copy the code
test
Note that the arguments here are in nginx,Request parameters for port 9090!
require(“resty.http”)
It’s this Lua module that loads requests, There are a lot of lua scripting modules in OpenResty…
Gets the POST request parameters
Very similar to get….
ngx.req.read_body() Get the request URL
local arg = ngx.req.get_post_args() Parameter set Map type!
Declare several empty objects for storage
id=nil
deptname=nil
-- Loop parameter collection!
for k,v in pairs(arg) do
-- Judge parameter,key parameter assignment!
if k=="id" then
id = v
end
if k=="deptname" then
deptname = v
end
end
-- Page output!
ngx.say("deptname: ", deptname)
ngx.say("id: ", id)
Copy the code
Post requests using postman:
Openresty uses the Redis module
- Caching is often used in high-concurrency scenarios
- Now the distributed cache that we often use redis is the best known and we need to introduce the redis module require “resty.redis”
The lua script
myweb.lua
Define private methods
local function close_redis(red)
if not red then
return
end
Release the connection (connection pooling implementation) in milliseconds
local pool_max_idle_time = 10000
-- Connection pool size
local pool_size = 100
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
local log = ngx_log
if not ok then
log(ngx_ERR, "set redis keepalive error : ", err)
end
end
- connect the redis
local redis = require('resty.redis') -- Introducing modules
local red = redis.new()
red:set_timeout(1000)
local ip = "127.0.0.1"
local port = "6379"
-- local PWD = "ok"
Connection test IP port is correct...
ok, err = red:connect(ip,port)
if not ok then
ngx.say("failed to auth: ", err)
return close_redis(red)
end
-- Password is correct without direct comment!
--[[ ok, err = red:auth(pwd) if not ok then ngx.say("failed to auth: ", err) return close_redis(red) end ]]--
Get the first redis library,redis total 16 libraries
red:select('0')
red:set("msg"."test ngx hello") --set stores a MSG key with the value test NGX hello
-- get query by key... And handle exceptions
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
Print off resource!
ngx.say("msg : ", resp)
close_redis(red)
Copy the code
Remember to start Redis!
Installation directory: Redis-server.exe
View all keys
Testing:
Direct gateway request!
Operate mysql in openresty
The database
Since want database operation, so make a database!mysql
The lua script
myweb.lua
Create connection to mysql module
local mysql = require "resty.mysql"
-- connect to mysql;
local db, err = mysql:new()
if not db then
return false -- Not connected to close!
end
-- Timeout
db:set_timeout(1000)
-- Set the connection information
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1".--ip
port = 3306.- port
database = "book".-- Connected database
user = "root".- the user
password = "ok".- the password
max_packet_size = 1024 * 1024 -- 1 MB in size
}
Verify that the connection is up
if not ok then
ngx.say("connect mysql failed")
return false -- Not connected to close
end
if db == false then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
return
end
ngx.say("---------- Query data ----------------"."<br/>")
res, err, errcode, sqlstate =
db:query("SELECT * FROM bookinfo") In practice, the concatenation parameter.... may also be required
-- No data, return... Abnormal!
if not res then
ngx.say("bad result: ", err, ":", errcode, ":", sqlstate, ".")
return
end
Get the JSON module
local cjson = require "cjson"
--JSON translation, page output
ngx.say("result: ", cjson.encode(res))
-- If it is new...
--[[-- if no result is returned, add exception message! Ngx. say("insert rows :", res.affected_rows,", id", if not res then ngx.say("insert rows :", res.affected_rows,", ID ", res.insert_id, "
") ]]--
Copy the code
Results test:
Extension:
- It is recommended to use nginx to reference external LuaConvenient troubleshooting, if there is an error, direct console run lua script can! Clear structure…