Dynamic Routing Based On Redis

Ngnix技术研究系列2-基于Redis实现动态路由

 

上篇博文我们写了个引子:

Ngnix技术研究系列1-通过应用场景看Nginx的反向代理

发现了新大陆,OpenResty

OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

回到我们的原始需求:

http://api.***.com/action    => http://192.168.0.11/api/action

Header: ***                            Header: ***

Body:   ***                             Body: ***    

通过Actiton获取对应的后端服务器地址

Action和服务器的对应关系(路由表)存储在Redis中.(实时更新实时获取)

根据请求的Action动态解析对应的内网服务器地址,再实现服务的转发。

Nginx原生的路由配置无法实现上述动态路由配置,因为我们要访问Redis,获取到反向代理的路由信息,再实现服务的转发。详细的实现步骤:

1. 解析URL中的Action

2.访问Redis,Key=Action Value=内网服务器地址

3.Http请求转发到内网服务器

明确了具体的实现方案后,我们需要先详细的研究一下OpenResty和Lua

http://openresty.org/cn/

https://www.tutorialspoint.com/lua/

大致了解OpenResty是什么,能做什么,同时能简单写一些Lua脚本。

然后,我们重点看OpenResty提供的样例:

Dynamic Routing Based On Redis

通过这个样例,我们就可以模仿着写一个我们自己的配置和脚本,实现上面的动态路由的需求。

Come On。

一、解析URL中的Action

首先,要解析并拆分URL字符串,各种百度和Google,需要写一段Lua代码,实现字符串按"/"拆分

其实就是定义了一个split_path函数。

然后我们将上面的Split.lua文件,配置到Nginx的配置文件中

/usr/local/openresty/nginx/conf/nginx.conf

注:split.lua文件我们放在了

/usr/local/openresty/nginx/lua

编辑/usr/local/openresty/nginx/conf/nginx.conf文件

