分类 Typecho 下的文章

一、故障概述

在 Typecho 博客系统执行文章保存操作(POST /action/contents-post-edit)时,页面返回 HTTP 504 Gateway Timeout 错误。对存储、资源、数据库及 PHP 环境进行分层排查后,确认底层运行正常,问题定位为反向代理超时配置。

二、排查过程与实证结果

1、存储系统验证

排查命令:在 Pod 内执行

time touch /var/www/html/nfs_test && echo "test">/var/www/html/nfs_test && rm /var/www/html/nfs_test

实测结果

real    0m0.125s
user    0m0.000s
sys     0m0.001s

结论:NFS 文件读写操作耗时仅 0.125 秒,无 I/O 延迟或挂载异常,可排除存储瓶颈。

2、资源使用率检查

排查命令kubectl top pod miiv-lnp-557f547c45-d4745

实测结果

NAME                        CPU(cores)   MEMORY(bytes)
miiv-lnp-557f547c45-d4745   13m          25Mi

结论:Pod CPU 使用率 13m、内存 25Mi,资源配额充足,无资源争抢或耗尽情况。

3、数据库状态分析

排查命令SHOW FULL PROCESSLIST;

实测结果

| Id     | User    | Host            | db      | Command | Time | State    | Info                  |
| 404341 | root    | localhost       | NULL    | Query   |    0 | starting | SHOW FULL PROCESSLIST |
| 404377 | typecho | 10.42.2.3:45330 | typecho | Sleep   |   61 |          | NULL                  |
| 404378 | typecho | 10.42.2.3:45340 | typecho | Sleep   |   61 |          | NULL                  |

结论:数据库连接均为 Sleep 状态,无长时间运行查询,无连接阻塞或死锁,负载正常。

4、PHP 执行能力测试

测试脚本:创建 PHP 文件模拟耗时操作,访问

<?php
echo "Start: " . date('Y-m-d H:i:s') . "\n";
sleep(2); // 模拟耗时操作
echo "End: " . date('Y-m-d H:i:s') . "\n";
?>

实测结果

Start: 2026-05-02 12:56:03
End: 2026-05-02 12:56:05

结论:PHP-FPM 可正常处理 2 秒耗时请求,脚本执行不受限制,应用层基础处理能力无异常。

5、故障日志定位

日志内容

10.42.1.2 - - [02/May/2026:12:44:32 +0000] "POST /action/contents-post-edit?_=94be44fc416e098a75bd09ba9d85aec0 HTTP/1.1" 504 569

关键信息:文章保存请求触发 504 超时,与 PHP 正常处理能力测试结果不一致。

结论:问题并非应用层逻辑错误,而是网关层超时配置导致。

6、调整反向代理超时配置

修改 Nginx 或 Ingress Controller 配置,增加proxy_read_timeoutproxy_send_timeout值(建议设置为 120 秒以上)

示例配置(Nginx):

location~\.php$ {
    proxy_read_timeout 120s;
    proxy_send_timeout 120s;
}

重新发布文章发现正常(耗时还是有问题)

三、根因分析

综合实测数据,系统底层环境(存储、资源、数据库、PHP)均无异常。HTTP 504 错误本质为反向代理等待后端响应超过预设超时阈值。PHP 可正常处理 2 秒耗时请求,说明基础执行能力正常;但文章保存操作可能包含额外处理逻辑(如插件触发、缓存更新等),导致总耗时超过网关默认超时时间(通常为 60 秒)。

四、解决方案

关闭Typecho中的AISummary插件正常

ypecho 动态 IP 环境适配与故障排查指南

场景一:解决动态 IP 导致的后台死链问题

Typecho 是一个使用 PHP 编写的博客系统。在部署环境(如容器、动态 IP 服务器)中,如果域名或 IP 地址不固定,系统生成的后台按钮链接往往会指向旧的 IP 地址或错误的端口,导致访问异常。

为了解决这个问题,我们需要开启相对地址模式。虽然开启后永久链接(伪静态)可能无法正常使用,但这能确保后台按钮在 IP 变动时依然可用。

开启相对地址的两种方法

方法一:修改数据库(不推荐)
直接修改数据库 typecho_options 表,将 siteUrl 字段的值改为相对路径(如 /)。

方法二:修改核心代码(推荐)
通过修改核心文件来绕过后台对“绝对 URL”的强制校验。

操作步骤:

1.定位文件:var/Widget/Options/General.php

2.查找代码(约 87 行):

->addRule('url', _t('请填写一个合法的URL地址'))

3.修改代码:

->addRule('xssCheck', _t('请填写一个合法的URL地址'))

4.保存文件,刷新后台即可生效。

修改效果Typecho 后台不再强制校验站点地址协议和域名,后台所有链接自动适配当前访问地址,彻底解决动态 IP / 端口导致的死链问题。

场景二:后台 “Server Error” 排查与修复

访问后台模块(如附件管理)出现 Server Error (500) 且无具体报错时,按以下步骤修复。

