Welcome to Bo-Blog.
 [文章作者:张宴 本文版本:v1.0 最后修改:2011.07.26 转载请注明原文链接:http://blog.zyan.cc/httpsqs_1_7/]

  HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。

  项目网址http://code.google.com/p/httpsqs/
  使用文档http://blog.zyan.cc/httpsqs/
  使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
  软件作者:张宴



  HTTPSQS 1.7 版本更新内容:

  下面的内容不只是介绍 HTTPSQS 1.7 更新了哪些东西,更多的介绍在于:如何绕开 Libevent 2.0.x evhttp 使用过程中,无法正常处理包含“|”字符的 URI 参数的问题;提供了一份比 Libevent 官方网站更新的在线文档;Linux 下如何动态编译程序,运行时不用在 /etc/ld.so.conf 文件中添加动态链接库路径。

  1、针对 Libevent 2.0.x 版本 evhttp_parse_query 函数的 BUG。

  网友发邮件,反应了一个 HTTPSQS 的 BUG,见下图,data 的值为NULL。我查找发现,这不是 HTTPSQS 的 BUG,而是 Libevent 2.0.x 版本的 BUG。在 Libevent 1.4.14b 版本中,evhttp_parse_query 函数是能够正常处理包含“|”字符的 URI 的,而在 Libevent 2.0.12 版本中,同样使用 evhttp_parse_query 函数,包含“|”字符的 URI  处理后的结果是 NULL。

  点击在新窗口中浏览此图片

  对比 Libevent 2.0.12 和 1.4.14b 版本的 evhttp_parse_query 函数代码,发现在 2.0.12 版本中,evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 实际变成了调用 evhttp_parse_query_impl(uri, headers, 1) 函数,该函数内再调用的一个 2.0.x 版本新增的函数 evhttp_uri_parse(const char *source_uri),逻辑处理代码在 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 函数中。evhttp_uri_parse(const char *source_uri) 无法正确解析含有“|”的URL,遇到类似“http://127.0.0.1:1218/?opt=get&name=aaa|bbb”的URL,直接返回NULL,也就是 BUG 所在。

  libevent-2.0.12-stable/http.c
  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  不建议修改第三方库,这个 BUG 还是留给 Libevent 自己去解决吧。使用 Libevent 2.0.x evhttp 作开发的同学,遇到URI参数中包含“|”的问题,注意一下吧。

  我修改了 HTTPSQS 代码,在 HTTPSQS 1.7 版本,采用以下方式来绕开evhttp_uri_parse(const char *source_uri)函数,解决这个问题。其中用到了 Libevent 2.0.x  evhttp_request 结构体中新增的 struct evhttp_uri *uri_elems,以及新增的函数 evhttp_parse_query_str (const char *uri, struct evkeyvalq *headers)。
        
  1. /* 处理模块 */  
  2.     
  3. void httpsqs_handler(struct evhttp_request *req, void *arg)  
  4.     
  5. {  
  6.     
  7.         struct evbuffer *buf;  
  8.     
  9.         buf = evbuffer_new();  
  10.     
  11.       
  12.     
  13.         /* 分析URL参数 */    
  14.     
  15.         const char *httpsqs_query_part;  
  16.     
  17.         struct evkeyvalq httpsqs_http_query;  
  18.     
  19.         httpsqs_query_part = evhttp_uri_get_query(req->uri_elems);  
  20.     
  21.         evhttp_parse_query_str(httpsqs_query_part, &httpsqs_http_query);  

  Libevent 的官方文档只有 1.4.10-stable  2.0.1-alpha 版本的,2.0.1x 很多新增的函数、结构体都没有。

  我这里提供一份最新的 Libevent 在线文档: http://blog.zyan.cc/book/libevent/ 



  2、静态编译改为动态编译,并指定程序运行时查找的动态链接库路径 

  一些网友反映,CentOS 6.0、Fedora 等系统没有默认安装lz、lbz2、lrt、...等静态链接库,出现无法编译HTTPSQS的情况:
gcc -o httpsqs httpsqs.c prename.c -L/usr/local/libevent-2.0.10-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.10-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g --static  
/usr/bin/ld: cannot find -lz  
/usr/bin/ld: cannot find -lbz2  
/usr/bin/ld: cannot find -lrt  
/usr/bin/ld: cannot find -lpthread  
/usr/bin/ld: cannot find -lm  
/usr/bin/ld: cannot find -lc  
/usr/bin/ld: cannot find -lc  
collect2: ld 返回 1  
make: *** [httpsqs] 错误 1


  HTTPSQS 1.7 版本改为动态编译,编译时使用“-Wl,-rpath”参数指定了程序运行时的动态库搜索路径。这样就不需要在 /etc/ld.so.conf 中 添加 HTTPSQS 程序运行时需要的 libevent、tokyocabinet 动态链接库路径了,可以避免与其他软件(例如:Memcached、TT)使用的 libevent、tokyocabinet 动态链接库版本相冲突。详情请见 Makefile 文件:
# Makefile for httpsqs
CC=gcc
CFLAGS=-Wl,-rpath,/usr/local/libevent-2.0.12-stable/lib/:/usr/local/tokyocabinet-1.4.47/lib/ -L/usr/local/libevent-2.0.12-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.12-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g

httpsqs: httpsqs.c
  $(CC) -o httpsqs httpsqs.c prename.c $(CFLAGS)
  @echo ""
  @echo "httpsqs build complete."
  @echo ""  

clean: httpsqs
  rm -f httpsqs

install: httpsqs
  install $(INSTALL_FLAGS) -m 4755 -o root httpsqs $(DESTDIR)/usr/bin
 


  用 ldd 命令查看一下 HTTPSQS 使用的动态链接库:
[root@ibm1 httpsqs-1.7]# ldd ./httpsqs
        linux-vdso.so.1 =>  (0x00007fff0ebff000)
        libevent-2.0.so.5 => /usr/local/libevent-2.0.12-stable/lib/libevent-2.0.so.5 (0x00007f5157979000)
        libtokyocabinet.so.9 => /usr/local/tokyocabinet-1.4.47/lib/libtokyocabinet.so.9 (0x00007f51576f6000)
        libz.so.1 => /lib64/libz.so.1 (0x00000038a1400000)
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00000038a8800000)
        librt.so.1 => /lib64/librt.so.1 (0x00000038a2000000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00000038a1000000)
        libm.so.6 => /lib64/libm.so.6 (0x00000038a1800000)
        libc.so.6 => /lib64/libc.so.6 (0x00000038a0c00000)
        /lib64/ld-linux-x86-64.so.2 (0x00000038a0400000)

  发现,libevent 和 libtokyocabinet 使用的是我们指定 lib 路径中的动态链接库。



  HTTPSQS 的详细使用说明,请访问: http://blog.zyan.cc/httpsqs/
Tags: , , , , , ,
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]