swoft微服务实战三十三:增加网关主类限流功能

文章讲述了如何在网关服务中增加对Consul_tag的解析,以便支持限流功能。ServiceHelper类用于解析tags,而main类则集成限流逻辑,使用CustomizeRateLimiter进行调用控制。当请求增多时,会触发降级处理策略。
摘要由CSDN通过智能技术生成

(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). 请求:
多次请求网关时,会出现降级函数处理.

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值