Author Archives: verynix

Page 4 of 21« First...23456...1020...Last »

完美支持ipv6的测试工具:tsung

平日工作做单元测试经常会需要进行一些简单的压力测试,挺多功能要测试ipv6地址,在网上找了一圈,发现只有tsung这个的命令行工具能完美支持ipv6地址,非常强大,它是一款分布式的、支持多协议的开源压力测试工具,据说压死过很多服务器,配置非常灵活,推荐大家使用。 来自官方网站的介绍:

What is Tsung ?

Tsung (formerly IDX-Tsunami) is a distributed load testing tool. It is protocol-independent and can currently be used to stress HTTP, WebDAV, SOAP, PostgreSQL, MySQL, LDAP, and Jabber/XMPP servers. It is distributed under the GNU General Public License version 2.

1.安装 需要安装erlang,以debian为例,去官方网站下载最新源代码: http://tsung.erlang-projects.org/;现在的最新版本是1.4.2。

sudo apt-get install erlang
tar zxvf tsung-1.4.2.tar.gz
cd tsung-1.4.2
./configure && make && make install

2.通过几个简单例子来理解配置文件 向服务器发送压力流量通过配置文件来设置相应参数。
2.1 向ip地址为2012:1081::10:8:1:75发压力,每隔0.2秒产生一个并发用户。















2.2 向ip地址为2012:1081::10:8:1:75发压力,每隔0.2秒产生一个并发用户,这次的端口是443(SSL)端口。















3.启动tsung

tsung start -f tsung.xml

tsung.xml是配置文件。

这是一些简单的例子,更多的配置和需求以后陆续更新;tsung用配置文件来定义压力的内容,让压力变得更加可控和扩展性。

参考文献:
1.tsung官方文档
http://tsung.erlang-projects.org/user_manual.html

2.来自iteye的一篇文章
http://cryolite.iteye.com/blog/378758

常见操作系统操作静态路由命令

记录一下常见系统设置静态路由的命令,备忘,希望对大家有帮助;注意:以下命令需要root权限。

1.ipv4
1.1 FreeBSD
1.1.1 添加路由
添加一条到网段192.168.2.0/24,下一跳地址是192.168.1.2的静态路由 :

route add -net 192.168.2.0/24 192.168.1.2

添加一条到主机192.168.2.1,下一跳地址是192.168.1.2的路由:

route add -host 192.168.2.1 192.168.1.2

1.1.2 删除刚才添加的路由

route del 192.168.2.0/24
route del 192.168.2.1

1.1.3 显示路由表信息

netstat -r

1.2 linux
1.2.1 添加路由

route add -net 192.168.2.0/24 gw 192.168.1.2
route add -host 192.168.2.1 gw 192.168.1.2

1.2.2 删除路由

route del 192.168.2.0/24
route del 192.168.2.1

1.2.3 显示路由表信息

netstat -r

1.3 windows xp
1.3.1 添加路由

route add 192.168.2.0 mask 255.255.255.0 192.168.0.10

1.3.2 删除路由

route delete 192.168.2.0

1.3.3 查看路由表信息

route print

 

2.ipv6
2.1 FreeBSD
2.1.1 添加路由

route add -net6 2012:2012::0/64 2012:2012::192:168:0:10
route add -net6 -host 2012:2012::192:168:2:1 2012:2012::192:168:0:10

2.1.2 删除路由

route del -inet6 2012:2012::0
route del -net6 -host 2012:2012::192:168:2:1

2.1.3 查看路由表,跟ipv4一样

2.2 linux
2.2.1 添加路由

route -A inet6 add 2012:2012::0/64 gw 2012:2012::192:168:0:10

2.2.2 删除路由

route -A inet6 del 2012:2012::0/64 gw 2012:2012::192:168:0:10

2.2.3 查看路由表

ip -6 route show

2.3 windows xp
有点罗嗦,请看这篇文章:

更详细的语法信息请看下面的参考文献。《WindowsXP下的IPv6配置》

参考文献:
1.FreeBSD手册 http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-routing.html
2.linux文档项目 http://tldp.org/HOWTO/Linux+IPv6-HOWTO/
3.MSDN http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_tcpip_pro_addstaticroute.mspx?mfr=true
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_ip_v6_pro_rt_add.mspx?mfr=true

4.来自百度一篇windows xp配置ipv6的文章,包括路由: http://hi.baidu.com/beimu/item/a2202bd0ea2fbaba33db90b7

学习graphviz:画双向队列或者双向链表

我在这篇文章《深入理解FreeBSD中的TAILQ》中需要画队列图举例子,想到的画图工具就是微软的visio,dia,diagram designer,易图等这些所见即所得的画流程图的软件,但是无法画出自己想要的那种效果,或者说要画出那种效果非常难,而且很做作的感觉;于是乎,网上乱搜一番,发现了强大的graphviz软件,画出来的图想当完美;它是AT&T的开源项目,原生的类unix命令行软件,沿袭了unix的文本即一切的思想,类似Knuth教授的tex软件,用文本生成图形。

来自官方网站的介绍(http://www.graphviz.org/):

What is Graphviz?

Graphviz is open source graph visualization software. Graph visualization is a way of representing structural information as diagrams of abstract graphs and networks. It has important applications in networking, bioinformatics,  software engineering, database and web design, machine learning, and in visual interfaces for other technical domains.

我现在要画出下面这个双向队列(或者双向链表)来学习graphviz。

说明(详细信息请见《深入理解FreeBSD中的TAILQ》):

1.这个队列头是queue_head,tqh_first指针指向第一个元素,tqh_last是一个二级指针,是最后一个元素1的tqe_next的地址。数据结构如下所示:

struct int_head {
    struct int_node *tqh_first; /* first element */
    struct int_node **tqh_last; /* addr of last next element */
} queue_head;

2.队列中的元素结构体如下:tqe_next是指向下一个元素的指针,tqe_prev是二级指针,是前一个元素的tqe_next的地址。

struct int_node{
    int num;
    struct int_node *tqe_next;  /* next element */
    sturct int_node **tqe_prev; /* address of previous next element */
};

先来一个简单的,画队列头的代码:

digraph g {
graph [
rankdir = "LR"
];
node [
fontsize = "20"
fontname = "Times-Italic"
shape = "record"
];

head [label = " tqh_first|  tqh_last"];
queue_head [label="queue_head",shape=plaintext];
head:last ->head:first;
head:first ->NULL;
head:last -> queue_head[style=invis,constraint=false];
}

生成这样的图:

解释:
这个图g中有3个节点:第一个节点叫做head,形状是record(可以分层,类似struct),第一层first的文字是tqh_first,第二层的文字是tqh_last;第二个几点叫做queue_head,形状是plaintext,也就是只有文字没有边框;第三个节点叫NULL。接下来是形容他们的指向关系。

下面这段代码生成开始的那个图:

digraph g {
rankdir=LR;
node [
fontsize = "20"
fontname = "Times-Italic"
shape = "record"
];

head [label = "tqh_first| tqh_last"];
first [label = " 2| tqe_next | tqe_prev"];
second [label =" 1| tqe_next | tqe_prev"];
queue_head [label = "queue_head",shape=plaintext]

head:first ->first:num[style=invis];
head ->queue_head[style=invis,constraint=false];
head:first ->first:num;
head:last ->second:next;

first:num ->second:num[style=invis,constraint=false];
first:next ->second:num;
first:prev ->head:first;

second:next ->NULL;
second:prev ->first:next;
}

解释:跟上图类似,只不过指向关系复杂一点。注意:head ->queue_head[style=invis,constraint=false];这行的目的是让queue_head在head结点的下方。

总结:这只是一个用graphviz画图的一个很简单的例子,graphviz在有很复杂的指向关系的时候,它的优势就会非常的突出,因为你不用去关心图形的拓扑细节,有了结点之间的指向关系,graphviz会自动生成相应的布局;更多内容请看下面的参考文献。


参考文献:

这里当然是最权威的文档,命令行的具体用法和图形的属性的详细信息都在这里的文档能找到;但是对于初学者来说,直接看文档可能会让你一头雾水,他们提供了一些具体的例子来学习: http://www.graphviz.org/Gallery.php

Kentbye的Flickr网络相册,这里有更多的例子,是新手入门非常好的资料;

来自icodeit的文章,这篇文章应该是国内介绍graphviz最详细的一篇文章了,强烈推荐。

  • 4.论坛

http://www.graphviz.org/forums/general-discussion

http://stackoverflow.com/

还有问题?到这两个地方问吧。

深入理解FreeBSD中的TAILQ

工作的主要内容是tcp/ip,平台是FreeBSD,而且在内核态开发,所以很多情况下会涉及内核的一些数据结构和宏,比如说mbuf和TAILQ等。
TAILQ是FreeBSD/linux内核对双向队列操作的一种抽象,抽象程度不亚于C++,能实现操作队列需要的各种操作:插入元素,删除元素,遍历队列等。这个队列的优点是插入元素很快。
这里先回顾一下队列的特点(来自维基百科 http://zh.wikipedia.org/wiki/%E9%98%9F%E5%88%97):

队列,又稱為佇列(英文queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。

FreeBSD中的TAILQ把整个队列头抽象为一个单独的数据结构,我们先看看FreeBSD中的TAILQ相关宏,然后再举例子理解这些宏。
这里用最简单的一个结构体来理解TAILQ,这个结构体中有一个int型整数,还有两个分别指向前方和后方的指针。

1.描述前一个和下一个元素的结构体

458 #define TAILQ_ENTRY(type)                       \
459 struct {                                \
460     struct type *tqe_next;  /* next element */          \
461     struct type **tqe_prev; /* address of previous next element */  \
462     TRACEBUF                            \
463 }

这是TAILQ对两个指向前后两个元素指针的抽象,抽象为TAILQ_ENTRY结构体:tqe_next是指向下一个元素的指针,tqe_prev是一个二级指针,指针变量的地址,是前一个元素的tqe_next的地址,解引用(*tqe_prev)之后就是本元素的内存地址;TRACEBUF是一个调试相关的宏,我们先不管它。举例:
我们声明一个结构体,这个结构体只有一个int型整数,还有前驱和后继指针。

struct int_node{
	int num;
	TAILQ_ENTRY(int_node);
};

宏展开之后就变成:

struct int_node{
	int num;
	struct int_node *tqe_next;  /* next element */ 
	sturct int_node **tqe_prev; /* address of previous next element */
};

例如:

2.队列头

TAILQ把整个队列头单独抽象为一个结构体TAILQ_HEAD,如下:

445 /*
446  * Tail queue declarations.
447  */
448 #define TAILQ_HEAD(name, type)                      \
449 struct name {                               \
450     struct type *tqh_first; /* first element */         \
451     struct type **tqh_last; /* addr of last next element */     \
452     TRACEBUF                            \
453 }

这个宏实际上使用的时候,会展开成为一个结构体,tqh_first是一个一级指针,指向队列中的第一个元素;tqh_last是一个二级指针,它指向最后一个元素中的tqe_next(请参考上面的TAILQ_ENTRY),也就是最后一个元素的tqe_next的地址,指针的地址就是二级指针;TRACEBUF是一个用来调试的宏,不用管它。举例:

声明一个叫做queue_head的队列头:

TAILQ_HEAD(my_int_struct, my_int) queue_head;

宏展开之后就会变成(不管TRACEBUF宏):

struct int_head {
	struct int_node *tqh_first; /* first element */
	struct int_node **tqh_last; /* addr of last next element */
} queue_head;

如图:

用下面的宏初始化这个队列头:

534 #define TAILQ_INIT(head) do {                       \
535     TAILQ_FIRST((head)) = NULL;                 \
536     (head)->tqh_last = &TAILQ_FIRST((head));            \
537     QMD_TRACE_HEAD(head);                       \
538 } while (0)

变成:

3.插入元素

插入元素用TAILQ_INSERT_TAIL宏,由于TAILQ中有一个tqh_last的二级指针,所以插入元素直接插到队尾,仅用O(1)时间。

578 #define TAILQ_INSERT_TAIL(head, elm, field) do {            \
579     QMD_TAILQ_CHECK_TAIL(head, field);              \
580     TAILQ_NEXT((elm), field) = NULL;                \
581     (elm)->field.tqe_prev = (head)->tqh_last;           \
582     *(head)->tqh_last = (elm);                  \
583     (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
584     QMD_TRACE_HEAD(head);                       \
585     QMD_TRACE_ELEM(&(elm)->field);                  \
586 } while (0)

QMD_TAILQ_CHECK_TAIL,QMD_TRACE_HEAD,QMD_TRACE_ELEM这三个宏和调试信息相关和做一些必要的检查,我们可以先不管;这个宏就是在调整相关的指针指向。我们向一个空队列插入两个元素2来理解这个宏:
3.1 580行让新元素的tqe_next指向空,执行完第580行:

3.2 581行让新元素的tqe_prev赋值为tqh_last,也就是指向队列头中的tqh_first的地址,执行完第581行:

3.3 582行让二级指针tqh_last中的内容指向新元素,也就是tqh_first指向新元素,执行完第582行:

3.4 583行,队列头的tqh_last赋值为新元素的tqe_next的地址(指针的地址,二级指针),执行完第583行:
这就是插入2后的整个链表。

4.删除元素

删除元素用TAILQ_REMOVE宏

596 #define TAILQ_REMOVE(head, elm, field) do {             \
597     QMD_SAVELINK(oldnext, (elm)->field.tqe_next);           \
598     QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);           \
599     QMD_TAILQ_CHECK_NEXT(elm, field);               \
600     QMD_TAILQ_CHECK_PREV(elm, field);               \
601     if ((TAILQ_NEXT((elm), field)) != NULL)             \
602         TAILQ_NEXT((elm), field)->field.tqe_prev =      \
603             (elm)->field.tqe_prev;              \
604     else {                              \
605         (head)->tqh_last = (elm)->field.tqe_prev;       \
606         QMD_TRACE_HEAD(head);                   \
607     }                               \
608     *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);      \
609     TRASHIT(*oldnext);                      \
610     TRASHIT(*oldprev);                      \
611     QMD_TRACE_ELEM(&(elm)->field);                  \
612 } while (0)

QMD_SAVELINK,QMD_TAILQ_CHECK_NEXT,QMD_TAILQ_CHECK_PREV,TRASHIT,同样先不管这几个宏。我们从队列中删除一个元素来理解这个宏:
4.1 假设经过上节插入元素2之后,我们用TAILQ_INSERT_TAIL再插入一个元素1,没有删除之前的链表如下图:

现在假设我们删除队列中的第一个元素2

4.2 602和603在调整当前元素的下一个元素的tqe_prev指针,执行完第602行和603行之后:

4.3 608调整当前元素tqe_prev中的内容,执行完第608行之后:

4.4 释放结点2的空间之后,最后的链表:

5.队列中的第一个元素

512 #define TAILQ_FIRST(head)   ((head)->tqh_first)



6.当前元素的下一个元素

591 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)

这个宏比较简单。

7.遍历链表中的每一个元素

用宏TAILQ_FOREACH

514 #define TAILQ_FOREACH(var, head, field)                 \
515     for ((var) = TAILQ_FIRST((head));               \
516         (var);                          \
517         (var) = TAILQ_NEXT((var), field))

这个宏就比较简单了,用临时变量var来遍历链表中的每一个元素。

这些宏就是几个操作TAILQ经常使用的宏,还有一些诸如TAILQ_INSERT_HEAD等宏,类似,请自行看代码,这里就不一一叙述了。这篇文章主要是理解相关的宏和插入删除过程,完整的应用例子请看下面的参考文献。

