baldinof/roadrunner-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

baldinof/roadrunner-bundle

Composer 安装命令:

composer require baldinof/roadrunner-bundle

包简介

A RoadRunner worker as a Symfony Bundle

README 文档

README

RoadRunner is a high-performance PHP application server, load-balancer, and process manager written in Golang.

This bundle provides a RoadRunner Worker integrated in Symfony, it's easily configurable and extendable.

Installation

Run the following command:

composer require baldinof/roadrunner-bundle

If you don't use Symfony Flex:

  • register Baldinof\RoadRunnerBundle\BaldinofRoadRunnerBundle in your kernel
  • copy default RoadRunner configuration files: cp vendor/baldinof/roadrunner-bundle/.rr.* .

Usage

  • require the RoadRunner download utility: composer require --dev spiral/roadrunner-cli
  • get the RoadRunner binary: vendor/bin/rr get --location bin/
  • run RoadRunner with bin/rr serve or bin/rr serve -c .rr.dev.yaml (watch mode)
  • visit your app at http://localhost:8080

Integrations

Depending on installed bundle & your configuration, this bundles add some integrations:

  • Sentry: configure the request context (if the SentryBundle is installed)
  • Sessions: add the session cookie to the Symfony response (if framework.sessions.enabled config is true)
  • Doctrine Mongo Bundle: clear opened managers after each requests (if DoctrineMongoDBBundle is installed)
  • Doctrine ORM Bundle: clear opened managers and check connection is still usable after each requests (if DoctrineBundle is installed)
  • Blackfire: enable the probe when a profile is requested (if the blackfire extension is installed)
  • Xdebug: allow Xdebug in trigger mode (if the xdebug extension is installed)

Even if it is not recommended, you can disable default integrations:

baldinof_road_runner:
  default_integrations: false

Middlewares

You can use middlewares to manipulate request & responses. Middlewares must implements Baldinof\RoadRunnerBundle\Http\MiddlewareInterface.

Example configuration:

baldinof_road_runner:
    middlewares:
        - App\Middleware\YourMiddleware

Be aware that

  • middlewares are run outside of Symfony Kernel::handle()
  • the middleware stack is always resolved at worker start (can be a performance issue if your middleware initialization takes time)

Kernel reboots

The Symfony kernel and the dependency injection container are preserved between requests. If an exception is thrown during the request handling, the kernel is rebooted and a fresh container is used.

The goal is to prevent services to be in a non-recoverable state after an error.

To optimize your worker you can allow exceptions that does not put your app in an errored state:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: on_exception
      allowed_exceptions:
        - Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
        - Symfony\Component\Serializer\Exception\ExceptionInterface
        - App\Exception\YourDomainException

If some of your services are stateful, you can implement Symfony\Contracts\Service\ResetInterface and your service will be resetted on each request.

If you are seeing issues and want to use a fresh container on each request you can use the always reboot strategy:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: always

If you are building long-running application and need to reboot it every XXX request to prevent memory leaks you can use max_jobs reboot strategy:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: max_jobs
      max_jobs: 1000 # maximum number of request
      max_jobs_dispersion: 0.2 # dispersion 20% used to prevent simultaneous reboot of all active workers (kernel will rebooted between 800 and 1000 requests)

If you want to reboot the worker when memory usage exceeds a certain threshold to prevent memory exhaustion you can use memory reboot strategy:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: memory
      memory_threshold_mb: 256 # memory threshold in megabytes (default: 128MB)

You can combine reboot strategies:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: [on_exception, max_jobs, memory]
      allowed_exceptions:
        - Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
        - Symfony\Component\Serializer\Exception\ExceptionInterface
        - App\Exception\YourDomainException
      max_jobs: 1000
      max_jobs_dispersion: 0.2
      memory_threshold_mb: 256

Events

The following events are dispatched throughout the worker lifecycle:

  • Baldinof\RoadRunnerBundle\Event\WorkerStartEvent: Dispatched right before the worker starts listening to requests.
  • Baldinof\RoadRunnerBundle\Event\WorkerStopEvent: Dispatched right before the worker closes.
  • Baldinof\RoadRunnerBundle\Event\WorkerExceptionEvent: Dispatched after encountering an uncaught exception during request handling.
  • Baldinof\RoadRunnerBundle\Event\WorkerKernelRebootedEvent: Dispatched after the symfony kernel was rebooted (see Kernel reboots).

