作者归档:Dante

RSS feed of Dante

最后更新于 .

一直以来,我都在考虑一个问题,怎么能保证在一个单机访问量上万的服务在上线之后一定是稳定的呢?测试,我们有单元测试,功能测试,但这是否够了呢?不够!一定尽量模拟正式环境的测试,否则一切都是没有办法保证的。 所以我写了fuload这个压力测试框架,并且把它开源,原因有几个:

  • 1.让所有人的做压力测试变得简单
  • 2.让尽量多的人,参与到开源项目里来

这个项目目前虽然已经能够正常的提供服务,但还需要尽量多的优化,所以很希望有朋友能够参加进来。另外,本博以后也会负责一些开源项目的开发和维护。一群素未蒙面的人一起完成一件有意义的事情,酷! 项目网址如下:http://code.google.com/p/fuload/ 详细的说明文档如下: 一.这个框架能做什么? 简单来说,fuload是为了给大型服务做压力测试或性能测试诞生的,你可以通过fuload来对你待上线或者已经上线的服务进行压力测试,并能通过详细的报表得出对你的服务的客观评价。 二.架构说明 整个框架实际包括两个部分:master和slave,master上运行用来统计的网站,slave上会调用用户自写的so并实现向master的上报. 上报的结果可以直接在master端查看,链接如下:http://{youhost}/report/show/(如图所示):

1

1

三 ...

最后更新于 .

这篇文章还是关于fuload项目的问题,由于压力测试的结果最后是要给出可视化统计曲线及饼图的,所以这里就涉及到数据上报时间,格式,以及绘制算法的问题。 饼图比较简单,我们这里主要看调用时间的曲线图。 我们采用自顶向下的方法来分析,先分别来看输入和输出。 前提

  • 有多台机器(称为从机),同时想远程机器上报,由远程机器(称为主机)统一绘制。

输入

  • 一段时间内(如5分钟):起始时间,结束时间,总的调用时间,调用次数,平均调用时间。

输出

  • 根据平均响应时间,绘制时间为横轴,调用时间为纵轴的走势曲线图。

这里主要有几个难点

  • 1.对于这“一段时间”来说,每台从机是不一样的,即可能A机器报了7点5分~7点10分的数据,而B机器报了7点7分到7点12分的数据,也可以理解为主机端接收到每台从机上报数据时间点是不统一的。要解决这个问题,我们可以通过对上报数据做分片的处理,简单来说,既然我们选择了5分钟上报一次,那么统计图的X轴一定是5分钟一个统计点,比如拿7点5分~7点10分这段时间来说,7点7分~7点12分的数据有3/5落在了这个时间段(具体计算可以更精确),另外有2/5落在了7点10分~7点15分,这样统计曲线就可以绘制出来了。
  • 2.相信从机时间还是主机时间 ...

最后更新于 .

今天发文比较多,哈,实在是觉得知识就该及时沉淀下来,时间长了难免记忆会模糊。 OK,直接切入正题,之前http://t.vimer.cn上提过正在开发的fuload压力测试框架,由于是想拿python做胶水语言,所以不可避免的涉及到了进程间通信的问题。 简单来说就是,一个python写的主进程与多个c写的处理进程通信的问题。主进程启动之后,会启动多个c的处理进程,主进程会对处理进程发送数据,并控制处理进程。 这种情况在server的编写中比较常见,为了解耦一般会将接受数据的进程与处理进程分开,在c中的实现一般是主进程先fork出子进程,然后在子进程中调用exec将自身替换为处理进程,进程id不变。这样主进程即可拿到所有的子进程id进行统一管理。 python当然也可以通过这种方式来实现,fork+execv即可完美重现,但是这可是无所不能的python呀,是否有更好的方式呢? 有的!python2.4之后引入了subprocess模块,通过它,我们将不再需要繁琐的调用fork,execv等,其主要函数如下:

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn ...

最后更新于 .

最近部门在推行单元测试框架的时候,对C++有指定使用gtest,但对php并没有规定使用的框架,在试用了几个php单元测试框架后,认为simpletest这个框架最简单易用,而phpunit实在过于庞大与繁琐了。 这里简单说一下simpletest的使用。一个简单的unittest文件如下:

define('BASE_PATH','/home/dantezhu/appbase/php/');

require_once BASE_PATH . '/simpletest/autorun.php';

class TestOfSite extends UnitTestCase
{
    function __construct()
    {
        parent::__construct();
    }
    function setUp() {}
    function tearDown() {}

    function test_case1()
    {
        $this->assertTrue(true);
    }
}
$test = &new TestOfSite();
//$test->run(new HtmlReporter());
$test->run(new TextReporter());

其中以test开头的函数即为每个testcase,而setUp和tearDown函数分别为每个testcase运行开始前和结束后会自动调用的函数,可以做一些初始化或者清理工作。

$test = &new TestOfSite();
//$test->run ...

最后更新于 .

《vim(gvim)正则表达式查找替换》是个比较久的系列了,这次因为博友niejieqiang的一个问题,所以决定继续在写一篇,而主题就是将正则表达式查找替换与vim脚本结合。 其实这种方法在之前的文章中也出现过如: vim(gvim)正则表达式查找替换(4)-生成连续数字或行号

let i=1|g/1/s//\=i/|let i=i+1

就是一种方式。 OK,回到正题,我们来看一下博友niejieqiang的问题:

A格式如下:
nrk 你
nrk 侚
….
sobb 论坛
sobb 交款
sobb 文坛
…
ejj 茴
ejj 莒

需要转换成B格式:
nrk 你 侚
sobb 论坛 交款 文坛
ejj ...

最后更新于 .

可能不少读者知道,本博之前是有单独搭建过一个微博:http://t.vimer.cn,用来记录一些简短的思想,不过后来由于与主站的关联太少,所以就没有再使用了。
不过最近对于这种一句话思想的需求日渐多了起来,所以发愤图强,终于算是搞定啦~(如果还没注意到的朋友,请看右侧的"我的唠叨")。
如图:

1


对于http://t.vimer.cn的搭建比较简单,使用的是p2主题,大家自行安装即可,这里只贴出右侧widget的实现,代码如下:

<?php
$con = mysql_connect('localhost', 'dantezhu_wp', 'xxxxxxxx',true);
mysql_query("SET NAMES 'utf8'");
mysql_select_db('dantezhu_t',$con);
$result = mysql_query("select * from wp_posts where post_status='publish' order by ID desc limit 1 ...

最后更新于 .

今天在开例会的时候,提到其他小组要做一个通用任务系统,会涉及到C++调用其他语言脚本开发的逻辑。之前倒是听互娱那边的同事说过,他们都是嵌入lua来进行脚本编程,但自己从来没试过。
而作为一个严重中毒的vim+python爱好者,其实我每天都在用vim直接执行python命令(如出名的pyflakes插件),想知道vim是怎么实现的,所以就自己试了一下。
由于家里没有linux开发环境,所以就在windows下用 Mingw + makefile的方式开发了。
先写一个简单的py程序:helloworld.py

def hello():
       print"hello,world!"

然后来写我们的c++代码:

py.cpp

#include<Python.h>//前面所做的一切配置都是为了调用这个头文件和相关库
int main()
{
    Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
    PyObject * pModule = NULL;//声明变量
    PyObject * pFunc = NULL;// 声明变量
    pModule =PyImport_ImportModule ...

最后更新于 .

好吧,因为组织需要,最近又开始转战php了,业务逻辑都还好说,主要是老大要求在数据访问层上加上登录态验证。
其实这种要求也是合理的,互联网服务要求上层保护下层,但下层不能完全相信上层。但是问题也就来了,有如下两种方案:

1.写一个mysql proxy server,用来将调用方发来的请求拼装,然后返回给调用侧。这样做的主要难度在于:

  • a)SQL语句的拼装及序列化
  • b)数据集序列化,虽然有不少这方面的产品,但是终究还是太过复杂,而且没有时间折腾

果断放弃。
2.封装一层mysql的api,调用方直接在本地调用即可。这样的话,只需要考虑SQL语句的拼装即可。现在就有很多选择啦,

  • a)使用类似django里面Model的模型类
  • b)使用ci中的Active Record

虽然说Model的方式,对数据层的屏蔽较好,但是小组成员普遍认为这种方式过重,轻量的一点的话,最终还是选择了CodeIgniter中的AR。
OK,那么现在,考验ci模块拆分的好不好的时候到啦!
具体中间的种种辛苦就不说啦,直说我最终的实现把,拷贝system\database到一个单独的目录,x:/php/ 。
创建一个文件myconfig.php:

<?php
define ...

最后更新于 .

很久没有写vim相关的文章,愧对vimer.cn这个域名呀~~哈,不过我还是尽量保持经常给大家提供一些Vim相关的知识。
这次介绍的是 recover.vim (http://www.vim.org/scripts/script.php?script_id=3068)
先简单介绍一下背景,vim有自动生成swp文件的功能,能够在异常情况下(简单来说就是你的vim进程被强制终止)将你没有来得及保存的代码存储下来。
但这仍然有个问题,当你再次打开那个文件的时候,vim仅提示你是否要恢复,但是我们并不知道会被恢复成什么样子。。
recover.vim就是为了解决这个问题。
我们直接来做个演示可能会比较明确,以windows下的gvim7.3为例。
新建一个文件 1.cpp,写入如下数据但是不保存

#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
int main(int argc, const char *argv[])
{
    
    return 0 ...

最后更新于 .

最近需要给一个现网server增加过载保护的功能,借此机会也思考了很多,简单谈谈我对这两个概念的理解和实现方法。
一.负载均衡
简单来说,就是按照目标server的参数进行合理分配,这个参数可以是失败率,也可以是响应时间,也可以是请求量,甚至是随机数。
我们来按照从简单到复杂逐个看一下几种实现。
1.轮询式
逻辑比较简单,直接看代码:

vector vecServer;
while(1)
{
    Server* server = vecServer[curIndex % vecServer.size()];
    curIndex ++;
}

如上代码就是一个简单的轮询式分配方法,这种方法优点实现简单,cpu计算少,缺点就是无法动态判断server的状态,当后端有一台server挂掉的时候,会至少1/vecServer.size()的请求。(最为严重的情况是由于单台后端server的超时导致前段全部挂死)。而且这种分配方法有一个bug,就是当每次请求结束后就释放内存,那么curIndex永远都只会为0,即每次都请求第一个server。
2.定死权重式
这种方式适用于那种需要实现就规定后端server的权重,比如A比Bserver的响应速度快,我们希望A接受的请求比B多。

//假设A,B, C server的权重分别为 10 5 2
typedef struct ...