前言
一个项目,从开始到版本更新,一直到最后的版本维护。功能在不断增多,对应的代码量也在不断增加,也就意味着项目变得更不可维护,这时候,我们需要用拆分的方式将一个项目打散,以便开发团队更好的对项目进行维护。
分模块
这个阶段,一般也是项目的初级阶段,由于人手不够,一个服务端的接口项目只有一个开发进行维护,根据开发的习惯,会把项目分成若干个模块进行开发,在一个项目下进行部署。
这样做的缺点在于项目会随着版本更新而变得不可维护。
分项目
随着每个模块功能的不断完善,代码变得更加臃肿。这时候需要对项目进行拆分,比如上面的图,分成用户体系项目、支付体系项目。
CURL
开始大家会采用CURL的方式对外部资源进行访问。
比如某短信平台SDK,比如各大第三方提供的SDK,纠结到源码发现都是直接采用CURL函数的方式进行访问。
优点在于没有环境要求,能直接用。
缺点在于并发访问的资源占用问题。
//新浪微博SDK的http请求部分源码
/**
* Make an HTTP request
*
* @return string API results
* @ignore
*/
function http($url, $method, $postfields = NULL, $headers = array()) {
$this->http_info = array();
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ci, CURLOPT_ENCODING, "");
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
if (version_compare(phpversion(), '5.4.0', '<')) {
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 1);
} else {
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 2);
}
curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
curl_setopt($ci, CURLOPT_HEADER, FALSE);
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
$this->postdata = $postfields;
}
break;
case 'DELETE':
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($postfields)) {
$url = "{$url}?{$postfields}";
}
} if ( isset($this->access_token) && $this->access_token )
$headers[] = "Authorization: OAuth2 ".$this->access_token;
if ( !empty($this->remote_ip) ) {
if ( defined('SAE_ACCESSKEY') ) {
$headers[] = "SaeRemoteIP: " . $this->remote_ip;
} else {
$headers[] = "API-RemoteIP: " . $this->remote_ip;
}
} else {
if ( !defined('SAE_ACCESSKEY') ) {//
$headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
}
}
curl_setopt($ci, CURLOPT_URL, $url );
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers );
curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE );
$response = curl_exec($ci);
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
$this->url = $url;
if ($this->debug) {
echo "=====post data======\r\n";
var_dump($postfields);
echo "=====headers======\r\n";
print_r($headers);
echo '=====request info====='."\r\n";
print_r( curl_getinfo($ci) );
echo '=====response====='."\r\n";
print_r( $response );
}
curl_close ($ci);
return $response;
}
RPC
远程过程调用协议
Yar
鸟哥出品的RPC框架,轻量级框架。
<?phpclass API { /** * the doc info will be generated automatically into service info page. * @params * @return */ public function api($parameter, $option = "foo") { } protected function client_can_not_see() { } }$service = new Yar_Server(new API());$service->handle();?>
调用代码
注意的是鸟哥出的东西文档比较少,需要多调试。
Thrift
远程调用的意义在于,不同的子项目可以用更适合自己的语言来解决,更有效率的实现需求。
同时,对团队的开发来讲,更能提高整体的技术水平。
SOAP
由于用的XML就不多描述了,毕竟还是json用的多。
JSON-RPC
下面是返回值的标准
实际上你会发现我们在给客户端提供接口的返回值,就是按照这个标准来做的。
相应的,服务端对服务端的数据接收和返回,也要同样按照这个标准来做。
项目拆分带来的变化
项目细化
一个模块对应一个项目,项目之间通过基于REST的接口标准进行面向资源的数据访问。
人员需求
项目拆分的前提是一个项目不足以满足现有的业务发展要求,也就意味着拆分之后的开发人员数量的扩增。
游击队向正规军编制的跨越!
文档
更多的项目也就意味着更多的接口调用文档,适当的处理文档才能更好的提高团队协作效率。
后记
服务的远程调用在于怎么合理的把一个正在变得不可维护的项目从焦油坑中解救出来,并提高项目整体能承载的业务量,不过,世界上没有银弹。