服务端研发应具备的技能(3)

原创 2013年12月02日 11:25:58

2,数据传输

我这里指的数据传输意思是当我们写好处理程序时往往由于需要多机来同时处理以达到处理性能要求(单机情况下不能达到处理性能要求)

而这时需要各处理机程序可以无序化的对等条件下处理数据,这样可以方便新机器上程序部署扩充

这里我常用的就是两种方式1,gearman方式; 2,RPC方式

用起来很方便也很灵活



2.1 gearman队列

如下为图示简单描述:

我这里举个例子:有人(许多人)A会写信,然后投到附近的邮筒中,然后邮局B统一处理将信件投到对应地点, 最后有人C会取信件

在这个过程中A就相当于client,  B相当于server,  C相当于worker,(你A只管投,C只管取,当然没有数据话C也会一直查看)

也就是client往队列中投递数据,worker负责取走队列中的数据然后处理,而这中间的队列就是gearman





这里client常用的内个函数为

›gearman_client_do_background
›gearman_client_create
›gearman_client_free
›gearman_client_add_server
gearman_client_set_timeout

其中create为创建 ,add_server为注册投递队列服务机器,do_background即为将数据发送到队列中


例如 php程序中编写client端程序构造函数中可以注册队队相关信息,

//gmServer="your hostname or ip";      gmPort="your port default 4730",   gmName="queue name"

function __construct($gmServer, $gmPort, $gmName)

{

  parent::__construct(); 

  $this->m_gmclient = new GearmanClient();

  $this->m_gmclient->setTimeout(3000);

  $this->m_gmServerEnv['gmServer'] = $gmServer;  

  $this->m_gmServerEnv['gmPort']   = $gmPort; 

  $this->m_gmServerEnv['gmName']   = $gmName;

   if(!is_array($this->m_gmServerEnv['gmServer'])) {

                   $this->m_gmclient->addServer($this->m_gmServerEnv['gmServer'],$this->m_gmServerEnv['gmPort']); 

    } else { 

                    foreach ($this->m_gmServerEnv['gmServer'] as $serverItem) {

                               $this->m_gmclient->addServer($serverItem, $this->m_gmServerEnv['gmPort']);    }

                    }

    }

}

这样完成注册后可以登录到注册机器上看下4370端口


注册完成后需要处理数据然后把数据发到注册的这个队列中,可以示例如下示:

这里注意看,是不是我们调用了do_backguound了(一般都会试几次,因为可以由于网络原因出现失败,毕竟这个是基于网络传输的)


function send($data) {
        $try_cnt = 3;
        while ( $try_cnt > 0 ) {
            $this->m_gmclient->doBackground($this->m_gmServerEnv['gmName'], $data);
            if ($this->m_gmclient->returnCode() != GEARMAN_SUCCESS) {
                unset($this->m_gmclient);
                $this->m_gmclient = new GearmanClient();
                $this->m_gmclient->setTimeout(3000);
                $this->m_gmclient->addOptions(GEARMAN_CLIENT_RETRY_ON_FULL);
                if(!is_array($this->m_gmServerEnv['gmServer'])) {
                    $this->m_gmclient->addServer($this->m_gmServerEnv['gmServer'],$this->m_gmServerEnv['gmPort']);
                } else {
                    foreach ($this->m_gmServerEnv['gmServer'] as $serverItem) {
                        $this->m_gmclient->addServer($serverItem, $this->m_gmServerEnv['gmPort']);
                    }
                }  
            } else {
                return 0;
            }
            $try_cnt-- ;
        }
        return -1;
    }


好了,以上这两块完成后,说明client端可以把数据发到指定队列中了


那么worker端如何接收呢?

worker常用的函数

›gearman_worker_create
›gearman_worker_add_server
›gearman_worker_set_timeout
›gearman_worker_add_function
›gearman_worker_work
›gearman_job_workload
›gearman_job_workload_size
其实过程如果client完成的话,情况都差不多,只不过多了几个函数

job_workload: 这个相当于从队列中取到数据了

add_function: 这个相当于一个回调函数,意思是由这个函数来处理从队列中接收到的数据

例如下面这个函数gearman_worker_work(&worker)即是去队列中取数,取的数由gearman_worker_add_function(&worker, gmname.c_str(), 0, handler_work, NULL);函数中handler_worker这个函数来处理


static void receiveGearman(gearman_worker_st& worker, size_t& timeout, std::string& gmname)

{

        gearman_worker_set_timeout(&worker, timeout);      

        gearman_return_t ret;  

        ret= gearman_worker_add_function(&worker, gmname.c_str(), 0, handler_work, NULL);

        if (ret != GEARMAN_SUCCESS) {

               printf("%s", gearman_worker_error(&worker));  

              exit(1);

        }          

     while(!b_exit) {               

                    ret= gearman_worker_work(&worker);    

                    if (ret == GEARMAN_TIMEOUT) {            

                           printf("%s", "Worker timeout.");     \

                   } else if (ret != GEARMAN_SUCCESS) { 

                         printf("%s,%d", "Worker ret != GEARMAN_SUCCESS", ret); 

                   }   

                usleep(1);  

      }      

     gearman_worker_free(&worker);  

 

exit(1);

}


回调handler_worker例如:

其中char* pworkload即为得到的队列中的数据,你可以处理这个数据了,我这里把接收到的数据分割后使用for_each函数来调用proc_func分别处理分割后的数据

static void *handler_work(gearman_job_st *job, void *cb_arg, size_t *result_size, gearman_return_t *ret_ptr) {

        const char *workload = NULL;
        size_t workload_size = 0;

        workload= (char*)gearman_job_workload(job);
        workload_size= gearman_job_workload_size(job);
        std::string str_workload(workload, workload_size);
        char* pworkload = &str_workload[0];
        std::vector<std::string> svec;
        if ("" != str_workload ) {
                boost::split( svec, pworkload, boost::is_any_of( "\n" ), boost::token_compress_on );
                for_each(svec.begin(), svec.end(), proc_func);
        } else {
                ;
        }
        svec.clear();

        *result_size= 0;
        *ret_ptr= GEARMAN_SUCCESS;
        return NULL;
}


好了,到这里client和worker都可以使用了,可以多个机器上部署处理速度还是可以的,毕竟可以分布式来处理,



当这个服务部署完成后怎么用命令来查看队列是否正常,队列中是否有数据正在处理呢

可以使用如下命令查看:

例如我在本机上看4730端口队列是否正常,


$ (echo status; sleep 0.1) | nc 127.0.0.1 4730
analysis    0    0    1
do_task    72    1    1
.

这里我有两个队列名字analysis和do_task

可以看到do_task中正有72个等待处理

另外

›status
›五列数据,分别为name, 队列中job数量, job 正处理的数量, worker正处理数量, queue长度


待续




研发项目经理需要具备的7大核心素质特征

项目管理能力素质标准包含7项核心素质:客户服务精神、影响力、合作精神、领导能力、成就导向、关注次序质量和准确性、逻辑思维能力。对照评价标准,项目经理可以自评项目管理水平。 项目经理级别 核心内...
  • sztiger168
  • sztiger168
  • 2013年07月17日 07:07
  • 1786

服务端研发应具备的技能(4)

2,数据传输 2.1  gearman 2.2 RPC 先插一下百度百科内容: RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远...
  • timegoesby001
  • timegoesby001
  • 2013年12月02日 11:45
  • 655

服务端研发应具备的技能(2)

1,日志处理 通常我们处理文件,大多数都是处理完即程序退出,但在IT行业里,尤其是互联网公司,日志不是一时性的,而是源源不断的一直生成中,所以要求你的程序也需要像linux 下的tail -f命令...
  • timegoesby001
  • timegoesby001
  • 2013年11月29日 17:10
  • 692

优秀的架构师应该具备哪些能力

合格的运营式运维工程师 首先我们总结下,关于谈到何为一名合格的运维运营工程师,大概就是几点: 具备一定运营技能;要有运营意识;主动性要强;学习能力要跟得上。 大家都会发现...
  • liu136313
  • liu136313
  • 2016年01月03日 21:13
  • 1657

C++服务器端开发技能

Linux C++服务器端开发技术   1、基本知识:掌握C/C++语法,熟悉STL标准库、ACE库、Boost库。 2、应用技能:多线程编程、网络编程、Oralce数据库、内存管理、正则表达式。...
  • fuyuehua22
  • fuyuehua22
  • 2014年02月17日 15:31
  • 4790

一个优秀的程序员应该具备哪些技能和修养?

李运华:这个问题就像“1千个人眼中有1千个哈姆雷特”一样,每个人都有不同的看法。我认为一个优秀的程序员应该具备如下技能和修养: 首先是“快速学习能力”。这里不是说一定要去快速去学习各种各样的新技术,...
  • kpchen_0508
  • kpchen_0508
  • 2014年11月01日 14:31
  • 1275

一名合格的web前端工程师需要哪些技能?

我们都知道,所有呈现的内容都是基于HTML 网页的。 如果你的html、css(包括现在的HTML5+CSS3)基础不会,或者不够扎实,都很难在有大的进步,或者你的JS 很好,但布局基础不行,还...
  • w3cschoolcn
  • w3cschoolcn
  • 2016年08月19日 18:15
  • 2658

项目经理需要具备四种基本素质及八大管理技能

项目经理需要具备四种基本素质及八大管理技能。 ●四种素质  1.品德素质。项目经理对外与供应商、客户打交道,对内需要跨部门整合资源,诚信的品德素质是基础。  2.能力素质。项目经理需...
  • wxlinwzl
  • wxlinwzl
  • 2015年11月28日 11:58
  • 4134

合格程序员应该具备的12种能力

毕业四年来,感觉自己也是从一名不合格的程序员一步步走过来的。回头反思一下,合格的程序员有很多标准和要求,下面是我总结的一个合格程序员应该具备的 12种能力。中国软件行业的崛起,靠的是合格的程序员。任何...
  • u011075946
  • u011075946
  • 2014年10月17日 09:48
  • 1713

优秀的Java工程师需要掌握的10项技能

转载IT学生网 ★www.itxsw.com★ 编程专业相对于计算机领域其他专业来讲,是一门比较难以修炼的专业,此专业如果想要大成,需要修行之人心性极佳,踏踏实实,耐得住寂寞,受得住冷落。所以...
  • u010582345
  • u010582345
  • 2016年03月10日 20:04
  • 1518
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:服务端研发应具备的技能(3)
举报原因:
原因补充:

(最多只允许输入30个字)