Swoft 2.0.3 重大更新,发布优雅的微服务治理

Posted Swoft 开源框架

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swoft 2.0.3 重大更新,发布优雅的微服务治理相关的知识,希望对你有一定的参考价值。

什么是 Swoft ?

Swoft 是一款基于 Swoole 扩展实现的 php 微服务协程框架。Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传统的 PHP-FPM。有类似 Go 语言的协程操作方式,有类似 Spring Cloud 框架灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等。

Swoft 通过长达三年的积累和方向的探索,把 Swoft 打造成 PHP 界的 Spring Cloud, 它是 PHP 高性能框架和微服务治理的最佳选择。

优雅的服务治理

Swoft 官方建议开发者使用 Service mesh 模式,比如 Istio/Envoy 框架,把业务和服务治理分开,但是 Swoft 也为中小型企业快速构建微服务提供了一套微服务组件。

  • 服务注册与发现

  • 服务熔断

  • 服务限流

  • 配置中心

服务注册与发现

服务注册与发现,需要用到 Swoft 官方提供的 swoft-consul 组件,如果其它第三方也类似。

注册与取消服务

监听 SwooleEvent::START 事件,注册服务

 
   
   
 
  1. /**

  2. * Class RegisterServiceListener

  3. *

  4. * @since 2.0

  5. *

  6. * @Listener(event=SwooleEvent::START)

  7. */

  8. class RegisterServiceListener implements EventHandlerInterface

  9. {

  10. /**

  11. * @Inject()

  12. *

  13. * @var Agent

  14. */

  15. private $agent;


  16. /**

  17. * @param EventInterface $event

  18. */

  19. public function handle(EventInterface $event): void

  20. {

  21. /* @var HttpServer $httpServer */

  22. $httpServer = $event->getTarget();


  23. $service = [

  24. // ....

  25. ];


  26. $scheduler = Swoole\Coroutine\Scheduler();

  27. $scheduler->add(function () use ($service) {

  28. // Register

  29. $this->agent->registerService($service);

  30. CLog::info('Swoft http register service success by consul!');

  31. });

  32. $scheduler->start();

  33. }

  34. }

监听 SwooleEvent::SHUTDOWN 事件,取消服务

 
   
   
 
  1. /**

  2. * Class DeregisterServiceListener

  3. *

  4. * @since 2.0

  5. *

  6. * @Listener(SwooleEvent::SHUTDOWN)

  7. */

  8. class DeregisterServiceListener implements EventHandlerInterface

  9. {

  10. /**

  11. * @Inject()

  12. *

  13. * @var Agent

  14. */

  15. private $agent;


  16. /**

  17. * @param EventInterface $event

  18. */

  19. public function handle(EventInterface $event): void

  20. {

  21. /* @var HttpServer $httpServer */

  22. $httpServer = $event->getTarget();


  23. $scheduler = Swoole\Coroutine\Scheduler();

  24. $scheduler->add(function () use ($httpServer) {

  25. $this->agent->deregisterService('swoft');

  26. });

  27. $scheduler->start();

  28. }

  29. }

服务发现

定义服务提供者

 
   
   
 
  1. /**

  2. * Class RpcProvider

  3. *

  4. * @since 2.0

  5. *

  6. * @Bean()

  7. */

  8. class RpcProvider implements ProviderInterface

  9. {

  10. /**

  11. * @Inject()

  12. *

  13. * @var Agent

  14. */

  15. private $agent;


  16. /**

  17. * @param Client $client

  18. *

  19. * @return array

  20. * @example

  21. * [

  22. * 'host:port'

  23. * ]

  24. */

  25. public function getList(Client $client): array

  26. {

  27. // Get health service from consul

  28. $services = $this->agent->services();


  29. $services = [


  30. ];


  31. return $services;

  32. }

  33. }

配置服务提供者

 
   
   
 
  1. return [

  2. 'user' => [

  3. 'class' => ServiceClient::class,

  4. 'provider' => bean(RpcProvider::class)

  5. // ...

  6. ]

  7. ];

服务熔断

Swoft 使用 @Breaker 注解实现熔断,可以在任何方法上面进行熔断操作。

 
   
   
 
  1. /**

  2. * Class BreakerLogic

  3. *

  4. * @since 2.0

  5. *

  6. * @Bean()

  7. */

  8. class BreakerLogic

  9. {

  10. /**

  11. * @Breaker(fallback="funcFallback")

  12. *

  13. * @return string

  14. * @throws Exception

  15. */

  16. public function func(): string

  17. {

  18. // Do something


  19. throw new Exception('Breaker exception');

  20. }


  21. /**

  22. * @return string

  23. */

  24. public function funcFallback(): string

  25. {

  26. return 'funcFallback';

  27. }

  28. }

服务限流

Swoft 中使用 @RateLimiter 注解实现服务限流,可以在任何方法上面限流,不仅仅是控制器,且 KEY 还支持 symfony/expression-language 表达式。

 
   
   
 
  1. /**

  2. * Class LimiterController

  3. *

  4. * @since 2.0

  5. *

  6. * @Controller(prefix="limiter")

  7. */

  8. class LimiterController

  9. {

  10. /**

  11. * @RequestMapping()

  12. * @RateLimiter(key="request.getUriPath()", fallback="limiterFallback")

  13. *

  14. * @param Request $request

  15. *

  16. * @return array

  17. */

  18. public function requestLimiter(Request $request): array

  19. {

  20. $uri = $request->getUriPath();

  21. return ['requestLimiter', $uri];

  22. }


  23. /**

  24. * @param Request $request

  25. *

  26. * @return array

  27. */

  28. public function limiterFallback(Request $request): array

  29. {

  30. $uri = $request->getUriPath();

  31. return ['limiterFallback', $uri];

  32. }

  33. }

