169it科技资讯


当前位置:  建站>运营/SEO
本页文章导读:
    ▪《深入理解Nginx》阅读与实践(三):使用upstream/subrequest访问第三方服务        本文是对陶辉《深入理解Nginx》第5章内容的梳理以及实现,代码和注释基本出自此书。   一、upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例 (一)模块框架   .........
    ▪如何给Fedora 15创建磁盘分区      如何给Fedora 15创建磁盘分区 1. 由普通用户切换到root用户 命令:su – 注:使用管理员用户身份运行命令也可以实现,但因在root用户中操作较方便,以下操作均在root用户中进行。 2. 使用fdisk.........
    ▪Packet Sniffer Code in C using sockets      接idc通知,按工信部和公安部要求,要对网站用户上下线时间ip用户名做记录,至少保留一年(什么乱七八糟啊)。 参考了以下code,做了一个http sniffer,把http header全部记录下来,比较简单,截.........

[1]《深入理解Nginx》阅读与实践(三):使用upstream/subrequest访问第三方服务
    来源: 互联网  发布时间: 2013-11-01

  本文是对陶辉《深入理解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 = "      
    
[2]如何给Fedora 15创建磁盘分区
    来源: 互联网  发布时间: 2013-11-01

如何给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)


作者:lyc_daniel 发表于2013-8-21 15:51:12 原文链接
阅读:62 评论:0 查看评论

    
[3]Packet Sniffer Code in C using sockets
    来源: 互联网  发布时间: 2013-11-01
接idc通知,按工信部和公安部要求,要对网站用户上下线时间ip用户名做记录,至少保留一年(什么乱七八糟啊)。
参考了以下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/
作者:jollyjumper 发表于2013-8-21 20:22:10 原文链接
阅读:56 评论:0 查看评论

    
最新技术文章:
 




特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号