Nginx-lua Dynamic location to upstream

2,938 views
Skip to first unread message

Simone

unread,
Mar 22, 2017, 2:08:06 PM3/22/17
to openresty-en
Hi there,
I've Just started to play with Lua and this is what I'd like to achieve:
I expose a location and a lua script Will inspect http args.Once It takes the args,It Will call an external api searching for a specific content and It Will writes the returned json values on some lua variables.
Based on the returned values,Nginx Will proxy_pass to the right upstream.
Does Nginx/luajit cache all json values/pages based on different calls?I don't really want to call an external api for every single location request...
Thanks a lot.

Martin Gee

unread,
May 10, 2017, 9:55:30 AM5/10/17
to openresty-en
You'll need your own cache.  https://github.com/sourcelair/ceryx  is a project that does a lot of what you're looking for. You can read the code to see how it's using ShareMemory as a cache for routes. 

Rob Kay

unread,
May 11, 2017, 12:26:42 AM5/11/17
to openresty-en
If you make the request to the external API using ngx.location.capture() via a proxy pass, you can configure the proxy pass to use nginx native caching. Something like:

http {
    proxy_cache_path /path/to/cache keys_zone=my_cache:100m;
}
upstream external_api {
    server external.api.com:443;
}

upstream backend1 {
    server 1.1.1.1:443;
}

upstream backend2 {
    server 2.2.2.2:443;
}

location / {
    set $chosen_backend '';
    set $reqeust_uri '';
    access_by_lua_block {
        local json = require 'cjson'
        local lua_request_uri = '/api/v1/searchterm' .. ngx.var.arg_searchterm
        api_response = ngx.location.capture('/external_api', {
            vars = {
                request_uri = lua_request_uri
            }
        })
        response_json = json.decode(api_response)
        if response_json['result'] then
            ngx.var.chosen_backend = 'backend1' 
        else
            ngx.var.chosen_backend = 'backend2'
        end
    }
    proxy_pass https://$chosen_backend;
}

location /external_api {
    internal;
    proxy_cache my_cache;
    proxy_cache_key $uri;
    proxy_cache_valid 200 5m;
}

David Birdsong

unread,
May 11, 2017, 1:10:46 AM5/11/17
to openresty-en
What are your route/upstream invalidation requirements?

If it's reasonable to fit in memory, just do the lookups in an access_by_lua* or rewrite_by_lua* block and cache the values in a lua module. If you can live w/ simply expiring out the info on a small interval, use the lua shared memory with whatever expiry is appropriate. 

...and then in increasing levels of sophistication:
https://github.com/pintsized/ledge

If you can't preset your upstream servers in the config, use balancer_by_lua to allow for your backends to be defined on the fly. Your code can access in data you've retrieved in the access_by or rewrite_by phases.



--
You received this message because you are subscribed to the Google Groups "openresty-en" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openresty-en+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages