lua-resty-http icon indicating copy to clipboard operation
lua-resty-http copied to clipboard

high cpu usage when using lua-http-resty

Open hkmo opened this issue 9 years ago • 3 comments

I am using NGINX 1.9.13 with lua-resty-http. The CPU load is abnormally too hight when making HTTP requests via the lua http resty module ( https://github.com/liseen/lua-resty-http) :

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
8446 root   20   0  209m 142m 1748 R 99.1  3.7   0:31.27 nginx

The more the body of the request is big, the higher the CPU. In this case the body was 20MB. If we add multiple requests,

it will kill the CPU.

QUESTION: Is there a way to reduce the CPU load when using LUA http resty?

I added below the NGINX Lua code as well as the NGINX configuration: NGINX is used a front-end proxy towards an internal web server.

The below lua code (content.lua) is called multiple times from NGINX server for each curl http request :

local ok, code, headers, status, body = nil, 0, nil, 0, nil
local Http = require("resty.http") -- https://github.com/liseen/lua-resty-http
local Httpc = Http.new()
local req_headers = ngx.req.get_headers()    
req_headers["range"] = "bytes=0-20000000" -- example of range
req_headers["connection"] = "keep-alive"
req_headers["if-range"] = nil

local req_params = {
    url = "http://127.0.01:8099" .. ngx.var.request_uri,
    method = 'GET',
    headers = req_headers,
    keepalive = 30000 -- 30 seconds
}

req_params["code_callback"] =
   function(statuscode)
     code = statuscode
   end

req_params["header_callback"] =
   function(headers)
       if headers and headers["x-custom"] and ngx.re.match(headers ["x-custom"],"CUSTOM_STR") then
          --increment a counter 
       else
          --increment another counter
       end         
    end

req_params["body_callback"] =
    function(data, chunked_header, ...)
        if chunked_header or code ~= 206 then return end
        ngx.print(data)
        ngx.flush(true)
    end

ok, code, headers, status, body = Httpc:request(req_params)
local start, stop = 0, 20000000 -- example of value
if (code == 206) and body then
   ngx.print(string.sub(body, start, stop))
end

Below is my NGINX configuration:

worker_processes  auto;
events {
 worker_connections  2048;
 multi_accept on;
 use epoll;
}

http {
  include ./mime.types;
  default_type application/octet-stream;

  proxy_cache_bypass 1;
  proxy_no_cache 1;
  proxy_set_header Host $http_host;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_buffering off;
  proxy_buffer_size 128k;
  proxy_buffers 100 128k;
  sendfile on;
  tcp_nopush on;
  keepalive_timeout 10;
  reset_timedout_connection on;

  upstream backend {
    server 127.0.0.1:8090;
    keepalive 20;
  }

  server {
    listen 192.168.0.10:8080;

    location ~ \.(mp4|jpg)$ {  
      lua_check_client_abort on;
      lua_code_cache on;
      lua_http10_buffering off;

      #request the lua code  
      content_by_lua_file '/opt/location/content.lua';
    }
  }

  server {
    listen 127.0.0.1:8099;
    access_log off;        

    location / {
       proxy_pass http://backend;
    }
  }

}

hkmo avatar Apr 26 '16 17:04 hkmo

@hkmo I think you should really use streaming processing for large responses (or requests) of this size. This library does not support streaming processing AFAIK. Pick up one that does, like James Hurst's, for example.

agentzh avatar Apr 26 '16 18:04 agentzh

Thanks for your comment. The merit of lua-resty-http from liseen resides in its simplicity.Reading the body can also be streamed in chunks with a size that can be specified in the request (fetch_size). for each chunk, the library performs a socket receive. What do you mean by streaming processing? reading the body by chunks? I am going to try the one you mention above, but I am curious to understand the conceptual difference that have impact on CPU when streaming large responses. Thanks again.

hkmo avatar May 01 '16 22:05 hkmo

@hkmo I think we should profile the code before taking any actions to opitmizate things. See https://openresty.org/en/profiling.html

agentzh avatar May 03 '16 03:05 agentzh