http {
include mime.types;
default_type application/octet-stream; sendfile on;
#tcp_nopush on; #keepalive_timeout 0;
keepalive_timeout 65; #gzip on;
init_worker_by_lua_file /usr/local/openresty/nginx/lua/split.lua;
server {
listen 80;
location = /redis {
internal;
set_unescape_uri $key $arg_key;
redis2_query get $key;
redis2_pass RedisServer:6379;
} location / {
set $target '';
access_by_lua '
local parameters = split_path(ngx.var.uri)
local action = parameters[1]

location中的access_by_lua '这一段负责执行Lua脚本和方法
local action = parameters[1]

这样,我们便解析到了Action,注:Lua中数组的下标从1开始

二.访问Redis,Key=Action Value=内网服务器地址

继续编辑Nginx配置文件

 location / {
set $target '';
access_by_lua '
local parameters = split_path(ngx.var.uri)
local action = parameters[1]
if(#parameters == 0) then
ngx.exit(ngx.HTTP_FORBIDDEN)
end

local key = action
local res = ngx.location.capture(
"/redis", { args = { key = key } }
)if res.status ~= 200 then
ngx.log(ngx.ERR, "redis server returned bad status: ",
res.status)
ngx.exit(res.status)
end if not res.body then
ngx.log(ngx.ERR, "redis returned empty body")
ngx.exit(500)
end local parser = require "redis.parser"
local server, typ = parser.parse_reply(res.body)
if typ ~= parser.BULK_REPLY or not server then
ngx.log(ngx.ERR, "bad redis response: ", res.body)
ngx.exit(500)
end if server == "" then
server = "default.com"
end

三.Http请求转发到内网服务器

继续编辑Nginx.Conf文件

 init_worker_by_lua_file /usr/local/openresty/nginx/lua/split.lua;
server {
listen 80;
location = /redis {
internal;
set_unescape_uri $key $arg_key;
redis2_query get $key;
redis2_pass RedisServer:6379;
} location / {
set $target '';
access_by_lua '
local parameters = split_path(ngx.var.uri)
local action = parameters[1]
if(#parameters == 0) then
ngx.exit(ngx.HTTP_FORBIDDEN)
end local key = action
local res = ngx.location.capture(
"/redis", { args = { key = key } }
) if res.status ~= 200 then
ngx.log(ngx.ERR, "redis server returned bad status: ",
res.status)
ngx.exit(res.status)
end if not res.body then
ngx.log(ngx.ERR, "redis returned empty body")
ngx.exit(500)
end local parser = require "redis.parser"
local server, typ = parser.parse_reply(res.body)
if typ ~= parser.BULK_REPLY or not server then
ngx.log(ngx.ERR, "bad redis response: ", res.body)
ngx.exit(500)
end if server == "" then
server = "default.com"
end

server = server .. "/api/" .. action
if ngx.var.QUERY_STRING ~= nil and ngx.var.QUERY_STRING ~= "" then
server = server .."&"..ngx.var.QUERY_STRING
end ngx.var.target = server
';
resolver 8.8.8.8;
proxy_pass http://$target;
}
}

至此,我们完成了Nginx的配置文件。

启动Nginx测试:

sudo /usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/Nginx.conf

PostMan发起一次请求:

查看Nginx日志

以上就是使用Nginx+lua+redis实现动态路由。分享给大家

Dynamic Routing Based On Redis的更多相关文章

  1. Hinton's paper Dynamic Routing Between Capsules 的 Tensorflow , Keras ,Pytorch实现

    Tensorflow 实现 A Tensorflow implementation of CapsNet(Capsules Net) in Hinton's paper Dynamic Routing ...

  2. 【论文笔记】Dynamic Routing Between Capsules

    Dynamic Routing Between Capsules 2018-09-16 20:18:30 Paper:https://arxiv.org/pdf/1710.09829.pdf%20 P ...

  3. Dynamic Routing Between Capsules

    目录 概 主要内容 损失函数 代码 Sabour S, Frosst N, Hinton G E, et al. Dynamic Routing Between Capsules[C]. neural ...

  4. Redis Installation、Configuration、Program Based On Redis Learning

    目录 . Redis 简介 . Redis安装配置 . 编程使用Redis . 使用Lua脚本 1. Redis 简介 0x1: Redis是什么 Redis是一款Nosql类型的基于key-valu ...

  5. dynamic routing between captual

    对于人脑 决策树形式 对于CNN 层级与层级间的传递 人在识别物体的时候会进行坐标框架的设置 CNN无法识别,只能通过大量训练 胶囊 :一个神经元集合,有一个活动的向量,来表示物体的各类信息,向量的长 ...

  6. Paper | SkipNet: Learning Dynamic Routing in Convolutional Networks

    目录 1. 概括 2. 相关工作 3. 方法细节 门限模块的结构 训练方法 4. 总结 作者对residual network进行了改进:加入了gating network,基于上一层的激活值,得到一 ...

  7. Ngnix技术研究系列2-基于Redis实现动态路由

    上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...

  8. Nginx技术研究系列2-基于Redis实现动态路由

    上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...

  9. nginx HttpLuaModule

    http://wiki.nginx.org/HttpLuaModule#Directives Name ngx_lua - Embed the power of Lua into Nginx This ...

随机推荐

  1. UG/NX 8.0安装方法(图文详解)

    UG8.0,自从被西门子收购后改名为NX,也称NX8.0,作为一款非常优秀三维模具设计软件.他可以针对用户的虚拟产品设计和工艺设计的需求,提供经过实践验证的解决方案.其以全面的设计概念.良好的界面受到 ...

  2. usb-cam(1)安装

    http://www.liuxiao.org/2015/10/ros-%E5%AE%89%E8%A3%85-usb-camera-%E9%A9%B1%E5%8A%A8%E5%B9%B6%E8%B0%8 ...

  3. 20145236《网络对抗》Exp7 网络欺诈技术防范

    20145236<网络对抗>Exp7 网络欺诈技术防范 一.基础问题回答 通常在什么场景下容易受到DNS spoof攻击? 随便连接没有设置密码的wifi的情况下比较容易受攻击,因为这样就 ...

  4. 转 jeecg3.5中多数据源的配置

    官方微信有介绍通过web界面配置的方法:浅谈jeecg多数据源的使用,没试过不知道能不能用. 如果要手工配置也是可以的 在spring-mvc-hibernate.xml这个配置文件中增加一个数据源, ...

  5. 如何在一台机器上部署多个tomcat

    1,在/usr/local/下部署两个tomcat7. 2,修改/etc/profile文件,加入下面内容 vi  /etc/profile export JAVA_HOME=/usr/java/jd ...

  6. JS常见的小代码

    一:去掉数组里面的重复项. 比如 如下一个数组:var arr = [1,2,4,3,4,3]; 我想要得到数组 [1,2,4,3].为这样的 写一个函数去掉重复的项. var unique = fu ...

  7. 【第196期】Drupal7 Features模块与 Drupal8 Configuration Management 模块对比

    Drupal 8 最好和最受欢迎的部分之一是新的配置管理系统. 该系统使开发人员很容易将配置导出到代码中.在此之前,开发人员不得不依赖于由Features.Strongarm.UUID.Feature ...

  8. 利用shell脚本或者php移动某个文件夹下的文件到各自的日期组成的目录下

    背景是这样的:网站一开始访问量比较小,大家就把所有的图片文件上传到一个目录下(比如是/data/images/).后来访问量大了,图片也多了,这样就影响读取效率.所以有个这样的需求,把这些个图片文件移 ...

  9. springbootAdmin+eureka集群+swagger

    请移步githubb下载源码.知识共享.(https://github.com/yivvonllh) 或者直接git下载(https://github.com/yivvonllh/spring-clo ...

  10. python_第一章

    从今天开始,正式开始学习python书籍:python 编程:从入门到实践. 感兴趣的读者可以去网上搜索这本书,适合读者入门,读下来,不会有任何 晦涩难懂的知识. 1.排序: 正排:sort()    ...