Swoft 2.0.3 Major Update Releases Elegant Microservice Governance

  Doophp, Microservices, php

图片描述

What is Swoft?

SwoftIt is based onSwooleThe PHP microservice coordination framework implemented by extension. Swoft, like Go, has built-in coordination network server and common coordination clients and memory resident, and does not rely on traditional PHP-FPM. There are synergetic operation modes similar to Go language, flexible annotations similar to Spring Cloud framework, powerful global dependency injection container, perfect service governance, flexible and powerful AOP, standard PSR specification implementation, etc.

After three years of accumulation and exploration, Swoft has become the Spring Cloud in PHP. It is the best choice for PHP’s high-performance framework and micro-service governance.

Elegant Service Governance

Swoft officially recommends developers to use Service mesh mode, such as Istio/Envoy framework, to separate business and service governance, but Swoft also provides a set of microservice components for small and medium-sized enterprises to quickly build microservices.

Service Registration and Discovery

Service registration and discovery need to be provided by Swoftswoft-consulComponent, if other third parties are similar.

Registration and cancellation services

MonitorSwooleEvent::STARTEvents, Registration Services

/**
 * Class RegisterServiceListener
 *
 * @since 2.0
 *
 * @Listener(event=SwooleEvent::START)
 */
class RegisterServiceListener implements EventHandlerInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param EventInterface $event
     */
    public function handle(EventInterface $event): void
    {
        /* @var HttpServer $httpServer */
        $httpServer = $event->getTarget();

        $service = [
            // ....
        ];

        $scheduler = Swoole\Coroutine\Scheduler();
        $scheduler->add(function () use ($service) {
            // Register
            $this->agent->registerService($service);
            CLog::info('Swoft http register service success by consul!');
        });
        $scheduler->start();
    }
}

MonitorSwooleEvent::SHUTDOWNEvent, cancel service

/**
 * Class DeregisterServiceListener
 *
 * @since 2.0
 *
 * @Listener(SwooleEvent::SHUTDOWN)
 */
class DeregisterServiceListener implements EventHandlerInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param EventInterface $event
     */
    public function handle(EventInterface $event): void
    {
        /* @var HttpServer $httpServer */
        $httpServer = $event->getTarget();

        $scheduler = Swoole\Coroutine\Scheduler();
        $scheduler->add(function () use ($httpServer) {
            $this->agent->deregisterService('swoft');
        });
        $scheduler->start();
    }
}    

Service discovery

Define service providers

/**
 * Class RpcProvider
 *
 * @since 2.0
 *        
 * @Bean()
 */
class RpcProvider implements ProviderInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param Client $client
     *
     * @return array
     * @example
     * [
     *     'host:port'
     * ]
     */
    public function getList(Client $client): array
    {
        // Get health service from consul
        $services = $this->agent->services();

        $services = [

        ];

        return $services;
    }
}

Configure service providers

return [
    'user'           => [
      'class'   => ServiceClient::class,
      'provider' => bean(RpcProvider::class)
      // ...
    ]
];

Service fuse

Swoft usage@BreakerAnnotation to realize fusing, can be inAny methodThe fuse operation is carried out above.

/**
 * Class BreakerLogic
 *
 * @since 2.0
 *
 * @Bean()
 */
class BreakerLogic
{
    /**
     * @Breaker(fallback="funcFallback")
     *
     * @return string
     * @throws Exception
     */
    public function func(): string
    {
        // Do something

        throw new Exception('Breaker exception');
    }
    
    /**
     * @return string
     */
    public function funcFallback(): string
    {
        return 'funcFallback';
    }
}

Service flow restriction

Swoft@RateLimiterRemark to realize service flow restriction, can be inAny methodThe above current limit is not only a controller, but also supported by KEYsymfony/expression-languageExpression.

/**
 * Class LimiterController
 *
 * @since 2.0
 *
 * @Controller(prefix="limiter")
 */
class LimiterController
{
    /**
     * @RequestMapping()
     * @RateLimiter(key="request.getUriPath()", fallback="limiterFallback")
     *
     * @param Request $request
     *
     * @return array
     */
    public function requestLimiter(Request $request): array
    {
        $uri = $request->getUriPath();
        return ['requestLimiter', $uri];
    }

