近来由于业务量急剧增长,业务种类越来越多,RPC混乱问题就凸现出来.
具体表现是:
a1,a2,a3,a4 为一组服务器,为用户提供A服务.
b1,b2,b3为一组服务器,为用户提供B服务.
c1,c2,c3为一组服务器,为用户提供C服务.
最初各服务器各自服务是不太相关的.随着业务拓展,用户提出新的需求,我们需要
在A服务中调用B组服务器的API接口.
….
最后我们发现这样一个现象:
用户请求a1 提供服务.a1发现他需要知道另一些数据,于是调用b2的rpc服务.但是b2
上这个数据又需要c3的RPC.结果c3又需要a2来提供一些数据….
我们的远程调用调来调去,最后把自己调晕了.
于是我开始考虑一种解决方案。
首先当然是:对远程调用加以控制和规范,避免不必要的远程调用。
接着我注意到,我们利用CURL来通过http通道进行远程调用其实是没必要的。我可以在做远程调用时,走FastCGI协议。
说干就干:
第一步:建立一个fastCGI:spawn-php
- #!/bin/bash
-
- ## ABSOLUTE path to the spawn-fcgi binary
- SPAWNFCGI="/home/y/opt/lighttpd/bin/spawn-fcgi"
-
- ## ABSOLUTE path to the PHP binary
- FCGIPROGRAM="/home/y/opt/php/bin/php-cgi"
-
- ## TCP port to which to bind on localhost
- FCGIPORT="1026"
-
- ## number of PHP children to spawn
- PHP_FCGI_CHILDREN=10
-
- ## maximum number of requests a single PHP process can serve before it is restarted
- PHP_FCGI_MAX_REQUESTS=1000
-
- ## IP addresses from which PHP should access server connections
- FCGI_WEB_SERVER_ADDRS="127.0.0.1,192.168.2.10"
-
- # allowed environment variables, separated by spaces
- ALLOWED_ENV="ORACLE_HOME PATH USER"
-
- ## if this script is run as root, switch to the following user
- USERID=y
- GROUPID=y
-
- ################## no config below this line
-
- if test x$PHP_FCGI_CHILDREN = x; then
- PHP_FCGI_CHILDREN=5
- fi
-
- export PHP_FCGI_MAX_REQUESTS
- export FCGI_WEB_SERVER_ADDRS
-
- ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS"
-
- if test x$UID = x0; then
- EX="$SPAWNFCGI -p $FCGIPORT -f $FCGIPROGRAM -u $USERID -g $GROUPID -C $PHP_FCGI_CHILDREN"
- else
- EX="$SPAWNFCGI -p $FCGIPORT -f $FCGIPROGRAM -C $PHP_FCGI_CHILDREN"
- fi
-
- # copy the allowed environment variables
- E=
-
- for i in $ALLOWED_ENV; do
- E="$E $i=${!i}"
- done
-
- # clean the environment and set up a new one
- env - $E $EX
2.接着我们建立这样的文件:http.txt
- for($i=0;$i<100;$i++)
- {
- echo rand();
- echo '....Scene of shooting at Nebraska shopping centre
- Eight killed in Nebraska shooting
- A gunman opens fire in a shopping centre in the US state of Nebraska, killing at least eight people.
- Scene of shooting at Nebraska shopping centre
- Eight killed in Nebraska shooting
- A gunman opens fire in a shopping centre in the US state of Nebraska, killing at least eight people.
- Scene of shooting at Nebraska shopping centre
- Eight killed in Nebraska shooting
- A gunman opens fire in a shopping centre in the US state of Nebraska, killing at least eight people.
- Scene of shooting at Nebraska shopping centre
- Eight killed in Nebraska shooting
- A gunman opens fire in a shopping centre in the US state of Nebraska, killing at least eight people.
- ';
- }
- print "done!";
这个做为是远程接口。
3.下面比较CURL和fastCGI两种访问remote API的方式:
A:走FastCGI:
- include "./mod_fcgi.php";
- $fcgi=new mod_fcgi();
- $args="127.0.0.1:1026";
- $filename="/home/y/www/qps/http.php";
- $fcgi->parser_open($args,$filename,$rq_err,$cgi_headers);
- print($fcgi->parsed_output);
- echo "\n=============\n";
B:走CURL通道:
- include "./curl.php";
- $curl=& new CURL();
- echo $curl->get("http://localhost/qps/http.php");
- echo "\n=============\n";
4我们比较FCGI方式和CURL方式的差异:
FCGI方式进行远程调用的QPS:
- Total transferred: 249306 bytes
- HTML transferred: 244410 bytes
- Requests per second: 275.77 [#/sec] (mean)
- Time per request: 3.626 [ms] (mean)
- Time per request: 3.626 [ms] (mean, across all concurrent requests)
- Transfer rate: 2233.76 [Kbytes/sec] received
HTTP通道进行远程调用的QPS:
- Total transferred: 2244515 bytes
- HTML transferred: 2240015 bytes
- Requests per second: 204.18 [#/sec] (mean)
- Time per request: 4.898 [ms] (mean)
- Time per request: 4.898 [ms] (mean, across all concurrent requests)
- Transfer rate: 14911.66 [Kbytes/sec] received
经过多次比较,确认用fastCGI通道时,效率比http方式要高。
但是….这个差别并不大,而且,使用lighttpd的spawn-cgi来充当fastcgi的守护进程,还不是特别稳定。
另外,经过我的测试,只有当远程调用的结果有较多的输出时,FastCGI协议与HTTP协议相比才有优势。在通过网络传输的数据不多的情况下(就是http.php几乎没有输出的情况下),用CURL来调远端调用,反而比FastCGI方式慢(显而易见,mod_fcgi是自行封装的用PHP的socket函数来进行网络操作的class,而Curl是一个编译了的php扩展).
因此,我忙活了半天,最后得出的结论是,目前还不能在公司大规模加以运用。
但是对于小型企业,创业型公司来说,这种效率对比还是很有用的,可以加以挖掘。
Tag:
相关文章