参考资料:

debian下安装curl loader压力工具出现crypto.h的错误

FreeBSD的编译环境跟linux差别怎么这么大,很多时候gmake编译源代码都出错,很无奈啊;最近用到一些http的测试工具,源代码安装,在FreeBSD上源代码安装很难成功,依赖关系残缺不全,用ports安装也不省心,果断用debian linux。
找个能支持ipv6的压力测试工具真是难啊,tsung貌似很强大,也符合要求,但是BSD7上通过cli安装tsung好麻烦,新的ports还要java的license认证,麻烦加无语啊,后来找来找去,貌似curl loader很符合要求,能做ftp和ipv6的压力测试,果断安装,但是debian上源代码编译有如下错误:

ssl_thr_lock.h:27:28: error: openssl/crypto.h: No such file or directory

本以为安装openssl就行了,但是谷歌发现,需要安装openssl-devel,debian的包名叫libssl-dev,安装之后就OK了。这种错误让新手很无语加蛋疼,权且记录下来,让需要的人少走些弯路。

启动Aptixia IxLoad出现错误

启动Aptixia IxLoad可能会出现如下错误:

Setting CurrentDirectory = C:\Program Files\Ixia\IxLoad\5.0-EA\Client
Loading resources...
Using database: (local)\IXIA2005\IxLoad_5_0_117_28
Resources loaded OK.
*************************** GetPathToDlls from IXLOAD: 'ixload'
************************Loading EX python23 from C:\Program Files\Ixia\IxLoad\5.
0-EA\3rdParty\Python2.3\python23.dll
************************Loading EX wintypes from C:\Program Files\Ixia\IxLoad\5.
0-EA\3rdParty\Python2.3\DLLs\pywintypes23.dll
'import site' failed; use -v for traceback
warning: integer multiplication
Application Error:

--------------------------------------------------------------------------------

Exception Type: exceptions.KeyError
Exception Description: 'WINDIR'
Exception Stack:
Traceback (most recent call last):
File "Client\Lib\Common\ixCal.py", line 28, in ?
File "E:\build\ixweb-5.0-28\ixweb\5.0\Client\Lib\Common\ixMainLock.py", line 8
2, in ?
File "E:\build\ixweb-5.0-28\ixweb\5.0\Client\Lib\Common\ixMainLock.py", line 8
6, in ixMainLock
File "E:\build\ixweb-5.0-28\ixweb\5.0\Client\Lib\Common\ixMainLock.py", line 4
3, in getMaxInstanceNo
File "E:\build\ixweb-5.0-28\ixweb\5.0\Client\Lib\Common\ixMainLock.py", line 3
0, in isRunningOnIxiaAppServer
File "E:\build\ixweb-5.0-28\ixweb\5.0\3rdParty\Python2.3\Lib\os.py", line 417,
in __getitem__
KeyError: 'WINDIR'

--------------------------------------------------------------------------------

Press [Enter] to quit...

Aptixia IxLoad 安装在c盘,看了一下日志,猜测是WINDIR环境变量的问题,在当前的用户设置里面添加用户变量WINDIR=C:\WINDOWS,如下图,果然,问题解决。

命令行测试ssl回话

工作到现在,经常在和HTTP协议打交道,所以HTTP相关的开发工具和调试工具是必备的;平时工作中调试bug的时候,一般都是调试单个回话的居多,所以经常使用telnet调试HTTP会话,telnet虽然功能极其简单,但是也极其的强大,因为你可以构造任何http header给服务器,这样你就可以研究各种条件下http服务器的返回内容;下面的一个例子。

但是telnet不支持ssl,需要这样测试https,怎么办,用openssl的s_client客户端就可以了,前提是你安装openssl:

openssl s_client -connect www.example.com:443

如下图:

 

参考资料:

1.http://www.bearfruit.org/2008/04/17/telnet-for-testing-ssl-https-websites/

谷歌搜索关键字telnet ssl,这是第一篇文章,也是从这里学到的;

2.http://www.ibm.com/developerworks/cn/linux/l-cn-sclient/index.html

这篇来自ibm的文章列举了openssl的s_client客户端的几个高级用法;

3.http://www.blogjava.net/ycyk168/archive/2009/11/27/303946.html

这篇博文举了几个s_client应用的简单例子;

4.http://www.openssl.org/docs/apps/s_client.html

这是openssl s_client客户端的官方手册。

配置你的firefox,让开发和测试工作变得更方便

今天终于知道了为什么firefox是开发利器,不仅对于前端开发工程师来说重要,对于web开发人员来说用处也非常大,因为它具有高度的可配置型,这里举几个例子,配置在工作中我经常用到的几个参数。

在firefox的浏览器地址栏里面输入:about:config,然后配置相应参数。
1.favicon.ico文件
当你用firefox进行简单http测试的时候,很多情况下你会用wireshark等抓包工具观察报文情况,你会发现,一般都会多出几个和favicon.ico 有关的404会话,这是很烦人的,它会打扰你分析问题;因为正常情况下,firefox会到根目录取favicon.ico文件, 你可以配置这两个参数:browser.chrome.favicons,browser.chrome.site_icons;让它禁止读取favicon.ico这个文件。如下图所示 。

browser.chrome.favicons

 

2.http请求的版本
这久一直在修复几个和http版本相关的bug,具体情况是,当http请求的版本号和http响应的版本号不一致的时候,系统无法正确处理压缩编码的内容,测试的时候需要发送不同的http请求版本,可以双击修改这个参数:network.http.version;如下图所示。

http version

3.Accept-Encoding头的值
你可能需要发送不同的编码值,例如,gzip,deflate,identity等等,你可以双击修改这个参数:network.http.accept-encoding;如下图所示。

accept-encoding

Page 4 of 21« First...23456...1020...Last »