技术实现很简单:

nginx分发请求的时候,upstream是由lua从redis中读取配置动态生成的。

装好nginx+lua,过程不表。 把lua redis的模块配到路径中

wget https://raw.github.com/nrk/redis-lua/version-2.0/src/redis.lua  

nginx配置如下:

server {  
  listen 80;
  server_name _;
  server_name_in_redirect off;
  port_in_redirect off;
  root /root/html;

  location / {
    set $upstream "";
    rewrite_by_lua '
      -- load global route cache into current request scope
      -- by default vars are not shared between requests
      local routes = _G.routes

      -- setup routes cache if empty
      if routes == nil then
        routes = {}
        ngx.log(ngx.ALERT, "Route cache is empty.")
      end

      -- try cached route first
      local route = routes[ngx.var.http_host]
      if route == nil then
        local redis  = require "redis"
        local client = redis.connect("localhost", 6379)
        route        = client:get(ngx.var.http_host)
      end

      -- fallback to redis for lookups
      if route ~= nil then
        ngx.var.upstream = route
        routes[ngx.var.http_host] = route
        _G.routes = routes
      else
        ngx.exit(ngx.HTTP_NOT_FOUND)
      end
    ';

    proxy_buffering             off;
    proxy_set_header            Host $host;
    proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect              off;
    proxy_connect_timeout       10;
    proxy_send_timeout          30;
    proxy_read_timeout          30;
    proxy_pass                  http://$upstream;
  }
}

送进redis一些数据

redis-cli =>  
SET localhost 127.0.0.1:49153  

测试一下:

curl -i -X HEAD "http://127.0.0.1/" # -> 404,没这个域名  
curl -i -X HEAD "http://localhost/" # -> 正常  
comments powered by Disqus