OpenResty 反向代理的用法与技巧

摘要:
设置上游_A此位置的流量被切换到上游地址192.168.1.120,而无需更改配置或重新启动Nginx服务,location/internet_prxoy{internal;

Nginx最开始是作为反向代理被熟知的,基于它的OpenResty的自然也是支持反向代理的,下面我们就来看看它的一些基本用法以及在使用过程中的一些技巧。

一、基本用法


在业务环境中,可能会将OpenResty(以后简称OR)作为反向代理,根据不同的location定位到不同的后端,在这样的架构下,对应的反向代理配置可能是这样的:

location /upstream_A {
    proxy_pass http://192.168.1.100:8080;
    proxy_connect_timeout 2s;
    ...
}
location /upstream_B {
    proxy_pass http://192.168.1.110:8080;
    proxy_connect_timeout 2s;
    ...
}

可以看到这部分的配置和Nginx并没有太大差别,但是这样的配置会有一些问题,比如我们需要切换后端服务器,将upstream_A这个location的流量打到192.168.1.120这个上游地址而不用修改配置或者重启Nginx服务,大部分人可能会选择通过域名的方式去定位上游比如用如下配置:

location /upstream_A {
    proxy_pass http://domain_for_upstream_A:8080;
    proxy_connect_timeout 2s;
    ...
}
location /upstream_B {
    proxy_pass http://domain_for_upstream_B:8080;
    proxy_connect_timeout 2s;
    ...
}

当需要做_上游切换_的时候,通过修改 /etc/host 文件来将域名定向到新的Ip,但不幸的是,Ngixn并不会使用/etc/host 而是使用命令resolver来指定DNS服务器,那么在OR里面有没有一些高阶的用法可以让上游漂移变得简单呢?答案是肯定的,下面就来看看更加方便的用法,以及里面的坑。

二、进阶用法


上面呢我们讲到如何使用OR(其实就用到了Nginx的配置啦)来完成反向代理,但是由于Ip或者域名写死,而Nginx又不支持host,所以在做上游平滑迁移的时候不是很方便,所以我们可以通过在上游配置中用Nginx变量来代替上游的地址,变可以避免上述问题。

location /internet_prxoy {
    internal;
    set_by_lua $query_url 'return ngx.unescape_uri(ngx.var.arg_url);'    proxy_pass $query_url;    
}
location /upstream_A {
    content_by_lua '
        local redis_op   = require "lua.redis_op"
        local upstream_addr = redis_op.get_upstream_from_redis() -- 从redis中获取上游地址
        local url  = 'http://'..  upstream_addr .. '/foo/bar'
        local res = ngx.location.capture('/internet_proxy',
            { args = {url = url}}
           )
           --容错判断
        ngx.print(res.body)
    ';
}

这样,当请求访问到/upstream_A的时候,会在redis当中读取到上游服务器的真实地址并通过/internet_prxoy转发到上游。

看到这里有人可能会问,为什么需要配置一个额外的跳转location,而不直接在set_by_lua阶段访问redis并对Nginx变量进行赋值?

原因是函数get_upstream_from_redis会涉及到redis的访问,而lua-resty-redis使用了ngx.socket.tcp这个函数,这个函数所支持的执行阶段不包括_set_阶段,需要我们需要一次跳转,通过第一次location的content阶段从redis中将数据读取出来,在第二个location的set阶段利用刚才所读取的数据完成反向代理。

需要注意的是如果第一次location,(也就是上述代码中的/upstream_A)的流量非常高,那么可以在redis的访问函数,也就是上述代码中的get_upstream_from_redis()函数中用shared.dict来做一次缓存,减少对redis的访问量也是可行的。

免责声明:文章转载自《OpenResty 反向代理的用法与技巧》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDBc# 免注册调用大漠插件100%完美识别文字下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

安装XMind出现Invalid Configuration Location The configuration area at

Invalid Configuration Location ,The configuration area at 'C:UsersAdministratorApplicationDataXMindconfiguration-cathy_win32'cound not be created.Please choose a writable location...

OCR数据合成工具Text Recognition Data Generator的help文档翻译

   -h, --help            show this help message and exit      --output_dir [OUTPUT_DIR]  The output directory      -i [INPUT_FILE], --input_file [INPUT_FILE]  When set, this argum...

pcap文件格式及文件解析

第一部分:PCAP包文件格式 一 基本格式:    文件头 数据包头数据报数据包头数据报...... 二、文件头:        文件头结构体 sturct pcap_file_header {      DWORD           magic;      DWORD           version_major;      DWORD       ...

STM32L15XXX 入门笔记

一、系统时钟默认是32M,最高支持32M,不过下图已经改成72M也可以运行,可能会有什么后遗症,位置在 二、定时器1ms两种方法1、Main.c里 void delay_nms(uint32_t time){ uint32_t i=0; while(time--) { i=12000; //自己定义 while(i--) ; }} 这种方式多少有点...

Android开机logo修改方法 【转】

本文转载自:http://blog.csdn.net/qq258711519/article/details/7766303 一体机平台开机logo修改方法 1:修改Kernel中的Logo:        若是要替换Kernel中的开机Logo,只需要把内核目录drivers/video/logo下的logo_android_1024_clut224.p...

js设置当前窗口为最上层窗口

实际使用iframe框架时会遇到当前窗口页面不能位于最上层窗口的情况,或者是防止自己的网站被别人放在他们的iframe中,这时就需要设置:   <script language="javascript" type="text/javascript"> if (window.top != null && windo...