本文是对陶辉《深入理解Nginx》第5章内容的梳理以及实现,代码和注释基本出自此书。
一、upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例 (一)模块框架
首先要明确的是,这里是编写一个使用upstream的模块,而不是编写upstream模块。因此,和HelloWorld类似,模块结构体ngx_http_mytest_module、模块上下文结构体ngx_http_mytest_module_ctx、数组ngx_http_mytest_command[]、方法ngx_http_mytest()和ngx_http_mytest_handler()的框架是不可少而且又十分相似的。如果忘记了它们之间的关系,请回顾原书或《深入理解Nginx》阅读与实践(一):Nginx安装配置与HelloWorld。
模块处理的请求是ngx_http_request_t结构对象r,它包含了一个ngx_http_upstream_t类型的成员upstream。当upstream非NULL时,将会根据其中设置的内容定制访问第三方服务的方式。而这个请求的处理是由upstream模块来完成的。从这里开始,要注意区分请求r中的upstream成员和Nginx提供的upstream模块不是一回事,而是由前者来指导后者的工作。前者的设定与开启(即告知upstream模块需要进行处理,通过ngx_http_upstream_init()实现)是由我们编写的的第三方模块(本文中是mytest)来完成的。
(二)upstream设置
upstream工作方式的配置可以通过填写由ngx_http_upstream_create(ngx_http_request_t *r)所传入的请求r中的ngx_http_upstream_t结构体来完成。这个函数成功返回时,即把请求r中的upstream设置为非NULL。ngx_http_upstream_t结构体主要包含了一下几个成员,由于原书对这里模块编写所需要用到的成员已做详细介绍(暂时用不到的成员在12章介绍),这里只做一个部分的概括:
typedef ngx_http_upstream_s ngx_http_upstream_t; sturct ngx_http_upstream_s { ... ngx_chain_t request_bufs;//发给上游服务器的请求,由create_request()完成 ngx_http_upstream_conf_t conf;//超时时间等限制性参数 ngx_http_upstream_resolved_t resolved;//用于直接指定的上游服务器地址 //设定方法请见mytest模块的ngx_http_mytest_handler()方法 /* 3个必须实现的回调方法 */ ngx_int_t (*create_request)(ngx_http_request_t *r);//构造向上游服务器发送的请求内容。调用mytest时,只调用一次 ngx_int_t (*process_header)(ngx_http_request_t *r);//收到上游服务器后对包头进行处理的方法 void (*finalize_request) (ngx_http_request_t *r, ngx_int_t rc);//销毁upstream请求时调用 /* 5个可选的回调方法,本文中用不到*/ ngx_int_t (*input_filter_init)(void *data);//处理上游包体 ngx_int_t (*input_filter)(void *data,ssize_t bytes);//处理上游包体 ngx_int_t (*reinit_request)(ngx_http_request_t *r);//第一次向上游服务器建立连接失败时调用 void (*abort_request)(ngx_http_request_t *r); ngx_int_t (*rewrite_redirect)(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix); //主要用于反向代理 ... }
可见,使用upstream功能时,除了需要按HelloWorld编写自己的模块和提供处理配置项的方法ngx_http_mytest_create_loc_conf()、ngx_http_mytest_merge_loc_conf()外,还需要填写ngx_http_upstream_t结构体并实现3个必备的回调方法。要注意的是,这些回调方法都是由模块的编写者提供、再由upstream模块来调用的。
(三)配置项获取
原书例子是将访问的URL请求/test?lumia转化成对www.google.com的搜索请求/search?q=lumia。为了简化,大部分参数采用硬编码的形式nginx.conf的添加的内容和以前一样:
location /test { mytest; }
typedef struct { ngx_http_upstream_conf_t upstream; } ngx_http_mytest_conf_t; static void* ngx_http_mytest_create_loc_conf(ngx_conf_t *cf) { ngx_http_mytest_conf_t *mycf; mycf = (ngx_http_mytest_conf_t *)ngx_pcalloc(cf->pool,sizeof(ngx_http_mytest_conf_t)); if(mycf == NULL) { return NULL; } mycf->upstream.connect_timeout = 60000; mycf->upstream.send_timeout = 60000; mycf->upstream.read_timeout = 60000; mycf->upstream.store_access = 0600; mycf->upstream.buffering = 0; mycf->upstream.bufs.num = 8; mycf->upstream.bufs.size =ngx_pagesize; mycf->upstream.buffer_size = ngx_pagesize; mycf->upstream.busy_buffers_size = 2*ngx_pagesize; mycf->upstream.max_temp_file_size = 1024*1024*1024; mycf->upstream.hide_headers = NGX_CONF_UNSET_PTR; mycf->upstream.pass_headers = NGX_CONF_UNSET_PTR; return mycf; } static char* ngx_http_mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_mytest_conf_t *prev = (ngx_http_mytest_conf_t *)parent; ngx_http_mytest_conf_t *conf = (ngx_http_mytest_conf_t *)child; //ngx_conf_merge_str_value(conf->my_str,prev->my_str,"defaultstr"); ngx_hash_init_t hash; hash.max_size = 100; hash.bucket_size = 1024; hash.name = "
如何给Fedora 15创建磁盘分区
1. 由普通用户切换到root用户
命令:su –
注:使用管理员用户身份运行命令也可以实现,但因在root用户中操作较方便,以下操作均在root用户中进行。
2. 使用fdisk命令,查看现有磁盘情况
命令:fdisk -l
输出:
可以看到在刚才新创建的8G磁盘sdb。
3. 为sdb创建一个主分区
(1)执行分区
命令:fdisk/dev/sdb
输出:
(2)查看命令
命令:m
输出:
(3)创建分区
命令:n
输出:
(4)创建主分区
命令:p
输出:
(5)输入主分区号
采用默认即可,直接回车。
(6)第一扇区大小
采用默认即可,直接回车。
(7)最后一个扇区大小
按扇区不好确定分区大小,直接采用+size{K, M, G}来确定2G大小的扇区。
命令:+2G
输出:
至此,已经创建一个2G的主分区。此时,分区表还在内存中,需要写入磁盘,才能真正有效。
(8)将分区表写入磁盘
命令:w
输出:
(9)参看sdb分区情况
方法一:
命令:ls/dev/sdb*
输出:
方法二:
命令:fdisk -l
输出:
以上两种方法均可以看出,已经成功创建主分区。
4. 为sdb创建扩展分区后再创建逻辑分区
(1)执行创建
输入命令fdisk/dev/sdb后,再输入n
输出:
(2)执行创建扩展分区
输入e后,直接回车,即采用默认序号;再回车,将所有剩下的空间全部分为扩展分区。
输出:
(3)打印分区表
输入:p
输出:
可以看出,已经成功创建了扩展分区。
(4)执行创建
输入:n
输出:
(5)创建逻辑分区
输入l后,回车给第一扇区默认序号;再输入+2G,创建2G大小的逻辑分区。
输出:
(6)打印分区表
(7)将分区表写入磁盘
输入:w
输出:
(8)查看分区情况
输入:fdisk -l
输出:
注:按windows习惯,操作系统放在主分区,其他的放在逻辑分区。引导也是在主分区。
可以看出,已经成功创建逻辑分区。
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
- 博客网址:http://blog.csdn.net/lyc_daniel/article/details/10149607
- 博 主: lyc_daniel
-
寄 语:神爱世人,甚至将他的独生子(耶稣)赐给他们,叫一切信他的,不至灭亡,反得永生。(圣经·约翰福音3:16)
参考了以下code,做了一个http sniffer,把http header全部记录下来,比较简单,截取数据直接是:
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
while(1)
{
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
}
参考:http://www.binarytides.com/packet-sniffer-code-c-linux/