什么是 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 事件,注册服务

/**
* 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();
}
}

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

/**
* 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();
}
}

服务发现

定义服务提供者

/**
* 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;
}
}

配置服务提供者

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

服务熔断

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

/**
* 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';
}
}

服务限流

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

/**
* 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];
}
}

配置中心

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

声明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();
}
}
}

启动Agent

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

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 组件

资源

Swoft 2.0.3 重大更新,发布优雅的微服务治理的更多相关文章

  1. 【版本发布】JAVA微服务开发框架,Jeecg-P3 1.0.0 重构版本发布

    1.项目介绍 Jeecg-P3是一个微服务框架,采用插件式模式开发:业务插件以JAR方式提供,松耦合可插拔支持独立部署,也可无缝集成Jeecg平台中,目前jeecg已经提供了在线聊天,我的邮箱等一系列 ...

  2. centos7下docker发布第一个微服务应用(Eureka)

    1.在windows下打包 微服务应用通过maven进行打包,在项目的pom.xml执行mvn clean package,或者直接通过idea或者eclipse进行maven打包 之上操作将在项目的 ...

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

    Dapr 是微软主导的云原生开源项目,2019年10月首次发布,到正式发布 V1.0 版本的不到一年的时间内,github star 数达到了 1.2万(现在已经超过1.7万星),超过同期的 kube ...

  4. Spring Cloud分区发布实践(2) 微服务

    我们准备一下用于查询姓名的微服务. 首先定义一下服务的接口, 新建一个空的Maven模块hello-remotename-core, 里面新建一个类: public interface RemoteN ...

  5. AspNet Core Api Restful +Swagger 发布IIS 实现微服务之旅 (二)

    上一步我们创建好CoreApi 接下来在框架中加入 Swagger  并发布  到 IIS (1)首先点击依赖项>管理Nuget包 (2)输入 Swashbuckle.aspnetCore  比 ...

  6. Swoft 2.0.5 更新,新增高效秒级定时任务、异常管理组件

    什么是 Swoft ? Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架.Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传统的 PHP-F ...

  7. 开源微信管家平台——JeeWx 捷微4.0 微服务版本发布,全新架构,全新UI,提供强大的图文编辑器

    JeeWx捷微4.0   微服务版本发布^_^ 换代产品(全新架构,全新UI,提供强大的图文编辑器) JEEWX 从4.0版本开始,技术架构全新换代,采用微服务架构,插件式开发,每个业务模块都是独立的 ...

  8. SpringCloud微服务如何优雅停机及源码分析

    目录 方式一:kill -9 java进程id[不建议] 方式二:kill -15 java进程id 或 直接使用/shutdown 端点[不建议] kill 与/shutdown 的含义 Sprin ...

  9. JAVA版本微信管家平台—JeeWx 捷微 4.1 微服务版本发布,微信砍价活动闪亮登场!

    捷微 4.1   微服务版本发布,微信砍价活动闪亮登场 ^_^ JEEWX 从4.0版本开始,技术架构全新换代更名 “捷微H5”.这是一款开源免费的微信运营平台,是jeewx的新一代产品,平台涵盖了: ...

随机推荐

  1. C++cctype软件包函数摆脱,ASCII码!

    对于字符,你是否还在用ASCII码? 下面是C++的函数库,摆脱ASCI码! 1.isalnum(): 判断是否为数字和字母 2.isalpha(): 判断是否是字母 3.iscntrl(): 判断是 ...

  2. Palindrome Degree(CodeForces 7D)—— hash求回文

    学了kmp之后又学了hash来搞字符串.这东西很巧妙,且听娓娓道来. 这题的题意是:一个字符串如果是回文的,那么k值加1,如果前一半的串也是回文,k值再加1,以此类推,算出其k值.打个比方abaaba ...

  3. java中判断空字符串和null的判断方法

    简单总结几个方法: 1.直观的: if(s == null ||"".equals(s)); //先判断是否对象,再判断是否是空字符串 2.比较字符串长度, 效率高, 比较绕: i ...

  4. SQL和HQL 区别浅析!!!

    hql是面向对象查询,格式:from + 类名 + 类对象 + where + 对象的属性 sql是面向数据库表查询,格式:from + 表名 + where + 表中字段 1.查询 一般在hiber ...

  5. 20.包含min函数的栈 Java

    题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 思路 借助辅助栈实现: 压栈时:若辅助栈为空,则将节点压入辅助栈.否则,当当前节点小于 ...

  6. LeetCode 无重复字符的最长子串(探索字节跳动)

    题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "a ...

  7. 图解Python 【第五篇】:面向对象-类-初级基础篇

    由于类的内容比较多,分为类-初级基础篇和类-进阶篇 类的内容总览图: 本节主要讲基础和面向对象的特性 本节内容一览图: 前言总结介绍: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 ...

  8. Spring对象依赖关系

    Spring中,如何给对象的属性赋值?  [DI, 依赖注入] 1) 通过构造函数 2) 通过set方法给属性注入值 3) p名称空间   4)自动装配(了解) 5) 注解 package loade ...

  9. PhoneUtils

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class PhoneUtils { /** * @par ...

  10. 008-ICMP协议(网络控制文协议)

    一.概述 ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议簇的一个子协议,用于在IP主机.路由器之间传递控制消息.控制 ...