Bughole(虫洞)工具:预发断点调试PHP利器
效果图
Bughole工具实现了PHPStorm中95%以上的debug功能。借助该工具在预发布调试:PHP的业务代码、API甚至任务脚本,都将变得极为方便!
试用
Bughole整套工具在预发9已经部署完备,以下步骤将分别演示:1)debug获取评价列表的API;2)debug PHP 任务
debug: 获取评价列表API - BeibeiItemRateGet
- 打开bughole UI:#(暂不对外开放) ,并且确认自己已经连上了预发9
- 添加断点。在断点模块,点击“Add”按钮,新增断点信息(可通过类似方式不断增加断点)
- 文件路径:***/***/api/ItemRateGet.php
- 断点行号:26
- 填好断点信息,点击确定
- 点击“建立连接”按钮。则服务端agent开始监听Xdebug的拦截信息
- 在新标签页访问:http://sapi.beibei.com/item/rate/0-27221145-1-10-1.html?preview=1&XDEBUG_SESSION_START=1 。这个访问也必须是预发9的!此时Xdebug会尝试拦截这个访问,具体表现为:页面hanging转圈不返回
- 回到bughole UI,点击页面顶端的“点我测试”按钮。如果一切正常,你将看到如下图所示信息,这表明Xdebug已经正确开始了
- 试试StepOver命令,StepInto命令,StepOut命令?当然你也可以使用RunToLine命令。
想查看当前Context的变量信息,就在右侧的Context面板查找吧。右下方还有调用栈信息
最后,一定要记得点击“Stop”按钮停止debug
debug: ProductTestTask任务(product-module)
- 打开bughole UI:#(暂不对外开放) ,并且确认自己已经连上了预发9
- 添加断点。在断点模块,点击“Add”按钮,新增断点信息(可通过类似方式不断增加断点)
- 文件路径:***/***/src/task/ProductTestTask.php
- 断点行号:17
- 填好断点信息,点击确定
- 点击“建立连接”按钮。则服务端agent开始监听Xdebug的拦截信息
在预发9机器上依次执行:
# 切换到root用户
sudo
su
# 为root用户设置环境变量(设置后Xdebug会主动拦截PHP脚本的运行)
export
XDEBUG_CONFIG=
"idekey=bughole"
# 执行任务(切记不要加sudo)
bash
/task/task_admin
.sh start --module=product ProductTestTask
- 回到bughole UI,点击页面顶端的“点我测试”按钮。如果一切正常,你将看到如上图所示信息,这表明Xdebug已经正确开始了
- 试试StepOver命令,StepInto命令,StepOut命令?当然你也可以使用RunToLine命令。
想查看当前Context的变量信息,就在右侧的Context面板查找吧。右下方还有调用栈信息
最后,一定要记得点击“Stop”按钮停止debug
说明:debug模式同一时间只允许一个人进行debug,如果有其他人也在debug,则可能出现错乱情况。解决办法:1)避免同时使用debug;2)如果debug已经不正常,尝试重启:kill这个任务(python bughole/agent.py);重新运行: python /tmp/tiny-scripts/bughole/agent.py (无需sudo)
实战
实战1:debug任意URL
详细步骤,请参考:debug获取评价列表API。
上方步骤4中触发Xdebug启动拦截的关键在于:URL后面要增加一个query(GET、POST皆可): XDEBUG_SESSION_START=1 即可触发调试模式
当然,很多API接口会对请求参数中的sign做安全校验,意即URL的GET参数不能随意增删,否则会报错:sign校验失败。遇到这种情况,可以通过在Cookie中添加参数触发Xdebug启动
情况1:如果你在Chrome浏览器中,可以通过Cookie管理工具为当前API域名添加Cookie: XDEBUG_SESSION = 1, HX-BETA = 9;或者直接在网页console中输入: document.cookie = 'HX-BETA=9; XDEBUG_SESSION=1;' 然后接着上述步骤4的指示继续即可
情况2:如果你在Charlse中,可以通过Rewrite工具为API添加Cookie,然后接着上述步骤4的指示继续即可
实战2:debug PHP任务(同上方debug ProductTestTask)
步骤参考debug ProductTestTask任务。触发Xdebug启动拦截的关键在于:当前用户的环境变量中设置了: XDEBUG_CONFIG=idekey=bughole 这个变量(使用env命令可以查看当前用户空间的变量)
由于通过sudo export命令设置环境变量会失败,所以需要切换到root用户运行任务脚本。
注意:多进程的任务(worker_num >= 2)在debug时会出现异常,解决办法:debug时将worker_num设为1,debug完成后再改回原值。
遇到问题要反馈?
遇到使用问题,烦请联系我qq: 379396993, 我会尽快帮忙查看问题
预发布如何部署
1)拉取agent代码。注意将 GitLab用户名 替换为自己的用户名
cd /tmp git clone http: //GitLab用户名@git.example.com/dongxu.lu/tiny-scripts.git |
2)安装Xdebug(如果已安装请跳过本步)
# 查看是否安装Xdebug,如果已安装请跳过本步 /opt/php- 7.1 . 9 /bin/php -m |grep Xdebug # copy编译好的扩展至PHP指定目录 cp /tmp/tiny-scripts/bughole/xdebug.so /opt/php- 7.1 . 9 /lib/php/extensions/no-debug-non-zts- 20160303 / # 新建文件: /opt/php- 7.1 . 9 /etc/conf.d/xdebug.ini , 内容如下 zend_extension = xdebug.so xdebug.remote_enable = 1 xdebug.remote_connect_back = 0 xdebug.remote_host = 127.0 . 0.1 xdebug.remote_port = 21733 xdebug.remote_handler = dbgp xdebug.remote_mode = req xdebug.remote_autostart = 0 xdebug.idekey = "bughole" # 重启PHP-FPM service php-fpm- 7 restart |
3)agent持久运行
python /tmp/tiny-scripts/bughole/agent.py > /tmp/bughole-agent.log 2 >& 1 & |
4)部署已完成。确认agent已运行
# agent会返回OK curl http: //127.0.0.1:21734 |
Bughole原理
工程结构图
时序图
以最常用的StepOver(下一行)命令的执行时序作为示例
安全考虑
Bughole未提供eval接口,所有操作都为“读”操作,不会对线上业务数据造成污染
待本周发布上线试用几天后会及时更新使用和部署(Agent)文档