In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article is to share with you about the example analysis of routing to different servers according to the post parameters in the Nginx custom module. The editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.
Nginx can easily be forwarded to different servers according to different url or get parameters. However, when we need to route requests according to http packets, the default configuration rules of Nginx are too tight, but it doesn't matter. Nginx provides powerful custom module features, we just need to expand as needed.
Let's get this straight. Our needs are:
Nginx selects the appropriate route according to the parameters of the http packet.
Before we do that, let's consider another question:
Is it possible to jump between servers with the support of the default configuration of Nginx? That is, similar to a state machine, after OK is executed from one server, it jumps to another server and passes it down in turn according to the rules.
The answer is yes, which is a feature I specifically tried on nginx after I wrote bayonet.
The configuration of an example is as follows:
Server {listen 8080; server_name localhost; location / {proxy_pass http://localhost:8888; error_page 433 = @ 433; error_page 434 = @ 434;} location @ 433 {proxy_pass http://localhost:6788;} location @ 434 {proxy_pass http://localhost:6789;} error_page 502 503 504 / 50x.html Location = / 50x.html {root html;}}
Do you understand? We use the return codes of two non-standard http protocols: 433 and 434. All requests enter http://localhost:8888; by default, and then choose whether to enter http://localhost:6788 or http://localhost:6789 according to whether the return code is 433 or 434.
OK, you may have guessed the purpose of this example, yes, we just need to return different return codes according to the packet body of http in our custom module, and then proxy_pass to different back-end servers.
All right, next, let's officially get into writing the nginx custom module.
one。 Nginx custom module writing because this is also my * times to write the nginx module, so I also refer to a lot of documents, I listed here one by one, so the detailed introduction will not be said, only to compare the different places. Reference link:
Helloworld of the helloworld module of nginx
Nginx is an example module that simply returns the content of the http request to output.
Development of nginx Custom Protocol extension Module
Emiller's Nginx module development guide
A * * feature of our module is that we need to wait for the whole packet to be received before it can be processed, so there is the following code:
Void ngx_http_foo_post_handler (ngx_http_request_t * r) {/ / request is entered from here after all the requests have been read, and the response ngx_http_request_body_t* rrb = r-> request_body; char* body = NULL; int body_size = 0 can be generated; if (rb & & rb- > buf) {body = (char*) rb- > buf- > pos Body_size = rb- > buf- > last-rb- > buf- > pos } int result = get_route_id (r-> connection- > log, (int) r-> method, (char*) r-> uri.data, (char*) r-> args.data, body Body_size) If (result
< 0) { ngx_log_error(NGX_LOG_ERR, r->Connection- > log, 0, "get_route_id fail, result:%d", result); result = DFT_ROUTE_ID;} ngx_http_finalize_request (r, result);} static ngx_int_t ngx_http_req_route_handler (ngx_http_request_t * r) {ngx_http_read_client_request_body (r, ngx_http_foo_post_handler); return NGX_DONE; / / main handler end}
We have registered a callback function ngx_http_foo_post_handler, which will be called when the packet is fully accepted. Then we call get_route_id to get the return code, and then tell nginx the result of the processing through ngx_http_finalize_request (r, result);.
Here's a little episode, get_route_id. Let's take a look at the prototype it defines:
Extern int get_route_id (ngx_log_t * log, int method, char* uri, char* args, char* body, int body_size)
The * parameter is ngx_log_t * log, which makes it easy to print logs when an error is reported. In the beginning, however, the prototype of get_route_id was like this:
Extern int get_route_id (ngx_http_request_t * r, int method, char* uri, char* args, char* body, int body_size)
The result is inside the get_route_id function, calling:
R-> connection- > log
The result is always null, and I still don't know why.
OK, next we just need to add logic code to get_route_id, read a few lines of configuration, and judge ~ but I want a lot more than that.
Second, the addition of lua parser
Old bloggers should have read a blog I wrote before: code is data, data is code (1)-turning hard-to-change code into easy-to-change data, and this time the requirements are very consistent with the principle of using scripts:
Just tell me which return code to return nginx, how to figure it out, no matter how complicated, no matter how changeable, put it in the script.
So then I wrote the code for c to call lua:
Int get_route_id (ngx_log_t * log, int method, char* uri, char* args, char* body, int body_size) {const char lua_funcname [] = "get_route_id"; lua_State * L = luaL_newstate (); luaL_openlibs (L) If (luaL_loadfile (L, LUA_FILENAME) | | lua_pcall (L, 0, 0)) {ngx_log_error (NGX_LOG_ERR, log, 0, "cannot run configuration file:% s", lua_tostring (L,-1)); lua_close (L); return-1;} lua_getglobal (L, lua_funcname) / * function to be called * / lua_pushnumber (L, method); lua_pushstring (L, uri); lua_pushstring (L, args); lua_pushlstring (L, body, body_size) / * do the call (1 arguments, 1 result) * / if (lua_pcall (L, 4, 1, 0)! = 0) {ngx_log_error (NGX_LOG_ERR, log, 0, "error running function% s:% s", lua_funcname, lua_tostring (L,-1)); lua_close (L); return-2 } / * retrieve result * / if (! lua_isnumber (L,-1)) {ngx_log_error (NGX_LOG_ERR, log, 0, "function% s must return a number", lua_funcname); lua_close (L); return-3;} int result = (int) lua_tonumber (L,-1); lua_pop (L, 1) / * pop returned value * / lua_close (L); return result;}
The frustrating thing is that many of the functions of lua 5.2 have changed, such as lua_open obsolete, luaL_newstate, etc., but generally speaking, it hasn't wasted much time.
Next is the content of req_route.lua. I only intercept the entry function as follows:
Function get_route_id (method, uri, args, body) loc, pf, appid = get_need_vals (method, uri, args, body) if loc = = nil or pf = = nil or appid = = nil then return OUT_CODE end-- to this location So I got all the data-- print (loc, pf, appid)-- to find out whether to if not is_match_pf_and_loc (pf, loc) then return OUT_CODE end in the corresponding url, loc, and whether to if not is_match_appid (appid) then return OUT_CODE end return IN_CODE end in the corresponding appid.
OK, combined with the lua parser, no matter how complex the adjustment, we can basically modify only the lua script without the need to re-modify and compile the nginx module code.
Next, it's time to experience our results.
III. Nginx configuration
Server {listen 8080; server_name localhost; location / req_route {req_route; error_page 433 = @ 433; error_page 434 = @ 434;} location @ 433 {proxy_pass http://localhost:6788;} location @ 434 {proxy_pass http://localhost:6789;} error_page 500 502 503 504 / 50x.html Location = / 50x.html {root html;}}
OK,enjoy it!
The above is the example analysis of routing to different servers according to the post parameters in the Nginx custom module. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.