1. 开启调试模式

编辑网站根目录 config.inc.php,在 <?php 下方直接粘贴:

// ----------调试使用-------
define('__TYPECHO_DEBUG__', true);
error_reporting(E_ALL);
ini_set('display_errors', 'On');
// 强制输出错误到浏览器,防止被 Nginx 拦截
ini_set('html_errors', 'Off');
// -------------------------

2. 分析报错信息

典型错误
TypeError: Argument 1 passed to Typecho\Common::mimeIconType() must be of the type string, null given

原因:数据库中部分附件 mime 字段为 NULL,但函数强制要求字符串,导致崩溃。

3. 修复方案

编辑文件admin/manage-medias.php

修改前(报错)

<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime); ?>

修改后(修复)

<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime ?? ''); ?>

修复后完整代码段

<?php while ($attachments->next()): ?>

<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime ?? ''); ?>

4. 结果与注意

保存后刷新后台,Server Error 消失,附件管理正常显示。

️ 注意:调试完成后,务必注释 / 删除 config.inc.php 里的调试代码,避免生产环境泄露敏感信息。

一、Certbot 简介

是Let's Encrypt官方推荐的获取证书的客户端,可以帮我们获取免费的Let's Encrypt 证书。Certbot 是支持所有 Unix 内核的操作系统的。

sudo yum install snapd               #安装 snapd
sudo snap install --classic certbot  #使用snapd安装 Certbot
sudo ln -s /var/lib/snapd/snap /snap #创建软链接保证命令

二、申请证书

执行证书生成命令,去云服务商后台增加一条dns,并将certbot生成的参数填写到dns配置的相关位置

certbot certonly -d *.lius.fun --manual --preferred-challenges dns
  • certonly 表示安装模式,Certbot 有安装模式和验证模式两种类型的插件
  • -d 为那些主机申请证书,如果是通配符,输入 *.example.com
  • --manual 表示手动安装插件,Certbot 有很多插件,不同的插件都可以申请证书,用户可以根据需要自行选择
  • --preferred-challenges dns 使用 DNS 方式校验域名所有权

[button color="light" icon="" url="https://letsencrypt.org/docs/challenge-types/#http-01-challenge" type=""]其他挑战方式[/button]

三、自动申请

Let’s Encrypt 证书将在 90 天后到期。我们建议您自动更新证书。此处,我们将一个 cron 作业添加到现有 crontab 文件中,以执行这一操作。

  1. 打开 crontab 文件
$ crontab -e
  1. 添加certbot命令,并设置为每天运行。在本例中,我们每天中午运行该命令。该命令检查服务器上的证书是否会在未来 30 天内到期,如果是,则更新证书
0 12 * * * /usr/bin/certbot renew --quiet

[scode type="share"]-quiet指令告知certbot不要生成输出[/scode]

四、手动申请

手动申请需要进行DNS挑战,请注意开启
cd /etc/letsencrypt/renewal
cat lius.fun.conf
certbot certonly --email gua3j7@126.com -d *.lius.fun --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory

准备工作:

Typecho生成备份文件

一、docker容器环境配置

1、docker 生成容器

docker run -itd 
  --name project
  --net photoprism_default         #保证和MariaDB一个网络环境
  -p 4888:4888                     #宝塔面板端口
  -p 4810:4810  
  -p 4820:4820 
  -p 4830:443
  --restart always  
  --privileged  
  -v /volume1/docker/project:/www   #使用宝塔面板快速部署
  -v /volume1/Mii:/opt/filerun      #Flerun可持续化环境
  centos7

2、安装宝塔面板

yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec

3、安装完毕后设置端口为4888

4、宝塔面板安装PHP7.4(7.3)、 Nginx1.24

说明:容器网络模式默认使用bridge忘记修改为photoprism_default,则使用以下办法

docker network disconnect bridge project  #解除网络绑定
docker network connect photoprism_default #网络绑定
docker restart project
重启生效后会导致宝塔面板、Nginx停止,请手动启动

二、远程数据库配置

1、进入MaraDB数据库容器

docker exec -it maradb bash
mysql -u root -p                   #photoprism系列的MariaDB数据密码为photoprism             
create database typecho;           #创建typecho数据库
create user 'typecho'@'%' identified by 'your_password';     #创建用户typecho
grant all on typecho.* TO 'typecho'@'%';                    #typecho用户授权任何ip可访问typecho数据库 
flush privileges;                  #刷新操作

三、宝塔面板创建网站

1、创建Typecho网站,将4810端口分配给网站

2、进入安装向导,输入远程MariaDB数据库IP地址等信息

如一直显示:正在设置数据库、数据库不存在df_user
则可能是:

  • MariaDB和project不在photoprism网络
  • 账户密码错误权限未设置
  • fileru.zip文件解压后数据重复安装,导致存在缓存,影响数据库判断

注意:最好使用drop user 'user'@'localhost'&& flush privileges

四、安装完毕后打开后台上传即可

Typecho导入成功.png