今天来讲讲这个主题“kubernetes部署Discuz?kubernetes搭建Discuz?DiscuzX3.5一直通信失败或DiscuzX3.5一直正在连接状态在k8s或k3s环境下如何成功调试”,先说缘起!
为了更好服务于情感培训的学员,于是准备把之前自己的社区重新恢复回来。由于这个社区好久不用了,是X3.4的版本,但是恢复之后,本地k8s中运行正常,但是通信一直失败。由于当年搞这个社区的时候,还是接收搜索引擎过来的会员,当时的部署方式也比较原始,记得初始版本是编译部署的,到后来迁移到了用docker的部署方式,之后就搁置了,当时处理方式记得是用python写脚本,把所有数据又以wordpress的形式重新造了一份,当时的想法应该就是资讯站点就保留一个,整个应用服务体系的布局应该大换血,不需要社区了,应对移动互联网时代资讯的传播特点做一些新的突破。
但是微信群群聊这样的服务其实感觉学员成长的比较慢,也为了把自己社区之前沉淀的帖子重新激活,为学员所用,毕竟2000多个与女生互动各阶段的实践经验案例,对于新手成长意义还是格外非凡的,而且采用社区答疑的方式,也能更好的通过学员的fr的描述精准定位问题,给出解决方案,也免去了群聊时候,信息熵导致的信息传播噪音过大的毛病,于是把这套discuz程序重新激活就成了我的当务之急。
我的处理方式还是化繁为简,为了不引入太多引发偏差思考的过程,我决定先在k8s上重新安装一遍discuz,看通信状态是否正常,考虑的立意点就是如果通信失败,这是一套纯净的系统,我调试也方便,出问题原因无非就两个,程序本身的原因或者程序运行环境的原因,没有discuz插件的干扰,没有自定义主题的干扰,更方便我聚集问题的追踪。于是开始按着心里的盘算实践开来。
由于我本地开发环境也是全部启用https,并且写golang项目比较多,线上运行的php服务都稳定运行,所以也好久没碰php代码了,所以我亟需一个可以单步调试的debug环境。所以要解决的第一个问题就是如何在我现有运行的php环境基础上安装xdebug并让它运行成功。
由于我php环境的Dockerfile都是根据我自己项目的需求定制的,所以配置过程不表,总之,我安装完xdebug之后,遇到一个问题,因为之前有过心思要上线另外一个资源贩卖站点,那个站点需要配置支持swoole和swoole_loader支持,似乎跟我的xdebug安装之后的环境冲突,我网上也查了一下,的确有这个问题,会导致cpu飙升最终宕机,于是忽略次要问题(让swoole和xdebug可以共存,也许调研下来能掌握点什么,但是目前对我意义不大),直接解决主要问题,弄了去掉swoole和swoole_loader的运行环境,用xdebug愉快调试即可。
xdebug安装成功之后,用命令kubectl exec -it CONTAINER_ID – bash进入到容器内部,用命令php -m查看,发现xdebug已经正常安装,在discuz入口文件中phpinfo()查看xdebug也已存在,于是开始配置xdebug的选项。如果你是docker环境的话,有过配置经验的话,你可能会有external_ips和php ide config等ENV常量的印象,我上次在docker上用xdebug调试,记得还是解决一个wordpress用到的主题分页跳转问题(输入页码按enter键,只会跳到第一页),已经记不清是哪一年了,但是感受似曾相识,就是xdebug网上各种说的云里雾里,配置过程挺艰辛。这次也是有点畏难心理,但是毕竟相比于一行一行var_dump,xdebug确实舒爽很多,最终配置成功。要强调的几点是:
- client_host和client_port指的是容器运行环境连接本机应用运行环境,ide等监听的地址及端口
而本机的调试工具,或者你用phpstorm或者你用vscode,应该就这两个最常用吧?指的其实就是xdebug对于运行程序有监听行为时候(你想让xdebug无缝支持你做单步调试),安装了xdebug服务扩展服务的容器如何跟我(ide等,phpstorm或者vscode)通信,让我(ide等,phpstorm或者vscode)抓到你监听程序运行的全部行为,安装了xdebug服务扩展服务的容器就要告诉我(ide等,phpstorm或者vscode)连哪个地址,用哪个端口,方便调试的那些xdebug处理后的信息我都能取到。
mac上获取本机ip4地址的命令是`ipconfig getifaddr en0`
- 要提前打上断点或者让程序停在入口处,不然捕获不到
开始正式调试discuz程序了,最终定位到了问题,其实discuz后台是有提示的,但是可能你到了k8s环境,这个ip地址该填哪个你就懵了,最终调试成功,我也说一下要点。
- 如下图,这里要按我图中所说进行配置
但是还没完,最狗的事情其实也在这里,如果告诉你配置,你配置了,那么,配置这个地址能被使用,估计也就没有问题了,可关键来了,discuzX3.5中你尽管配,我压根不会用,如下图:
图中所示部分是我修改后的,这样ip地址可以在curl建立与discuz通信时被用到,这里原来值是特么'',而这个dfopen第六个参数就是ip地址,那压根你怎么传ip都不会被使用,就很。。。
- 要设置好文件的访问权限,即/api/uc.php文件的访问权限
不然最终uc_server(即通常意义上的ucenter)通过curl方式请求discuz程序是请求不到的。
- 你要会调试php中的curl请求
curl请求,如果服务间通信正常,并且是隶属同个项目(就是代码单步调试能被跟踪到),那么你debug追执行流程就好了,如果curl访问不通,比如这个discuzX3.5的程序,如果没做第2步,那压根就请求不过去,因为请求服务到了错误的ip地址,443在php环境运行的本地根本不通,你就没办法调试了,这个时候要想看到curl的全貌,可以把curl请求的信息详细记录下来,方法下面会讲,同时概括下这种情况下的处理思路,首先排除一下curl本身参数配置导致的问题,再排除一下是不是请求地址存在问题,这两个排查点都可以用构建一个最简单的curl资源的方式排查到,如下:
代码语言:javascript复制$ch = curl_init("某国内地址"); // initialize curl handle
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
print($data);
这样就能排除做为curl发起方本身的问题。当然看$errno = curl_errno($ch);
返回码也可以,curl请求失败的返回码含义文档中都有,大概能确定问题的范围。
回到前面挖的坑,开始填,如何把curl请求全部记录下来?
代码语言:javascript复制$f = fopen('/var/log/curl_debug.log', 'wb');
curl_setopt($ch,CURLOPT_VERBOSE,true);//默认是标准错误输出中
curl_setopt($ch,CURLOPT_STDERR ,$f);//有了该指令,请求过程记录会写到该文件中
我的标准处理方式,就是日志目录跟本地做了volumeMount,所以我直接mac本机tail -f curl_debug.log
就可以查看curl的请求链路,方便排查问题。
最终上图看效果:
这个点看似很小,其实它就是discuz程序的核心,因为它把业务程序和用户管理中心给拆分开了,这样的好处就是ucenter可以单独作为一个承接用户中心的独立业务,可以跟所有其他程序进行整合,本身这个通信过程中的加密和解密,通信验证规则也比较烦琐,有兴趣也可以自己跟一下代码。因为网络通信、加密、sso基本是所有系统都会涉及的部分,虽然discuz不是纯粹的面向对象,但是互联网技术发展至今,你如果在大公司做螺丝钉,其实架构底层的部分,你可能也没太多机会接触到,但是这些web服务的核心网络通信、加密算法、sso的解决方案是很多应用高维度的核心部分,有所学习总有精进,希望今天的课程能够帮助你!