配置中心

配置中心,需要用到 Swoft 官方提供的 Swoft-apollo 组件,如果其它第三方也类似。

声明Agent

 
   
   
 
  1. /**

  2. * Class AgentCommand

  3. *

  4. * @since 2.0

  5. *

  6. * @Command("agent")

  7. */

  8. class AgentCommand

  9. {

  10. /**

  11. * @Inject()

  12. *

  13. * @var Config

  14. */

  15. private $config;


  16. /**

  17. * @CommandMapping(name="index")

  18. */

  19. public function index(): void

  20. {

  21. $namespaces = [

  22. 'application'

  23. ];


  24. while (true) {

  25. try {

  26. $this->config->listen($namespaces, [$this, 'updateConfigFile']);

  27. } catch (Throwable $e) {

  28. CLog::error('Config agent fail(%s %s %d)!', $e->getMessage(), $e->getFile(), $e->getLine());

  29. }

  30. }

  31. }


  32. /**

  33. * @param array $data

  34. *

  35. * @throws ContainerException

  36. * @throws ReflectionException

  37. */

  38. public function updateConfigFile(array $data): void

  39. {

  40. foreach ($data as $namespace => $namespaceData) {

  41. $configFile = sprintf('@config/%s.php', $namespace);


  42. $configKVs = $namespaceData['configurations'] ?? '';

  43. $content = '<?php return ' . var_export($configKVs, true) . ';';

  44. Co::writeFile(alias($configFile), $content, FILE_NO_DEFAULT_CONTEXT);


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


  46. /** @var HttpServer $server */

  47. $server = bean('httpServer');

  48. $server->restart();

  49. }

  50. }

  51. }

启动Agent

Agent 只需要在服务(Http/RPC/Websocket)启动前,运行即可。

 
   
   
 
  1. php bin/swoft agent:index

更新内容

移除(Remove)

  • 移除 request->json() 方法(c9e8f04)

新增(Enhancement):

  • 新增接口依赖注入(6169f84)

  • 新增 getFile 方法获取文件上传保存之后的信息(fe7e3a6)

  • 新增 restart() 服务新增重启方法(2ffec37)

  • 新增调用 1.x RPC 服务支持(30d73c3)

  • 新增 AOP 类名匹配支持正则表达式(bc5e479)

  • 新增 RPC Server /Http Server 中间件命名空间 use 错误提示(b1cec04)

  • 新增 验证器排除属性字段 unfields(b1bf44f)

  • 新增 自动写入时间戳(dc58011)

  • 新增 模型动作事件(dc58011)

  • 新增 数据库迁移(26bb464)

  • 新增 实体自动与 json 和数组互转(dc58011)

  • 新增 模型批量更新方法 batchUpdateByIds(dc58011)

修复(Fixed):

  • 修复 cookies 设置时的一些问题,增加一些 withCookie 相关方法(b05afbb01)

  • 修复 在console使用协程方式运行命令时,没有捕获处理错误(8a5418bf)

  • 修复 websocket server 重启命令没有先停止旧server问题(db2d935)

  • 修复任务返回值为 null 问题(a69347c)

  • 修复 RPC Server 只有类中间件无法使用问题()204bc7f

  • 修复 RPC Server 返回值为 null 问题(4d091be)

  • 修复 Logger 和 CLog 日志等级无法覆盖和无效问题(8eb8aba)

  • 修复 模型里面的属性不支持自定义表达式(dc58011)

更新(Update):

  • 验证器优化,支持自定义验证规则(d959a4f)

  • 重命名错误处理管理类 ErrorHanlders 为 ErrorManager (f3a8f04b)

  • console组件的异常处理改为由error组件提供的统一处理风格 (4f47204)

  • console组件允许设置禁用命令组(c5a0269)

  • 在默认的错误处理中,允许设置错误捕获级别。默认级别是 E_ALL|E_STRICT (afff9029)

  • 优化 启动ws server时同时启用了http处理功能,信息面板添加提示(83a81170)

  • 优化 启动ws server 并同时添加rpc server启动,信息面板没有显示 rpc server信息(3d1d0d848)

扩展(Extra):

  • 文档添加支持通过google进行搜索

  • 新增 apollo 组件

  • 新增 consul 组件

  • 新增 breaker 组件

  • 新增 limter 组件

资源

  • Gitee: https://gitee.com/swoft/swoft

  • GitHub: https://github.com/swoft-cloud/swoft

  • 官网:https://www.swoft.org

  • 文档:https://www.swoft.org/docs

以上是关于Swoft 2.0.3 重大更新,发布优雅的微服务治理的主要内容,如果未能解决你的问题,请参考以下文章

5 月上海源创会,韩天峰解读基于 Swoft 的微服务治理

Swoft Route 路由

为什么Dapr是比SpringCloud和Istio更优雅的微服务框架?

为什么Dapr是比SpringCloud和Istio更优雅的微服务框架?

为什么Dapr是比SpringCloud和Istio更优雅的微服务框架?

基于 Swoft 协程框架的 PHP 微服务治理