安装 php 以及 xdebug 扩展

配置 xdebug

需要注意的是,自从 PHP 5.3 开始, 你需要使用 'zend_extension', 不能使用 'zend_extension_ts', 'zend_extension_debug' 或者 'extension'。

zend_extension="/usr/lib/php/20170718/xdebug.so" # 关键,之前写的是 extension 不可以,需要加前缀 zend_
xdebug.remote_enable = 1 # 关键,需要开启
xdebug.remote_host = "127.0.0.1"
xdebug.remote_port = "9001" #关键,定义监听端口, phpstorm 需要做相应的配置

xdebug.remote_log="var/log/xdebug/xlog"
xdebug.remote_autostart = 1

xdebug.idekey = "PHPSTORM"
xdebug.show_error_trace = 1
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp/xdebug-someuser/"
xdebug.profile_enable_trigger=1
xdebug.trace_enable_trigger=1

需要注意,字符串用双引号引起来

phpstorm 配置

  • 设置解释器
  • 设置站点
  • 增加 debug 用例

phpstorm 验证

  • phpstorm 有一个 valiate 功能,用于验证配置是否正确。

断点调试测试

配置完成之后,打个断点试试看。

参考

  • https://confluence.jetbrains.com/display/PhpStorm/Xdebug+Installation+Guide

在 laravel 开发中遇到了这样的问题,业务代码中调用 env() 获取环境变量,结果无法获取。

原因如官方文档所述:

为了给你的应用程序提升速度,你应该使用 Artisan 命令 config:cache 将所有的配置文件缓存到单个文件中。这会把你的应用程序中所有的配置选项合并成一个单一的文件,然后框架会快速加载这个文件。
通常来说,你应该把运行 php artisan config:cache 命令作为生产环境部署常规的一部分。这个命令不应在本地开发环境下运行,因为配置选项在应用程序开发过程中是经常需要被更改的。
如果在部署过程中执行 config:cache 命令,那你应该确保只从配置文件内部调用 env 函数。

意思是说,在你的业务代码中,不能使用 env() 方法。

原因何在?

在 Laravel 中,如果执行 php aritisan config:cache 命令,Laravel 将会把 app/config 目录下的所有配置文件“编译”整合成一个缓存配置文件到 bootstrap/cache/config.php,每个配置文件都可以通过 env 函数读取环境变量,这里是可以读取的。但是一旦有了这个缓存配置文件,在其他地方使用 env 函数是读取不到环境变量的,所以返回 null.

让我们看看这段代码,Illuminate/Foundation/Bootstrap/DetectEnvironment.php line 18:

public function bootstrap(Application $app)
{
    if (! $app->configurationIsCached()) {
        $this->checkForSpecificEnvironmentFile($app);

        try {
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        }
    }
}

这个方法在框架启动后就会运行,如果存在缓存配置文件,就不会去设置环境变量了。

因此,在配置文件即 app/config 目录下的其他地方,读取配置不要使用 env 函数去读环境变量,这样你一旦执行 php artisan config:cache 之后,env 函数就不起作用了。所有要用到的环境变量,在 app/config 目录的配置文件中通过 env 读取,其他地方要用到环境变量的都统一读配置文件而不是使用 env 函数读取。

环境:

  • ubuntu 16.04
  • php7.2

一、安装 php7.2-dev

apt-get install php7.2-dev -y

二、下载并编译 xdebug

  • 下载 xdebug 最新的源码包
wget https://xdebug.org/files/xdebug-2.6.0.tgz
  • 解压缩
tar -zxvf xdebug-2.6.0.tgz
  • 编译安装
cd xdebug-2.6.0
phpize
/configure --enable-xdebug
make
make install

三、配置

  • 在 cd /etc/php/7.2/mods-available 目录中,增加 xdebug.ini
extension=xdebug.so
xdebug.remote_enable = 1
xdebug.remote_port = 9001
xdebug.idekey = PHPSTORM
xdebug.show_error_trace = 1
xdebug.remote_autostart = 0
xdebug.file_link_format = phpstorm://open?%f:%l
  • 增加软连接
cd /etc/php/7.2/fpm/conf.d/
sudo ln -s /etc/php/7.2/mods-available/xdebug.ini 20-xdebug.ini
cd /etc/php/7.2/cli/conf.d/
sudo ln -s /etc/php/7.2/mods-available/xdebug.ini 20-xdebug.ini

四、测试

  1. cli 环境下,查看 php -m
  2. 测试 phpinfo,查看 xdebug 的信息 (略)
  3. phpstorm 测试 xdebug

在 openresty 中,要对部分特殊的 url 进行 rewrite,由于 url 比较多,还经常变动,rewrite 时还需要做判断,因此考虑使用 lua 进行处理。

