(4). 在网关中增加解析consul_tag限流参数:
app\Lib\ServiceHelper.php
class ServiceHelper{
...
// 解析tags
public function parseTags(array $service): array
{
if (empty($service) || !is_array($service) || empty($service['Tags'])) {
return [];
}
$result = [];
foreach ($service['Tags'] as $v) {
// 二段式解析,如:gw.NAMESPACE=App.Rpc.Lib
if (preg_match("/^gw\.(\w+)=(.*)/i", $v, $matches)) {
$result[$matches[1]] = str_replace('.', '\\', $matches[2]);
continue; // 不加,还会去扫下面
}
// 三段式解析,如:gw.rateLimiter.key=order
// ['rateLimiter' => ['key' => 'xx', 'rate' => 0, 'max' => 0]]
if (preg_match("/^gw\.(\w+).(\w+)=(.*)/i", $v, $matches)) {
if (!isset($result[$matches[1]])) {
$result[$matches[1]] = [];
}
$result[$matches[1]][$matches[2]] = $matches[3];
}
}
return $result;
}
}
(5). 增加网关主类限流功能:
app\Http\main.php:
namespace App\Http;
use App\Lib\CustomizeRateLimiter;
use App\Lib\EnvConfig;
use App\Lib\ServiceHelper;
use App\Lib\ServiceSelector;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Bean\BeanFactory;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;
/**
* @Controller()
*/
class main {
/**
* @Inject()
* @var EnvConfig
*/
protected $envConfig = null;
/**
* @Inject()
* @var ServiceHelper
*/
protected $servicHelper;
/**
* @Inject()
* @var ServiceSelector
*/
private $selector;
/**
* @RequestMapping("/{prefix}/{service}/{method}", method={RequestMethod::POST, RequestMethod::OPTIONS})
*/
public function test(string $prefix, string $service, string $method)
{
$param = jsonParams(); // 获取请求json参数,返回一个数组
try {
$serviceList = $this->servicHelper->getService($this->envConfig->getServicePrefix() . "." . $prefix);
$getService = $this->selector->selectByRoundRobin($serviceList);
$host = "tcp://" . $getService['Address'] . ':' . $getService['Port'];
$tags = $this->servicHelper->parseTags($getService);
// RPC目标调用方法
$callRpc = function () use ($host, $tags, $service, $method, $param){
return requestRPC($host, choose($tags['NAMESPACE'], $this->envConfig->getNamespace()) . "\\". $service, $method, $param);
};
// 如果设置了限流,就执行限流函数,否则直接执行RPC目标调用
if (!empty($tags['rateLimiter'])) {
/**
* 下面方法没有提示,加这句
* @var CustomizeRateLimiter $rateLimiter
*/
$rateLimiter = BeanFactory::getBean("CustomizeRateLimiter");
// 传前面两个参数的作用,主要是做日志记录
$result = $rateLimiter->checkRate($service, $method, $callRpc, $tags['rateLimiter']);
} else {
$result = $callRpc();
}
} catch (\Exception $e) {
$result = ["error" => $e->getMessage()];
}
return $result;
}
}
(6). 请求:
多次请求网关时,会出现降级函数处理.