资讯专栏INFORMATION COLUMN

Lumen配置文件按需加载出现的坑

lentoo / 1769人阅读

摘要:问题分析通过阅读源码发现,中的服务都是按需绑定并加载。在服务按需绑定并加载的时候,使用了类似组件的形式通过载入配置项并绑定服务。因为在这个时候的相关配置文件还没有被载入。

问题描述

公司一个高并发API需要从Laravel移植到Lumen,由于数据库配置信息是通过远程或者缓存读取后动态配置,所以在中间件时使用到了 Config::set 然而实际运行时发现数据库配置并没有更新。

由于是从Laravel移植,因此保留了Facades的写法,Lumen中可以通过以下方法使用Facades:

取消 bootstarp/app.php$app->withFacades(); 的注释

use IlluminateSupportFacadesXXX

另一方面,系统使用 Redis 作为缓存,通过 env 配置 Redis ,配置信息存储在 config/database.php 在没有使用数据库先使用缓存的情况下,报没有传配置项的错误。

问题分析

通过阅读源码 laravel/lumen-framework/src/Application.php 发现,Lumen中的服务都是按需绑定并加载。先来看看 make() 的代码:

public function make($abstract, array $parameters = [])
{
    $abstract = $this->getAlias($this->normalize($abstract));

    if (array_key_exists($abstract, $this->availableBindings) &&
        ! array_key_exists($this->availableBindings[$abstract], $this->ranServiceBinders)) {
        $this->{$method = $this->availableBindings[$abstract]}();

        $this->ranServiceBinders[$method] = true;
    }

    return parent::make($abstract, $parameters);
}

Lumen通过数组 $availableBindings 实现了基本服务的按需绑定并加载。在服务按需绑定并加载的时候,使用了类似组件的形式通过 loadComponent() 载入配置项并绑定服务。再来看看 loadComponent() 的代码:

public function loadComponent($config, $providers, $return = null)
{
    $this->configure($config);

    foreach ((array) $providers as $provider) {
        $this->register($provider);
    }

    return $this->make($return ?: $config);
}

如此就释然为什么在中间件以及使用 DB 之前想要动态配置数据库的信息时无法正确的写入配置项了。因为在这个时候 DB 的相关配置文件还没有被载入。你先写入了配置项当使用 DB 的时候会再次载入配置文件中的配置项覆盖动态写入的内容。

同理,使用 Redis 时,由于 Redis 相关配置是写在 database.php 里的,仅仅通过 $app->register(IlluminateRedisRedisServiceProvider::class); 注册是无法获取到配置项,如果在使用 Redis 时之前没有使用 DB 就会报没有传配置项的错误。

解决方案

既然找到了问题所在,要解决起来也是很方便的。只要在修改、使用配置项之前先载入配置文件就可以解决这些问题。比如:

使用 app()->configure("database"); 载入所需要的配置文件

在注册绑定服务到服务容器的时候使用 loadComponent 进行注册绑定


欢迎关注我的博客 http://targetliu.com

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21790.html

相关文章

  • 使用less-loader与antd按需加载(babel-plugin-import)的坑

    摘要:的按需加载设置安装插件修改或新建文件进行编辑,但两者只能存一种根据配置更改主题颜色在中找到原配置注释后更改为定义全局样式配置自定义主题只需修改的颜色,再重启项目即可更改主题颜色 为了在react中使用antd以及它的主题更改,需要在项目中 yarn eject 暴露出webpack文件进行改造本答案是在日期当时最新的create-react-app上的webpack版本 less-l...

    Eminjannn 评论0 收藏0
  • Docker 使用 supervisord 管理 lumen队列与crontab

    摘要:之前在内使用的队列服务做了一个异步,处理一些内容审核的相关操作。但是每次重启容器之后都需要进入内部启动的队列进程虽然文档内有写使用管理进程,但是并没有那么做。。,最近需求上需要使用,所以决定使用来管理这些进程。所以使用了一个脚本,在执行它。 之前在docker内使用lumen的队列服务做了一个异步,处理一些内容审核的相关操作。但是每次重启容器之后都需要进入docker内部启动lumen...

    cyqian 评论0 收藏0
  • Docker 使用 supervisord 管理 lumen队列与crontab

    摘要:之前在内使用的队列服务做了一个异步,处理一些内容审核的相关操作。但是每次重启容器之后都需要进入内部启动的队列进程虽然文档内有写使用管理进程,但是并没有那么做。。,最近需求上需要使用,所以决定使用来管理这些进程。所以使用了一个脚本,在执行它。 之前在docker内使用lumen的队列服务做了一个异步,处理一些内容审核的相关操作。但是每次重启容器之后都需要进入docker内部启动lumen...

    hlcc 评论0 收藏0
  • 基于 lumen 的微服务架构实践

    摘要:现在的提供了一种更易于使用和维护的计划任务方式。注意事项建议开启这样会极大的加速类的加载。 lumen 为速度而生的 Laravel 框架 官网的介绍很简洁,而且 lumen 确实也很简单,我在调研了 lumen 相关组件(比如缓存,队列,校验,路由,中间件和最重要的容器)之后认为已经能够满足我目前这个微服务的需求了。 任务目标 showImg(https://segmentfault...

    hatlonely 评论0 收藏0
  • PHPUnit实践二(生命周期)

    摘要:另外,与模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。 本系列教程所有的PHPUnit测试基于PHPUnit6.5.9版本,Lumen 5.5框架 PHPUnit测试一个文件类的生命周期 showImg(https://segmentfault.com/img/bVbnXJj?w=1330&h=1186); 理解PHPUnit加载机制(Lumen...

    jemygraw 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<