Below you will find pages that utilize the taxonomy term “Hyperf”
Posts
Socket.io Server For Hyperf
有小伙伴抱怨道,WebSocket Server感觉太原始,没有“框架感”。希望Socket.io协议的支持,可以让WebSocket更好用,不再有开篇提到的困惑。
Posts
使用Hyperf插入100万行数据到MongoDB,能行吗
最近用go搞了一个swoole的边车。是真的边车,用swoole process启动的。挂载到swoole server上跑,swoole起它起,swoole停它停,中间如果go挂了swoole还负责给拉起来。消息投递也照搬swoole task走IPC,从web worker上直接投递,等结果出来再返还web worker。
Posts
云原生Hyperf骨架包
2020-01-22 日更新:现已提供Hyperf Helm chart。详见repo。
Hyperf官方提供了容器镜像,配置选项又非常开放,将Hyperf部署于云端本身并不复杂。下面我们以Kubernetes为例,对Hyperf默认的骨架包进行一些改造,使它可以优雅的运行于Kubernetes上。本文不是Kubernetes的入门介绍,需要读者已经对Kubernetes有一定了解。
生命周期 容器在Kubernetes上启动以后,Kubernetes会对容器进行两项检查: Liveness Probe和Readiness Probe。Liveness Probe如果没有通过,容器会被重启,而Readiness Probe没有通过,则会暂时将服务从发现列表中移除。当Hyperf作为HTTP Web server启动时,我们只需要添加两条路由就行了。
<?php namespace App\Controller; class HealthCheckController extends AbstractController { public function liveness() { return 'ok'; } public function readiness() { return 'ok'; } } <?php // in config/Routes.php Router::addRoute(['GET', 'HEAD'], '/liveness', 'App\Controller\HealthCheckController@liveness'); Router::addRoute(['GET', 'HEAD'], '/readiness', 'App\Controller\HealthCheckController@readiness'); 在Kubernetes的deployment上配置:
livenessProbe:httpGet:path:/livenessport:9501failureThreshold:1periodSeconds:10readinessProbe:httpGet:path:/readinessport:9501failureThreshold:1periodSeconds:10 当然这里我们只是简单了返回‘ok’,显然不能真正检查出健康状况。实际的检查要考虑业务具体场景和业务依赖的资源。例如对于重数据库服务我们可以检查数据库的连接池,如果连接池已满就暂时在Readiness Probe返回状态码503。
服务在Kubernetes销毁时,Kubernetes会先发来SIGTERM信号。进程有terminationGracePeriodSeconds这么长的时间(默认60秒)来自行结束。如果到时间后还没结束,Kubernetes就会发来SIGINT信号来强制杀死进程。Swoole本身是可以正确响应SIGTERM结束服务的,正常情况下不会丢失任何运行中的连接。实际生产中,如果Swoole没有响应SIGTERM退出,很有可能是因为服务端注册的定时器没有被清理。我们可以在OnWorkerExit处清理定时器来保证顺利退出。
<?php // config/autoload/server.php // ... 'callbacks' => [ SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], SwooleEvent::ON_WORKER_EXIT => function () { Swoole\Timer::clearAll(); }, ], // .
Posts
Hyperf 注解整洁之道
注解是元编程的一种。元编程从字面意思上说就是编写程序的程序。和普通编程一样,注解在给我们带来便捷的同时,如果使用不当,也有可能造成可读性、可维护性下降等问题。
在某些注解中,可能有很多配置项,比如:
//这还不是一个特别夸张的例子 @CircuitBreaker(timeout=0.05, failCounter=1, successCounter=1, fallback="App\Service\UserService::searchFallback") 如果我们的代码里用很多这样复杂的注解,就会引发以下几个问题:
注解中可使用的数据类型表达能力有限,比如必须用方法的字符串全名来表达方法,容易出错。 离开了IDE的帮助,长注解的可读性变得很差。(比如在GitHub上) 同样配置的注解多个地方使用,修改时要改很多地方。 这里我向大家推荐通过继承的方式配置Hyperf内的注解。
下面是一个继承CircuitBreaker(熔断器)注解的例子。
<?php ... /** * @Annotation * @Target({"METHOD"}) * * Shorthand for CircuitBreaker(timeout=0.05, failCounter=1, successCounter=1, fallback="App\Service\UserService::searchFallback") */ class FooCircuitBreakerAnnotation extends CircuitBreakerAnnotation { /** * @var float */ public $timeout = 0.05; /** * @var string */ public $fallback = UserService::class.'::searchFallback'; /** * The counter required to reset to a close state. * @var int */ public $successCounter = 1; /** * The counter required to reset to a open state.