blob: 021cff757914b056c58a7a5a9940ea89932f6fe7 [file] [log] [blame]
<?php
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace com\fenqile\fsof\consumer\proxy;
use com\fenqile\fsof\common\protocol\fsof\DubboRequest;
use com\fenqile\fsof\consumer\fsof\FSOFProcessor;
use com\fenqile\fsof\consumer\Type;
final class Proxy
{
private $appName;
private $group;
private $serviceInterface;
private $serviceAddress = array();
private $fsofProcessor;
//默认超时时间为3s
private $ioTimeOut = 3;
private $logger;
public static function newProxyInstance($serviceInterfaces, $appName, $group)
{
return new Proxy($serviceInterfaces, $appName, $group);
}
public function __construct($serviceInterfaces, $appName, $group)
{
$this->logger = \Logger::getLogger(__CLASS__);
$this->serviceInterface = $serviceInterfaces;
$this->appName = $appName;
$this->group = $group;
$this->fsofProcessor = new FSOFProcessor();
}
public function setIOTimeOut($ioTimeOut)
{
$this->ioTimeOut = $ioTimeOut;
}
public function setAddress($serviceAddr = array())
{
//删除旧的地址
unset($this->serviceAddress);
$this->serviceAddress = $serviceAddr;
}
public function getAddressStr()
{
$ret = "";
foreach ($this->serviceAddress as $index => $url)
{
$ret .= $url->getHost().':'.$url->getPort().';';
}
return $ret;
}
protected function generatePackageSN()
{
srand((double)microtime() * 1000000);
$rand_number = rand();
return $rand_number;
}
protected function generateParamType($args)
{
foreach ($args as $val) {
if($val instanceof \stdClass){
$types[] = $val->class;
}else{
$types[] = Type::adapter[$val->type]??'Ljava/lang/Object;';
}
}
return $types;
}
protected function trimParams($params)
{
if(count($params) == 1 && empty($params[0]))
{
return null;
}
return $params;
}
public function __call($name, $args)
{
$result = NULL;
$method = null;
$providerAddress = NULL;
$request = new DubboRequest();
//取到微秒
$begin_time = microtime(true);
$this->logger->debug("in|consumer_app:{$this->appName}|service:{$this->serviceInterface}|timout:{$this->ioTimeOut}|name:{$name}");
try {
$request->setSn($this->generatePackageSN());
$request->setService($this->serviceInterface);
$request->setMethod($args[0]);
array_shift($args);
$request->setParams($args);
$request->setTypes($this->generateParamType($request->getParams()));
$result = $this->fsofProcessor->executeRequest($request, $this->serviceAddress, $this->ioTimeOut, $providerAddress);
}catch (\Exception $e) {
$cost_time = (int)((microtime(true) - $begin_time) * 1000000);
//记录consumer接口告警日志
$this->setAccLog($request, $cost_time, $e->getMessage());
throw $e;
}
$cost_time = (int)((microtime(true) - $begin_time) * 1000000);
//记录consumer接口告警日志
$this->setAccLog($request, $cost_time, "ok");
return $result;
}
protected function setAccLog($request, $costTime, $errMsg='ok')
{
//时间|服务名|耗时(us)|返回码|应用名|方法名|目标服务group|目标服务version|目标机器ip:port|备注
$accLog = sprintf("%s|%d|%d|%s|%s|%s|%s|%s", $request->getService(), $costTime,
$this->appName,
$request->getMethod(),
$request->getGroup(),
$request->getVersion(),
$request->host . ':' . $request->port,
$errMsg);
$this->logger->debug($accLog);
}
}