nginx自定义模块编写-根据post参数路由到不同服务器

简介: nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,nginx默认的配置规则就捉襟见肘了,但是没关系,nginx提供了强大的自定义模块功能,我们只要进行需要的扩展就行了。

nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,nginx默认的配置规则就捉襟见肘了,但是没关系,nginx提供了强大的自定义模块功能,我们只要进行需要的扩展就行了。

我们来理一下思路,我们的需求是:

nginx根据http包体的参数,来选择合适的路由

在这之前,我们先来考虑另一个问题:

在nginx默认配置的支持下,能否实现服务器间的跳转呢?即类似于状态机,从一个服务器执行OK后,跳转到另一台服务器,按照规则依次传递下去。

答案是可以的,这也是我之前写bayonet之后,在nginx上特意尝试的功能。

一个示例的配置如下:

 

 

看明白了吧?我们使用了 433和434 这两个非标准http协议的返回码,所有请求进入时都默认进入 http://localhost:8888;,然后再根据返回码是 433 还是 434 来选择进入 http://localhost:6788 还是 http://localhost:6789。

OK,也许你已经猜到我将这个例子的用意了,是的,我们只要在我们的自定义模块中,根据http的包体返回不同的返回码,进而 proxy_pass 到不同的后端服务器即可。

好吧,接下来,我们正式进入nginx自定义模块的编写中来。

一. nginx 自定义模块编写
由于这也是我第一次写nginx模块,所以也是参考了非常多文档,我一一列在这里,所以详细的入门就不说了,只说比较不太一样的地方。
参考链接:

  1. nginx的helloworld模块的helloworld
  2. nginx 一个例子模块,简单的将http请求的内容返输出
  3. nginx 自定义协议 扩展模块开发
  4. Emiller的Nginx模块开发指南

而我们这个模块一个最大的特点就是,需要等包体整个接收完才能进行处理,所以有如下代码:

 

我们注册了一个回调函数 ngx_http_foo_post_handler,当包体全部接受完成时就会调用。之后我们调用了get_route_id来获取返回码,然后通过 ngx_http_finalize_request(r, result); 来告诉nginx处理的结果。

这里有个小插曲,即get_route_id。我们来看一下它定义的原型:

第一个参数是 ngx_log_t *log,是为了方便在报错的时候打印日志。然而在最开始的时候,get_route_id 的原型是这样:

结果在 get_route_id 函数内部,调用

的结果总是null,至今也不知道为什么。(知道了是lua头文件和ngx头文件顺序的问题,把ngx头文件放到最前面即可)

OK,接下来我们只要在get_route_id中增加逻辑代码,读几行配置,判断一下就可以了~ 但是,我想要的远不止如此。

二.lua解析器的加入
老博友应该都看过我之前写的一篇博客: 代码即数据,数据即代码(1)-把难以变更的代码变成易于变更的数据,而这一次的需求也非常符合使用脚本的原则:

只需要告诉我返回nginx哪个返回码,具体怎么算出来的,再复杂,再多变,都放到脚本里面去。

所以接下来我又写了c调用lua的代码:

 

比较郁闷的是,lua 5.2的很多函数都变了,比如lua_open废弃,变成luaL_newstate等,不过总体来说还算没浪费太多时间。

接下来是req_route.lua的内容,我只截取入口函数如下:

 

OK,结合了lua解析器之后,无论多复杂的调整,我们都基本可以做到只修改lua脚本而不需要重新修改、编译nginx模块代码了。

接下来,就该是体验我们的成果了。
三.nginx配置

 

OK,enjoy it!

最后,放出代码如下:
https://vimercode.googlecode.com/svn/trunk/nginx_req_route


用perl or lua的版本如下
http://www.php-oa.com/2010/09/25/perl-perl-nginx.html
https://github.com/chaoslawful/lua-nginx-module

目录
相关文章
|
1月前
|
存储 弹性计算 网络协议
阿里云服务器ECS自定义购买流程:亲测图文全解析
本文详细图解阿里云ECS自定义购买全流程,涵盖付费模式、地域选择、实例规格、镜像、存储、网络、安全组及登录设置等核心配置,助您轻松掌握专业级云服务器搭建方法。
118 0
|
3月前
|
缓存 负载均衡 JavaScript
Nginx:高性能Web服务器与反向代理利器
Nginx:高性能Web服务器与反向代理利器
259 110
|
3月前
|
负载均衡 Cloud Native 前端开发
Nginx:高性能的Web服务器与反向代理利器
Nginx:高性能的Web服务器与反向代理利器
191 100
|
3月前
|
缓存 负载均衡 前端开发
Nginx:高性能Web服务器的核心力量
Nginx:高性能Web服务器的核心力量
211 100
|
3月前
|
缓存 负载均衡 前端开发
Nginx:高性能的Web服务器与反向代理利器
Nginx:高性能的Web服务器与反向代理利器
225 99
|
3月前
|
负载均衡 前端开发 安全
Nginx:高性能的Web服务器与反向代理利器
Nginx:高性能的Web服务器与反向代理利器
217 98
|
3月前
|
缓存 负载均衡 前端开发
Nginx:高性能Web服务器的核心引擎
Nginx:高性能Web服务器的核心引擎
213 99
|
30天前
|
弹性计算 网络协议 Linux
阿里云服务器简介及使用教程,附送云服务器ECS自定义创建流程
阿里云ECS是安全可靠、弹性灵活的云计算服务,支持多种实例规格与操作系统,可快速创建和管理云服务器。本文详解ECS介绍、购买流程及使用教程,涵盖配置选择、网络设置、安全组规则等,助您轻松上手。
306 16
|
27天前
|
存储 弹性计算 网络协议
超详细的阿里云服务器购买流程,ECS自定义购买配置教程
本文详细图解阿里云ECS服务器自定义购买全流程,涵盖付费模式、地域选择、网络配置、实例规格、镜像、存储、安全组及登录设置等核心步骤,助您轻松掌握专业级云服务器搭建方法。