    /**
     * @param Request $request
     *
     * @return array
     */
    public function limiterFallback(Request $request): array
    {
        $uri = $request->getUriPath();
        return ['limiterFallback', $uri];
    }
}

Configuration center

Configuration center, need to use Swoft officially providedSwoft-apolloComponent, if other third parties are similar.

Declare Agent

/**
 * Class AgentCommand
 *
 * @since 2.0
 *
 * @Command("agent")
 */
class AgentCommand
{
    /**
     * @Inject()
     *
     * @var Config
     */
    private $config;

    /**
     * @CommandMapping(name="index")
     */
    public function index(): void
    {
        $namespaces = [
            'application'
        ];

        while (true) {
            try {
                $this->config->listen($namespaces, [$this, 'updateConfigFile']);
            } catch (Throwable $e) {
                CLog::error('Config agent fail(%s %s %d)!', $e->getMessage(), $e->getFile(), $e->getLine());
            }
        }
    }

    /**
     * @param array $data
     *
     * @throws ContainerException
     * @throws ReflectionException
     */
    public function updateConfigFile(array $data): void
    {
        foreach ($data as $namespace => $namespaceData) {
            $configFile = sprintf('@config/%s.php', $namespace);

            $configKVs = $namespaceData['configurations'] ?? '';
            $content   = '<?php return ' . var_export($configKVs, true) . ';';
            Co::writeFile(alias($configFile), $content, FILE_NO_DEFAULT_CONTEXT);

            CLog::info('Apollo update success!');

            /** @var HttpServer $server */
            $server = bean('httpServer');
            $server->restart();
        }
    }
}

Start Agent

The Agent only needs to run before the service (Http/RPC/Websocket) starts.

php bin/swoft agent:index

Update content

Remove

  • removerequest->json()Method (c9e8f04)

New:

  • New Interface Dependency Injection (6169f84)
  • NewgetFileMethod to obtain the information after the file is uploaded and saved (fe7e3a6)
  • Newrestart()New restart method for service (2ffec37)
  • New call to 1.x RPC service support (30d73c3)
  • New AOP Class Name Matching Supports Regular Expressions (bc5e479)
  • Add RPC Server /Http Server middleware namespaceuseError prompt (b1cec04)
  • Add Validator Exclusion Attribute Fieldsunfields(b1bf44f)
  • Add an automatic write timestamp (dc58011)
  • Add model action events (dc58011)
  • New database migration (26bb464)
  • The newly added entity automatically alternates with json and arrays (dc58011)
  • New Model Batch Updating MethodbatchUpdateByIds(dc58011)

Fixed:

  • Fix some problems in cookies setting and add some withCookie related methods (b05afbb01)
  • Fixes when console runs commands in coordinated mode without capturing processing errors (8a5418bf)
  • Fixing a websocket server restart command did not stop the old server problem (db2d935)
  • The return value of the repair task isnullQuestion (a69347c)
  • Fix the problem that RPC Server cannot be used only by class middleware ()204bc7f
  • Repair RPC Server returned the valuenullQuestion (4d091be)
  • Fixing Logger and CLog Log Levels Fail to Overwrite and Invalid Issues (8eb8aba)
  • Custom expressions (dc58011)

Update:

  • Validator optimization to support custom validation rules (d959a4f)
  • Rename Error Handling Management ClassErrorHanldersForErrorManager(f3a8f04b)
  • The exception handling of console component is changed to the unified handling style provided by error component (4f47204)
  • The console component allows setting disable command groups (c5a0269)
  • In the default error handling, it is allowed to set the error capture level. The default level isE_ALL | E_STRICT(afff9029)
  • Http processing is also enabled when the ws server is optimally started. the information panel adds a prompt (83a81170)
  • Optimize startup of ws server and add rpc server startup at the same time. The information panel does not display rpc server information (3d1d0d848)

Extra:

  • Document addition supports searching through google
  • Add apollo component
  • Add consul Components
  • Add breaker Assembly
  • Add limter components

Resources