How do you learn a new language quickly? If you already know one language, you can think of all the others. A small demand, may encounter a lot of problems, but search related keywords, can quickly achieve it, complete a small goal, get twice the result with half the effort. Rote memorization of manual, too boring, anyway I can not read, it is better to direct a small project.

A small need

PC and Mobile Have two sets of pages in one address. You need to display different pages on the back end according to the user_Agent of the browser. Do it through PHP, of course, but the activity page view is generally relatively large, I want to optimize some, so I want to try Lua.

Nginx install lua – nginx – module

You can just go to OpenResty, but sometimes you just want to mess around. Installation steps mengkang.net/994.html (check it out if you want to practice)

Lua demo script

Function isMobile(userAgent) local mobile = {"phone", "android", "mobile", "itouch", "ipod", "symbian", "htc", "palmos", "blackberry", "opera mini", "windows ce", "nokia", "fennec", "hiptop", "kindle", "mot", "webos", "samsung", "sonyericsson", "wap", "avantgo", "eudoraweb", "minimo", "netfront", "teleca" } userAgent = string.lower(userAgent) for i, v in ipairs(mobile) do if string.match(userAgent, V) then return true end end return false end isMobile) local path = "/data/www/mengkang/demo/promotion/" local filename if isMobile then path = path .. "mobile" else path = path .. "pc" end filename = path .. "/".. id .. ".html" if file_exists(filename) then local file = io.open(filename,"r") io.input(file) print(io.read("*a")) IO. Close (file) else print(" File does not exist: ".. string.gsub(filename, "/data/www/mengkang/demo", Function file_exists(path) local file = IO. Open (path, "Rb ") if file then file:close() end return file ~= nil End local ID = 1 local userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 "showPromotionHtml(ID, isMobile(userAgent))Copy the code

summary

As a lua newbie, I looked it up with this little requirement

Variable definition function writing loop understanding judgment logic writing comment writing file I/O string concatenation.. Match string to lowercase string.lower

Slight tweaks for nginx Lua module

Function isMobile(userAgent) local mobile = {"phone", "android", "mobile", "itouch", "ipod", "symbian", "htc", "palmos", "blackberry", "opera mini", "windows ce", "nokia", "fennec", "hiptop", "kindle", "mot", "webos", "samsung", "sonyericsson", "wap", "avantgo", "eudoraweb", "minimo", "netfront", "teleca" } userAgent = string.lower(userAgent) for i, v in ipairs(mobile) do if string.match(userAgent, V) then return true end end return false end isMobile) local path = "/data/www/mengkang/demo/promotion/" local filename if isMobile then path = path .. "mobile" else path = path .. "pc" end filename = path .. "/".. id .. ".html" if file_exists(filename) then local file = io.open(filename,"r") io.input(file) ngx.say(io.read("*a")) io.close(file) else ngx.say("file not found : " .. string.gsub(filename, "/data/www/mengkang/demo", Function file_exists(path) local file = IO. Open (path, "rb") if file then file:close() end return file ~= nil end local id = ngx.var.id local userAgent = ngx.req.get_headers().user_agent showPromotionHtml(id, isMobile(userAgent))Copy the code

Nginx configuration

server { listen 80; server_name mengkang.net location ~ /promotion/(\d+) { set $id $1; default_type "text/html"; content_by_lua_file /data/www/lua/1.lua; }}Copy the code

Nginx can also install lua modules separately, or use OpenResty. For separate installation, see mengkang.net/994.html

Demo address

Mengkang.net/promotion/1 mengkang.net/promotion/1… Switch user_Agent to see the pages of different PC and mobile versions

Compare performance with PHP

Nginx configuration

rewrite ^/promotion2/(.*)$  /demo/promotion.php last;Copy the code

The PHP code

<? php header("Content-type:text/html; charset=utf-8"); header_remove('x-powered-by'); ini_set('display_errors', 'Off'); function getId(){ $uri = $_SERVER["REQUEST_URI"]; $tmp = explode("?" ,$uri); $uri = $tmp[0]; $uri = trim($uri,"/"); $tmp = explode("/",$uri); return intval(array_pop($tmp)); } function isMobile() { $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower ( $_SERVER['HTTP_USER_AGENT'] ) : ''; if ( preg_match ( "/phone|itouch|ipod|symbian|android|htc_|htc-|palmos|blackberry|opera mini|windows ce|nokia|fennec|hiptop|kindle|mot |mot-|webos\/|samsung|sonyericsson|mobile|pda; |avantgo|eudoraweb|minimo|netfront|nintendo/", $user_agent ) ) { return true; } return false; } $id = getId(); $isMobile = isMobile(); if ($isMobile){ $filename = __DIR__."/promotion/mobile/".$id.".html"; }else{ $filename = __DIR__."/promotion/pc/".$id.".html"; } if (file_exists($filename)) { echo file_get_contents($filename); }else{ echo "file not found : /promotion/pc/".$id.".html"; } exit;Copy the code

That is to say visit mengkang.net/promotion/1 and mengkang.net/promotion2/… It’s the same result

Configuration instructions

PHP version: 7.0.11 php-fPM configuration

pm = dynamic
pm.max_children = 10
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 10Copy the code

PHP pressure test results

Ab - n - 1000 - c 100 http://mengkang.net/promotion2/1 Requests per second: 3105.21 # / SEC (mean) Time per request: 32.204 [ms] (mean) ab - n - 4000 - c 400 http://mengkang.net/promotion2/1 Requests per second: 3361.87 [#/ SEC] (mean) Time per Request: 118.981 [MS] (mean) Complete requests: 4000 Failed requests: Ab 259 - n - 8000 - c 800 http://mengkang.net/promotion2/1 Requests per second: 3358.20 # / SEC (mean) Time per request: 238.223 [MS] (MEAN) Complete Requests: 8000 Failed requests: Ab 654 - n - 10000 - c 1000 http://mengkang.net/promotion2/1 Requests per second: 3275.30 # / SEC (mean) Time per request: 305.315 [MS] (mean) Complete Requests: 10000 Failed requests: 9150Copy the code

Lua pressure test results

Ab - n - 1000 - c 100 http://mengkang.net/promotion/1 Requests per second: 6014.89 # / SEC (mean) Time per request: 16.625 [ms] (mean) ab - n - 4000 - c 400 http://mengkang.net/promotion/1 Complete requests: 4000 Failed requests: 0 Requests per second: 6190.57 [#/ SEC] (mean) Time per request: 64.614 [ms] (mean) ab - n - 8000 - c 800 http://mengkang.net/promotion/1 Complete requests: 8000 Failed requests: 0 Requests per second: 7046.66 [#/ SEC] (mean) Time per request: 113.529 [ms] (mean ab - n - 10000 - c 1000 http://mengkang.net/promotion/1 Complete requests: 10000 Failed requests: 0 Requests per second: 5670.38 [#/ SEC] (MEAN) Time per request: 176.355 [ms] (mean)Copy the code

The comparison shows that the performance hints are quite impressive. PHP QPS is around 3000 and nginx_lua QPS is around 7000. PHP starts to see more failed requests at 400 concurrent requests, and throughput starts to decline. Lua results in 1000 concurrent requests, and the number of failed requests is still zero.