Development mode

Copy the dev config file if it's not present: cp vendor/baldinof/roadrunner-bundle/.rr.dev.yaml .

Start RoadRunner with the dev config file:

bin/rr serve -c .rr.dev.yaml

Reference: https://roadrunner.dev/docs/beep-beep-reload

If you use the Symfony VarDumper, dumps will not be shown in the HTTP Response body. You can view dumps with bin/console server:dump or in the profiler.

Metrics

Roadrunner can collect application metrics, and expose a prometheus endpoint.

Example configuration:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
  metrics:
    enabled: true
    collect:
      user_login:
        type: counter
        help: "Number of logged in user"

And configure RoadRunner:

# .rr.yaml
rpc:
  listen: "tcp:127.0.0.1:6001"

metrics:
  address: "0.0.0.0:9180" # prometheus endpoint

Then simply inject Spiral\RoadRunner\MetricsInterface to record metrics:

class YouController
{
    public function index(MetricsInterface $metrics): Response
    {
        $metrics->add('user_login', 1);

        return new Response("...");
    }
}

gRPC

gRPC support was added by the roadrunner-grpc plugin for RoadRunner 2 (https://github.com/spiral/roadrunner-grpc).

To configure Roadrunner for gRPC, refer to the configuration reference at https://roadrunner.dev/docs/beep-beep-grpc. Basic configuration example:

server:
  command: "php public/index.php"
  env:
    APP_RUNTIME: Baldinof\RoadRunnerBundle\Runtime\Runtime

grpc:
  listen: "tcp://:9001"

  proto:
    - "calculator.proto"

Once you have generated your PHP files from proto files, you just have to implement the service interfaces. GRPC services are registered automatically. Example service:

<?php

namespace App\Grpc;

use Spiral\RoadRunner\GRPC;
use App\Grpc\Generated\Calculator\Sum;
use App\Grpc\Generated\Calculator\Result;
use App\Grpc\Generated\Calculator\CalculatorInterface;

class Calculator implements CalculatorInterface
{
    public function Sum(GRPC\ContextInterface $ctx, Sum $in): Result
    {
        return (new Result())->setResult($in->getA() + $in->getB());
    }
}

KV caching

Roadrunner has a KV (Key-Value) plugin that can be used to cache data between requests.

To use it, refer to the configuration reference at https://roadrunner.dev/docs/kv-overview. This requires the spiral/roadrunner-kv, spiral/goridge and symfony/cache composer dependencies. Basic configuration example:

Example configuration:

# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
  kv:
    storages:
      - example

And configure RoadRunner:

# .rr.yaml
rpc:
  listen: tcp://127.0.0.1:6001

kv:
  example:
    driver: memory
    config: { }

An adapter service will now be created automatically for your storage with the name cache.adapter.roadrunner.kv_<YOUR_STORAGE_NAME>.

Basic usage example:

# config/packages/cache.yaml
framework:
  cache:
    pools:
      cache.example:
        adapter: cache.adapter.roadrunner.kv_example

Usage with Docker

# Dockerfile
FROM php:8.1-alpine

RUN apk add --no-cache linux-headers autoconf openssl-dev g++ make pcre-dev icu-dev zlib-dev libzip-dev && \
    docker-php-ext-install bcmath intl opcache zip sockets && \
    apk del --purge autoconf g++ make

WORKDIR /usr/src/app

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

COPY composer.json composer.lock ./

RUN composer install --no-dev --no-scripts --prefer-dist --no-progress --no-interaction

RUN ./vendor/bin/rr get-binary --location /usr/local/bin

COPY . .

ENV APP_ENV=prod

RUN composer dump-autoload --optimize && \
    composer check-platform-reqs && \
    php bin/console cache:warmup

EXPOSE 8080

CMD ["rr", "serve"]

baldinof/roadrunner-bundle 适用场景与选型建议

baldinof/roadrunner-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.48M 次下载、GitHub Stars 达 307, 最近一次更新时间为 2019 年 12 月 10 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 baldinof/roadrunner-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 baldinof/roadrunner-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 baldinof/roadrunner-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.48M
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 307
  • 点击次数: 15
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 307
  • Watchers: 3
  • Forks: 59
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-12-10