在这个过程中,希望把特殊的 url 作为配置文件写入 table,然后进行判断,那么 lua 如何读取一个配置文件呢?

其实很简单,在 lua 脚本中使用 dofile 即可:

dofile "myconfig.lua"
dofile "/usr/share/myapp/config.lua"

这样的方式比较简单,但是如果遇到错误,会导致整个程序停止运行,如果你希望在遇到读取文件发生错误的时候抛出异常,可以使用以下的方式:

local ok,e = pcall(dofile,"myconfig.lua")
if not ok then
  -- handle error; e has the error message
end

MySQL slow query log consists of SQL statements that took more than long_query_time seconds to complete execution & required atleast min_examined_row_limit to be examined. By default, administrative queries & those that don’t use indexes for lookups are not logged.

Two common techniques used by Logrotate are:

copytruncate: Instead of moving the old log file & optionally creating a new one, logrotate truncates the original log file in place after creating a copy.
nocopytruncate: Do not truncate the original log file in place after creating a copy.
Truncating log files can block MySQL because the OS serializes access to the inode during the truncate operation. Therefore, it is recommended to temporarily stop slow query logging, flush slow logs, rename the old log file & finally re-enable slow query logging.

Flushing logs might take a considerable amount of time, so, to avoid filling slow log buffer, it’s advisable to temporarily disable MySQL slow query logging & re-enabling it once the rotation is complete.

Manual Rotation
To manually rotate slow query logs, we’ll temporarily disable slow query logging, flush slow logs, rename the original file & finally re-enable slow query logging.

get the path to slow query log file

MariaDB [(none)]> show variables like '%slow_query%';
+---------------------+-------------------------------+
| Variable_name | Value |
+---------------------+-------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/mysql-slow.log |
+---------------------+-------------------------------+
2 rows in set (0.00 sec)
temporarily disable slow query logging

MariaDB [(none)]> set global slow_query_log=off;
Query OK, 0 rows affected (0.00 sec)
flush only slow logs

MariaDB [(none)]> flush slow logs;
Query OK, 0 rows affected (0.00 sec)
rename the old log file and or compress it

[email protected]:~# mv /var/lib/mysql/mysql-slow.log /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log
[email protected]:~# gzip -c /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log > /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log.gz
finally, re-enable slow query logging

MariaDB [(none)]> set global slow_query_log=on;
Query OK, 0 rows affected (0.00 sec)

使用 logrotate

使用 logrotate 您可以安全的对 mysql query log 的日志进行切分
logrotate: /etc/logrotate.d/mysql-query

/var/lib/mysql/ubuntu.log {
        daily
        size 1G
        rotate 2
        missingok
        create 640 mysql adm
        compress
        sharedscripts
        postrotate
                test -x /usr/bin/mysqladmin || exit 0
                # If this fails, check debian.conf! 
                MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
                if [ -z "`$MYADMIN ping 2>/dev/null`" ]; then
                  # Really no mysqld or rather a missing debian-sys-maint user?
                  # If this occurs and is not a error please report a bug.
                  #if ps cax | grep -q mysqld; then
                  if killall -q -s0 -umysql mysqld; then
                    exit 1
                  fi
                else
                  $MYADMIN flush-logs
                fi
        endscript
}

参数                         功能
   compress                     通过gzip 压缩转储以后的日志
   nocompress                   不需要压缩时,用这个参数
   copytruncate                 用于还在打开中的日志文件,把当前日志备份并截断
   nocopytruncate               备份日志文件但是不截断
   create mode owner group      转储文件,使用指定的文件模式创建新的日志文件
   nocreate                     不建立新的日志文件
   delaycompress 和 compress    一起使用时,转储的日志文件到下一次转储时才压缩
   nodelaycompress              覆盖 delaycompress 选项,转储同时压缩。
   errors address               专储时的错误信息发送到指定的Email 地址
   ifempty                      即使是空文件也转储,这个是 logrotate 的缺省选项。
   notifempty                   如果是空文件的话,不转储
   mail address                 把转储的日志文件发送到指定的E-mail 地址
   nomail                       转储时不发送日志文件
   olddir directory             转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
   noolddir                     转储后的日志文件和当前日志文件放在同一个目录下
   prerotate/endscript          在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
   postrotate/endscript         在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
   daily                        指定转储周期为每天
   weekly                       指定转储周期为每周
   monthly                      指定转储周期为每月
   rotate count                 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
   tabootext [+] list           让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~
   size 1G                    当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem).

dateext: archive old log files by adding a date extension using the format YYYYMMDD instead of using a number.
missingok: if a log file is missing, don’t issue an error message
rotate 20: 保存多少个切分文件
notifempty: don’t rotate empty log files
sharedscripts: run prerotate & postrotate scripts only once, no matter how many logs match the wildcard pattern