The article is organized in bilibili Dark horse programmer’s video tutorial
Lua is introduced
What is Lua?
Lua [1] is a small scripting language. It was developed in 1993. It is designed to provide flexible extension and customization capabilities for applications through flexible embedding. Lua is written in standard C and can be compiled and run on almost any operating system and platform. Lua does not provide a powerful library because of its positioning. So Lua is not a good language for developing standalone applications. Lua has a concurrent JIT project that provides just-in-time compilation on a specific platform.
In a nutshell:
Lua is a lightweight scripting language written in standard C and open as source code. It is designed to be embedded in applications to provide flexible extension and customization capabilities.
The characteristics of the lua
- Support for procedure-oriented programming and functional programming;
- Automatic memory management; Only provides a general type of table (table), with it can achieve array, hash table, collection, object;
- Language built-in pattern matching; Closure (closure); A function can also be viewed as a value; Multithreading (collaborative processes, not threads supported by the operating system) support;
- Closures and tables make it easy to support some of the key mechanisms needed for object-oriented programming, such as data abstraction, virtual functions, inheritance, and overloading.
Application scenarios of Lua
- The game development
- Standalone application scripts
- Web Application Scripts
- Extensions and database plug-ins such as MySQL Proxy and MySQL WorkBench
- Security systems, such as intrusion detection systems
- Nested calls in Redis implement transaction-like functionality
- The web container applies logic that handles filtering caches and so on, such as Nginx.
The installation of the lua
There e are Linux and MAC versions installed. We use the Linux version of the installation, first we prepare a Linux virtual machine.
To install, run the following command on Linux.
Curl the -r -o http://www.lua.org/ftp/lua-5.3.5.tar.gz tar ZXF lua - 5.3.5. Tar. GzcdLua - 5.3.5 make Linuxtest
Copy the code
Note: The following errors may occur during installation:To install lua dependent libraries, run the following command:
yum install libtermcap-devel ncurses-devel libevent-devel readline-devel
Copy the code
Then run the Lua test to check whether Lua is successfully installed
[root@localhost ~]# luaCopyright (C) 1994-2008 Lua.org, PUC-RioCopy the code
Entry procedures
Create a hello.lua file with the content
Edit the file hello.lua
vi hello.lua
Copy the code
Type in the file:
print("hello");
print("hello lua!");
print("hello world!");
Copy the code
Save and exit.
Execute the command
lua hello.lua
Copy the code
The output is:
hello
hello lua!
hello world!
Copy the code
The effect is as follows:
Basic syntax of LUA
Lua has interactive programming and scripted programming. Interactive programming is simply typing in the syntax and executing it. Scripting requires writing scripts and then executing commands to execute the scripts. Scripting is generally used. (For example, create a hello.lua file, enter the contents of the file, and execute lua hell.lua)
(1) Interactive programming
Lua provides an interactive programming mode. We can type programs on the command line and see the results immediately.
Lua interactive programming mode can be enabled with the command Lua -i or Lua:
lua -i
Copy the code
The diagram below:
(2) Scripted programming
We can save Lua program code to a lua-ending file and execute it. This pattern is called scripted programming, such as writing Lua syntax to a hello. Lua file in the introductory program.
annotation
2. Two minus signs are single-line comments:
--
Copy the code
Multi-line comments:
--[[multiline comment --]]
Copy the code
Define variables
Global variables. By default, defining a variable is a global variable,
To use a local variable, declare it local. For example:
-- Global variable assignment
a=1
-- Local variable assignment
local b=2
Copy the code
If the variable is not initialized: its value is nil which is different from null in Java.
As shown below:
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.
The data type | describe |
---|---|
nil | This is the simplest; only the value nil belongs to this class, representing an invalid value (equivalent to false in conditional expressions). |
boolean | Contains two values: false and true. |
number | Represents a real floating-point number of type double precision |
string | A string is represented by a pair of double or single quotation marks |
function | A function written by C or Lua |
userdata | Represents any C data structure stored in a variable |
thread | Represents a separate line of execution for the execution of the coroutine |
table | Lua tables are associative Arrays whose indexes can be numeric, string, or table types. In Lua, a table is created using a “construct expression”. The simplest construct expression is {}, which creates an empty table. |
Example:
print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
Copy the code
Process control
(1) if statements
A Lua if statement consists of a Boolean expression as a condition, followed by other statements.
Grammar:
if(Boolean expression)then
--[statement executed when Boolean expression is true --]
end
Copy the code
Example:
(2) the if… Else statements
Lua if statements can be paired with else statements to execute an else statement block if the if conditional expression is false.
Grammar:
if(Boolean expression)then
--[execute block when Boolean expression is true --]
else
--[execute block when Boolean expression is false --]
end
Copy the code
Example:
cycle
Students complete
(1)while loop
The Lua programming language while loop repeats the body of the loop if the condition is true. Grammar:
while(condition)
do
statements
end
Copy the code
Example:
a=10
while( a < 20 )
do
print("The value of a is:, a)
a = a+1
end
Copy the code
The effect is as follows:
(2) the for loop
Lua programming language for loop statements can repeatedly execute specified statements, the number of repetitions can be controlled in the for statement.
Syntax: 1->10 1:exp1 10:exp2 2:exp3: incremental number
for var=exp1,exp2,exp3
do< executor >end
Copy the code
Var changes from exp1 to exp2. Each change increments var by exp3 and executes the body of execution once. Exp3 is optional. If not specified, it defaults to 1.
Example:
for i=1.9.2
do
print(i)
end
Copy the code
For I = 1,9,2
: I =1 starts the loop at 1, 9 loops the data to 9, and 2 increments by 2 each time
(3) repeat… Until statement [condition satisfied end]
Lua programming language repeat… Until loops differ from for and while loops, where the conditional statements are judged at the beginning of the current loop execution, whereas repeat… The condition statement of the until loop is judged after the end of the current loop.
Grammar:
repeat
statements
until( condition )
Copy the code
Case study:
function
Functions can also be defined in Lua, similar to methods in Java. Such as:
--[[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:
The maximum value of the comparison is 10 and the maximum value of the comparison is 6Copy the code
… : indicates splicing
table
Table is a Lua data structure that helps us create different data types, such as arrays, dictionaries, etc.
Lua also uses tables for modules, packages, and objects.
Case study:
Initialize the table
mytable = {}
- the specified value
mytable[1] ="Lua"
-- Remove reference
mytable = nil
Copy the code
The module
(1) Module definition
Modules are similar to an encapsulation library. Starting from Lua 5.1, Lua has added a standard module management mechanism, which can put some common code in a file and call it in the form of API interface in other places, which is beneficial to code reuse and reduce code coupling.
Create a file called module.lua and create a separate module in module.lua with the following code:
-- The file name is module.lua
-- Define a module named module
module = {}
Define a constant
module.constant = "This is a constant."
Define a function
function module.func1(a)
print("This is a public function")
end
local function func2(a)
print("This is a private function!")
end
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 operate on constants or functions in the module as if you were calling elements in the table.
Func2 above is declared as a local variable of the block, representing a private function. Therefore, the private function in the module cannot be accessed externally and must be called through the public function in the module.
(2) the require function
Require is used to introduce other modules, similar to Java classes that reference other classes.
Usage:
require("< module name >")
Copy the code
require "< module name >"
Copy the code
Either way.
We can import the module defined above and create a test_module.lua file as follows:
-- test_module. Lua files
-- module is the module mentioned above in module.lua
require("module")
print(module.constant)
module.func3()
Copy the code
OpenResty introduction
OpenResty(also called ngx_OpenResty) is a scalable Web platform based on NGINx, started by Chinese Zhang Yichun, which provides many high quality third-party modules.
OpenResty is a powerful Web application server that allows Web developers to leverage the various C and Lua modules supported by Nginx using the Lua scripting language, especially in terms of performance. OpenResty can quickly build ultra-high-performance Web applications capable of responding to more than 10K concurrent connections.
360, UPYUN, Aliyun, Sina, Qq.com, Qunar, And Kugou music are all deep users of OpenResty.
OpenResty simply encapsulates Nginx and integrates LUA scripts. Instead of writing LUA scripts in Nginx, developers simply need to provide modules to implement the logic.
Install openresty
Linux installation openresty:
1. Add the warehouse and run the command
yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
Copy the code
2. Perform the installation
yum install openresty
Copy the code
3. After the installation, the default directory is as follows:
/usr/local/openresty
Copy the code
Install nginx
Has been installed by default nginx in directory: / usr/local/openresty/nginx.
Modify/usr/local/openresty/nginx/conf/nginx. Conf, sets the configuration file using the root to root, the purpose is to use lua scripts in the future, can be loaded directly under the root of the lua script.
cd /usr/local/openresty/nginx/conf
vi nginx.conf
Copy the code
Modify the code as follows:
Test access
Restart the centos VIRTUAL machine and access the test Nginx
Visit address:http://server IP address /
Lua script instance: page AD cache loading and reading
Demand analysis
Need to display advertising information on the page.
Lua + Nginx configuration
(1) Implementation idea – query data into Redis
Implementation idea:
- Define request: Used to query data in the database for updates to Redis.
- A. Connect to mysql, read the advertisement list according to the advertisement category ID, and convert it to a JSON string.
- B. Connect to Redis and save the AD list JSON string to Redis.
Define the request:
Request: /update_content Parameter: id -- Specifies the ID of the AD category. Returned value: JSONCopy the code
Request address: < http://server IP address /update_content? id=1>
Create directory /root/lua and create update_content.lua ‘: connect to mysql to query data and store it in Redis.
Above code:
ngx.header.content_type="application/json; charset=utf8"
local cjson = require("cjson")
local mysql = require("resty.mysql")
local uri_args = ngx.req.get_uri_args()
local id = uri_args["id"]
local db = mysql:new()
db:set_timeout(1000)
local props = {
host = "8.131.64.45",
port = 3306,
database = "changgou_content",
user = "root",
password = "[email protected]"
}
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)
db:close(a)local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(2000)
local ip ="8.131.66.136"
local port = 6379
red:connect(ip,port)
red:auth("csp19990129")
red:select(0)
red:set("content_"..id,cjson.encode(res))
red:close()
ngx.say("{flag:true}")
Copy the code
Modify the/usr/local/openresty/nginx/conf/nginx.conf
File: Add header information and location information:
The code is as follows:
server {
listen 80; server_name localhost; User request /update_content? id=1Location /update_content {content_by_lua_file /root/lua/update_content.lua; }}Copy the code
Define the lua cache namespace, modify nginx.conf, add the following code:
The code is as follows:
# lua cache namespace lua_shared_dict dis_cache128m;
Copy the code
Browser test execution cache:
http://server IP/update_Content? Id =1
Go to the Redis client to test whether the cache is successful:
As shown, the data is obtained and the cache is successful!
(2) Implementation idea – obtain data from Redis
Implementation idea:
Define a request where the user gets a list of ads based on the ID of the AD category. Get the data directly from Redis using lua scripts.
Define the request:
Request :/read_content Parameter: id Returned value: JSONCopy the code
Create read_content.lua in /root/lua:
-- Sets the response header type
ngx.header.content_type="application/json; charset=utf8"
Gets the ID of the parameter in the request
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
-- Introducing the Redis library
local redis = require("resty.redis");
Create a Redis object
local red = redis:new()
-- Set the timeout period
red:set_timeout(2000)
- the connection
local ok, err = red:connect("Server IP".6379)
Get the value of key
local rescontent=red:get("content_"..id)
Output to the return response
ngx.say(rescontent)
-- Close the connection
red:close(a)Copy the code
in/usr/local/openresty/nginx/conf/nginx.conf
The configuration is as follows:
As shown in figure:
Code:
User request /read_content? id=1Location /read_content {content_by_lua_file /root/lua/read_content.lua; }Copy the code
(3) Join openResty local cache
There is no problem in the above way, but if all the requests go to Redis, redis will be under great pressure, so we generally adopt multi-level caching to reduce the service pressure of the downstream system. Refer to the implementation of the basic idea diagram.
- Query the OpenResty local cache first if not
- Query data in Redis, if no
- Mysql > select * from ‘mysql’;
Modify the read_content.lua file as follows:
The complete configuration is as follows:
ngx.header.content_type="application/json; charset=utf8"
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
Get the local cache
local cache_ngx = ngx.shared.dis_cache;
Get local cache data based on 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("8.xxx.xx.xx6".6379)
-- Password and selected bucket
red:auth("csxxxxx29")
red:select(0)
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 = "8.xxx.xx.x5",
port = 3306,
database = "changgou_content",
user = "root",
password = "CSPxxxxxx.com"
}
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(a)else
cache_ngx:set('content_cache_'..id, rescontent, 10*60);
ngx.say(rescontent)
end
red:close(a)else
ngx.say(contentCache)
end
Copy the code
The test address: http://192.168.211.132/update_content? id=1
All ads with category ID=1 will be queried and stored in Redis cache:
Test address:http://server IP/update_Content? Id =1
All ads with category ID=1 will be obtained: