提交 8d3fd1a1 authored 作者: 陈泽健's avatar 陈泽健

docs(service): 根据执行问题输出服务自检问题处理文档及计划执行文档处理

- 添加中间件检测执行异常及信息打印乱码问题处理文档
- 修复安卓自检项问题处理文档中的问题三分析
- 更新服务检测java服务异常未打印信息问题处理文档
- 添加模块导入存在未正确导入函数问题处理文档
- 修复文档模板文件中的格式问题
- 完善问题根因分析、解决方案和验证步骤
上级 d773d7d2
......@@ -94,7 +94,8 @@
"Bash(powershell -Command \"Remove-Item ''C:\\\\PycharmData\\\\ubains-module-test\\\\AuxiliaryTool\\\\ScriptTool\\\\ServiceSelfInspection\\\\test_*.ps1'', ''C:\\\\PycharmData\\\\ubains-module-test\\\\AuxiliaryTool\\\\ScriptTool\\\\ServiceSelfInspection\\\\diagnose_modules.ps1'', ''C:\\\\PycharmData\\\\ubains-module-test\\\\AuxiliaryTool\\\\ScriptTool\\\\ServiceSelfInspection\\\\update_common_imports.ps1'' -ErrorAction SilentlyContinue\")",
"Bash(powershell -ExecutionPolicy Bypass -File \"C:\\\\PycharmData\\\\ubains-module-test\\\\AuxiliaryTool\\\\ScriptTool\\\\ServiceSelfInspection\\\\debug_modules.ps1\")",
"Bash(powershell -ExecutionPolicy Bypass -File \"C:\\\\PycharmData\\\\ubains-module-test\\\\AuxiliaryTool\\\\ScriptTool\\\\ServiceSelfInspection\\\\debug_modules2.ps1\")",
"Bash(powershell:*)"
"Bash(powershell:*)",
"Bash(dir /b \"C:\\\\PycharmData\\\\ubains-module-test\\\\Docs\\\\PRD\\\\服务自检\\\\问题修复\"\" | findstr \"java服务 \")"
]
}
}
......@@ -5,9 +5,16 @@ $AndroidDefaultPort = 5555
$script:ADB_PATH = $null
function Resolve-AdbPath {
param(
[Parameter(Mandatory=$false)]
[string]$ScriptDir
)
# 1) 脚本目录
$localAdb = Join-Path $SCRIPT_DIR "adb.exe"
if (Test-Path $localAdb) { return $localAdb }
if (-not [string]::IsNullOrEmpty($ScriptDir)) {
$localAdb = Join-Path $ScriptDir "adb.exe"
if (Test-Path $localAdb) { return $localAdb }
}
# 2) 系统 PATH
try {
......@@ -19,7 +26,12 @@ function Resolve-AdbPath {
}
function Test-AdbAvailable {
$script:ADB_PATH = Resolve-AdbPath
param(
[Parameter(Mandatory=$false)]
[string]$ScriptDir
)
$script:ADB_PATH = Resolve-AdbPath -ScriptDir $ScriptDir
if ([string]::IsNullOrWhiteSpace($script:ADB_PATH)) { return $false }
# 如果是本地 adb.exe,检查 DLL 是否齐全(避免"只放 adb.exe"运行不了)
......@@ -77,7 +89,7 @@ function Test-AndroidDeviceHealth {
$results = @()
# 0) 依赖检查:adb
if (-not (Test-AdbAvailable)) {
if (-not (Test-AdbAvailable -ScriptDir $ScriptDir)) {
Write-Log -Level "WARN" -Message "[Android] 未检测到 adb.exe(请安装 Android Platform Tools 或将 adb 加入 PATH),跳过安卓自检"
$results += @{
Check = "Android自检"
......
# ==============================================================================
# ==============================================================================
# ServiceCheck.psm1
# ------------------------------------------------------------------------------
# �������
# 服务检测模块
#
# .SYNOPSIS
# �ṩ���������������޸�����
# 提供服务检测和修复功能
#
# .DESCRIPTION
# ��ģ�����ڼ����޸� ujava/upython ����������������״̬��
# ֧����ƽ̨�ʹ�ͳƽ̨���ֲ���ʽ�ļ�⡣
# 本模块用于检测和修复 ujava/upython 容器内外的服务运行状态。
# 支持新平台和传统平台两种部署方式的检测。
#
# ��Ҫ���ܣ�
# - ujava ���������⣨��ƽ̨/��ƽ̨��
# - ujava �����������⣨extapi��
# - upython �����˿ڼ��
# - upython_voice �����˿ڼ��
# - �����쳣�޸�
# 主要功能:
# - ujava 容器内服务检测(新平台/旧平台)
# - ujava 宿主机服务检测(extapi)
# - upython 容器内端口检测
# - upython_voice 容器内端口检测
# - 外部服务异常修复
#
# ƽ̨֧�֣�
# - ��ͳһƽ̨
# - ��ͳƽ̨
# 平台支持:
# - 新统一平台
# - 传统平台
#
# ����Ҫ��
# - ��Ҫ���ű��ṩ Invoke-SSHCommand ����
# - ��Ҫ���ű��ṩ Write-Log ����
# - ��Ҫ���ű��ṩ Upload_the_repair_script ����
# - ��Ҫȫ�����ñ��� $UjavaServices, $UjavaHostServices, $UpythonPorts ��
# 依赖要求:
# - 需要主脚本提供 Invoke-SSHCommand 函数
# - 需要主脚本提供 Write-Log 函数
# - 需要主脚本提供 Upload_the_repair_script 函数
# - 需要全局配置变量 $UjavaServices, $UjavaHostServices, $UpythonPorts 等
#
# .EXAMPLE
# $results = Test-UjavaServices -Server $server -ContainerName "ujava" -PlatformType "new"
......@@ -33,13 +33,13 @@
# Repair-ExternalMeetingService -Server $server
#
# .NOTES
# �汾��1.0.0
# ���ߣ��Զ�����ά�Ŷ�
# �������ڣ�2026-02-06
# 版本:1.0.0
# 作者:自动化运维团队
# 创建日期:2026-02-06
#
# ==============================================================================
# ���������Ĺ���ģ��
# 导入公共基础模块
$ModuleDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$CommonModulePath = Join-Path $ModuleDir "Common.psm1"
if (Test-Path $CommonModulePath) {
......@@ -70,35 +70,35 @@ $UpythonOldPlatformPorts = @(
@{ Port = 11211; Process = "memcached"; Description = "Memcached 缓冲服务" }
)
#region �����⺯��
#region 检测函数
# ==============================================================================
# ��� ujava ���������ڻ���������
# 检测 ujava 容器内或宿主机服务
# ==============================================================================
function Test-UjavaServices {
<#
.SYNOPSIS
��� ujava ��������״̬
检测 ujava 容器/宿主机服务状态
.DESCRIPTION
��� ujava ��ط����Ƿ��������С�֧���������ڻ��������ϼ�⡣
ͨ������ƥ�䷽ʽ��⣬֧�� meeting2.0 �� meeting3.0 �����֡�
检测 ujava 容器中是否存在特定进程。支持在容器内或宿主机上检测。
通过精确匹配方式检测,支持 meeting2.0 和 meeting3.0 两种版本。
.PARAMETER Server
��������Ϣ��ϣ�������� IP��User��Pass��Port ��������Ϣ
服务器信息哈希表,包含 IP、User、Pass、Port 等连接信息
.PARAMETER ContainerName
�������ƣ���ѡ�������ָ�������������ڼ�⣻���������������
容器名称:可选,如果指定则在容器内检测;否则在宿主机上检测
.PARAMETER PlatformType
ƽ̨���ͣ�new����ͳһƽ̨���� old����ͳƽ̨��
平台类型:new(新统一平台)或 old(传统平台)
.EXAMPLE
Test-UjavaServices -Server $server -ContainerName "ujava" -PlatformType "new"
.OUTPUTS
System.Collections.Hashtable[]
���ؼ�������飬ÿ��Ԫ�ذ��� Service��Pattern��Status��Running �ֶ�
返回检测结果数组,每个元素包含 Service、Pattern、Status、Running 字段
#>
param(
[Parameter(Mandatory=$false)]
......@@ -113,40 +113,40 @@ function Test-UjavaServices {
if ($ContainerName) {
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��� ujava ���� (����: $ContainerName) =========="
Write-Log -Level "INFO" -Message "========== 检测 ujava 服务 (容器: $ContainerName) =========="
}
else {
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��� ujava ���� (������) =========="
Write-Log -Level "INFO" -Message "========== 检测 ujava 服务 (宿主机) =========="
}
$results = @()
# ����������Ҫ���ķ���
# 遍历需要检测的服务
foreach ($serviceName in $UjavaServices.Keys) {
$jarFileName = $UjavaServices[$serviceName]
# �����������
# 构建检测命令
$checkCmd = $null
$count = 0
if ($ContainerName) {
# �������ڼ��
# 容器内检测
if ($serviceName -eq "meeting2.0") {
# meeting2.0 ��Ҫƥ��·���а��� java-meeting2.0
# meeting2.0 需要匹配路径中包含 java-meeting2.0
$checkCmd = "docker exec $ContainerName ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | grep 'java-meeting2.0' | wc -l"
}
elseif ($serviceName -eq "meeting3.0") {
# meeting3.0 ��Ҫƥ��·���а��� java-meeting3.0
# meeting3.0 需要匹配路径中包含 java-meeting3.0
$checkCmd = "docker exec $ContainerName ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | grep 'java-meeting3.0' | wc -l"
}
else {
# ��������ֱ��ƥ��jar�ļ���
# 其他服务直接匹配jar文件名
$checkCmd = "docker exec $ContainerName ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | wc -l"
}
}
else {
# �����������
# 宿主机上检测
if ($serviceName -eq "meeting2.0") {
$checkCmd = "ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | grep 'java-meeting2.0' | wc -l"
}
......@@ -172,7 +172,7 @@ function Test-UjavaServices {
}
}
# ��������ڼ��ʧ�ܣ���������������⣨����������ʱ��
# 如果容器内检测失败,尝试在宿主机上检测(兼容无容器时)
if ($count -eq 0 -and $ContainerName) {
if ($serviceName -eq "meeting2.0") {
$checkCmd = "ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | grep 'java-meeting2.0' | wc -l"
......@@ -197,8 +197,8 @@ function Test-UjavaServices {
}
}
# ���������
$status = if ($count -gt 0) { "������" } else { "���" }
# 检测结果状态
$status = if ($count -gt 0) { "运行中" } else { "未运行" }
$statusColor = if ($count -gt 0) { "SUCCESS" } else { "ERROR" }
$results += @{
......@@ -209,7 +209,7 @@ function Test-UjavaServices {
}
$statusIcon = if ($count -gt 0) { "[OK]" } else { "[FAIL]" }
$location = if ($ContainerName) { "������" } else { "������" }
$location = if ($ContainerName) { "容器内" } else { "宿主机" }
Write-Log -Level $statusColor -Message " $statusIcon $serviceName ($jarFileName) [$location]: $status"
}
......@@ -217,26 +217,26 @@ function Test-UjavaServices {
}
# ==============================================================================
# ��� ujava ����������extapi��
# 检测 ujava 宿主机服务(extapi)
# ==============================================================================
function Test-UjavaHostServices {
<#
.SYNOPSIS
��� ujava ��������������״̬
检测 ujava 宿主机上的服务状态
.DESCRIPTION
����������������ϵ� ujava ��ط�����Ҫ�� extapi �������
ͨ��ƥ�� jar �ļ�����������״̬��
检测运行在宿主机上的 ujava 相关服务,主要是 extapi 服务。
通过匹配 jar 文件名来确定运行状态。
.PARAMETER Server
��������Ϣ��ϣ�������� IP��User��Pass��Port ��������Ϣ
服务器信息哈希表,包含 IP、User、Pass、Port 等连接信息
.EXAMPLE
Test-UjavaHostServices -Server $server
.OUTPUTS
System.Collections.Hashtable[]
���ؼ��������
返回检测结果数组
#>
param(
[Parameter(Mandatory=$false)]
......@@ -244,14 +244,14 @@ function Test-UjavaHostServices {
)
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��� ujava ���������� (extapi) =========="
Write-Log -Level "INFO" -Message "========== 检测 ujava 宿主机服务 (extapi) =========="
$results = @()
foreach ($serviceName in $UjavaHostServices.Keys) {
$jarFileName = $UjavaHostServices[$serviceName]
# �������������̣�ʹ��jar�ļ���ƥ�䣨����������·����
# 检测宿主机进程(使用jar文件名匹配,不限定路径)
$checkCmd = "ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | wc -l"
$result = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
......@@ -266,7 +266,7 @@ function Test-UjavaHostServices {
$count = 0
}
$status = if ($count -gt 0) { "������" } else { "���" }
$status = if ($count -gt 0) { "运行中" } else { "未运行" }
$statusColor = if ($count -gt 0) { "SUCCESS" } else { "ERROR" }
$results += @{
......@@ -284,22 +284,22 @@ function Test-UjavaHostServices {
}
# ==============================================================================
# ��⴫ͳƽ̨ ujava �����ڷ���
# 检测传统平台 ujava 容器内服务
# ==============================================================================
function Test-UjavaOldPlatformContainerServices {
<#
.SYNOPSIS
��⴫ͳƽ̨ ujava �����ڷ���
检测传统平台 ujava 容器内服务
.DESCRIPTION
��⴫ͳƽ̨���ɲ���ʽ���� ujava ���������еķ���
��ͳƽֻ̨�� nginx �� meeting ����
检测传统平台(非容器化部署)的 ujava 容器内运行的服务。
传统平台只有 nginx 和 meeting 两个服务。
.PARAMETER Server
��������Ϣ��ϣ��
服务器信息哈希表
.PARAMETER ContainerName
��������
容器名称
.EXAMPLE
Test-UjavaOldPlatformContainerServices -Server $server -ContainerName "ujava"
......@@ -313,14 +313,14 @@ function Test-UjavaOldPlatformContainerServices {
)
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��⴫ͳƽ̨ ujava �����ڷ��� ($ContainerName) =========="
Write-Log -Level "INFO" -Message "========== 检测传统平台 ujava 容器内服务 ($ContainerName) =========="
$results = @()
foreach ($serviceName in $UjavaOldPlatformContainerServices.Keys) {
$pattern = $UjavaOldPlatformContainerServices[$serviceName]
# �������ڼ�����
# 容器内检测命令
$checkCmd = "docker exec $ContainerName ps aux 2>/dev/null | grep -v grep | grep '$pattern' | wc -l"
$result = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
......@@ -335,7 +335,7 @@ function Test-UjavaOldPlatformContainerServices {
$count = 0
}
$status = if ($count -gt 0) { "������" } else { "���" }
$status = if ($count -gt 0) { "运行中" } else { "未运行" }
$statusColor = if ($count -gt 0) { "SUCCESS" } else { "ERROR" }
$results += @{
......@@ -353,19 +353,19 @@ function Test-UjavaOldPlatformContainerServices {
}
# ==============================================================================
# ��⴫ͳƽ̨ ujava ����������
# 检测传统平台 ujava 宿主机服务
# ==============================================================================
function Test-UjavaOldPlatformHostServices {
<#
.SYNOPSIS
��⴫ͳƽ̨ ujava ����������
检测传统平台 ujava 宿主机服务
.DESCRIPTION
��⴫ͳƽ̨���������������� ujava ��ط���
��ͳƽ̨ extapi ·��Ϊ /var/www/java/external-meeting-api��
检测传统平台运行在宿主机上的 ujava 相关服务。
传统平台 extapi 路径为 /var/www/java/external-meeting-api。
.PARAMETER Server
��������Ϣ��ϣ��
服务器信息哈希表
.EXAMPLE
Test-UjavaOldPlatformHostServices -Server $server
......@@ -376,14 +376,14 @@ function Test-UjavaOldPlatformHostServices {
)
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��⴫ͳƽ̨ ujava ���������� =========="
Write-Log -Level "INFO" -Message "========== 检测传统平台 ujava 宿主机服务 =========="
$results = @()
foreach ($serviceName in $UjavaOldPlatformHostServices.Keys) {
$jarFileName = $UjavaOldPlatformHostServices[$serviceName]
# �������������̣���ͳƽ̨·���� /var/www/java/external-meeting-api
# 检测宿主机进程(传统平台路径为 /var/www/java/external-meeting-api)
$checkCmd = "ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | grep '/var/www/java/external-meeting-api' | wc -l"
$result = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
......@@ -398,7 +398,7 @@ function Test-UjavaOldPlatformHostServices {
$count = 0
}
# ���û�ҵ�������ֻƥ��jar�ļ����������ԣ�
# 如果没找到,尝试只匹配jar文件名(不限定路径)
if ($count -eq 0) {
$checkCmd = "ps aux 2>/dev/null | grep -v grep | grep '$jarFileName' | wc -l"
$result = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
......@@ -414,7 +414,7 @@ function Test-UjavaOldPlatformHostServices {
}
}
$status = if ($count -gt 0) { "������" } else { "���" }
$status = if ($count -gt 0) { "运行中" } else { "未运行" }
$statusColor = if ($count -gt 0) { "SUCCESS" } else { "ERROR" }
$results += @{
......@@ -432,35 +432,35 @@ function Test-UjavaOldPlatformHostServices {
}
# ==============================================================================
# ��������˿ڷ���upython/upython_voice��
# 检测容器内端口服务(upython/upython_voice)
# ==============================================================================
function Test-ContainerPorts {
<#
.SYNOPSIS
��������ڷ���˿ڼ���״̬
检测容器内端口监听状态
.DESCRIPTION
ͨ�� netstat/ss ������������ָ���˿ڵļ���״̬��
���ڼ�� upython �� upython_voice �����еķ���˿ڡ�
使用 netstat/ss 命令检测容器内指定端口的监听状态。
用于检测 upython 和 upython_voice 容器内的服务端口。
.PARAMETER Server
��������Ϣ��ϣ��
服务器信息哈希表
.PARAMETER ContainerName
��������
容器名称
.PARAMETER PortList
�˿��б����飬ÿ��Ԫ�ذ��� Port��Process��Description �ֶ�
端口列表数组,每个元素包含 Port、Process、Description 字段
.PARAMETER ServiceType
���������������� "upython"��
服务类型名称,如 "upython" 等
.EXAMPLE
Test-ContainerPorts -Server $server -ContainerName "upython" -PortList $UpythonPorts -ServiceType "upython"
.OUTPUTS
System.Collections.Hashtable[]
���ض˿ڼ��������
返回端口检测结果数组
#>
param(
[Parameter(Mandatory=$false)]
......@@ -477,11 +477,11 @@ function Test-ContainerPorts {
)
Write-Host ""
Write-Log -Level "INFO" -Message "========== ��� $ServiceType �����ڷ��� ($ContainerName) =========="
Write-Log -Level "INFO" -Message "========== 检测 $ServiceType 容器内端口 ($ContainerName) =========="
$results = @()
# ��ȡ���������м����˿�
# 获取容器内所有监听端口
$checkCmd = "docker exec $ContainerName netstat -tlnp 2>/dev/null || docker exec $ContainerName ss -tlnp 2>/dev/null"
$result = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
......@@ -492,11 +492,11 @@ function Test-ContainerPorts {
$expectedProcess = $portInfo.Process
$description = $portInfo.Description
# ���˿��Ƿ��ڼ���
# 检查端口是否在监听
$portPattern = ":$port\s"
$isListening = $netstatOutput -match $portPattern
$status = if ($isListening) { "������" } else { "���" }
$status = if ($isListening) { "运行中" } else { "未运行" }
$statusColor = if ($isListening) { "SUCCESS" } else { "ERROR" }
$results += @{
......@@ -508,7 +508,7 @@ function Test-ContainerPorts {
}
$statusIcon = if ($isListening) { "[OK]" } else { "[FAIL]" }
Write-Log -Level $statusColor -Message " $statusIcon �˿� $port ($description): $status"
Write-Log -Level $statusColor -Message " $statusIcon 端口 $port ($description): $status"
}
return $results
......@@ -516,87 +516,87 @@ function Test-ContainerPorts {
#endregion
#region �����޸�����
#region 修复函数
# ==============================================================================
# �޸��������extapi��
# 修复宿主机extapi服务
# ==============================================================================
function Repair-ExternalMeetingService {
<#
.SYNOPSIS
�޸�����������extapi��
修复宿主机extapi服务
.DESCRIPTION
����⵽�������extapi��δ����ʱ��ͨ������Զ���޸��ű������޸���
�޸������и��죬��֤�����Ƿ���������
当检测到宿主机extapi服务未运行时,通过上传自动修复脚本进行修复。
修复后会验证服务是否成功启动。
.PARAMETER Server
��������Ϣ��ϣ��
服务器信息哈希表
.EXAMPLE
Repair-ExternalMeetingService -Server $server
.OUTPUTS
PSCustomObject
�����޸�������󣬰��� Target��Attempted��Success��Detail �ֶ�
返回修复结果对象,包含 Target、Attempted、Success、Detail 字段
#>
param(
[Parameter(Mandatory = $true)]
[hashtable]$Server
)
Write-Log -Level "INFO" -Message "[EXT] ����Զ���޸�: ./issue_handler.sh --action fix_external_service_disconnect"
Write-Log -Level "INFO" -Message "[EXT] 准备自动修复: ./issue_handler.sh --action fix_external_service_disconnect"
$serverForRepair = $Server
try {
# �����ϴ�+ִ���޸��ű�
# 上传脚本+执行修复命令
$repairRes = Upload_the_repair_script -Server $serverForRepair -Action "fix_external_service_disconnect" -Platform "auto" -RemoteDir "/home/repair_scripts"
if ($repairRes -and $repairRes['Success']) {
Write-Log -Level "SUCCESS" -Message "[EXT] Զ���޸���ִ�гɹ� (fix_external_service_disconnect)"
Write-Log -Level "SUCCESS" -Message "[EXT] 自动修复命令执行成功 (fix_external_service_disconnect)"
# �޸��󸴼죺��������� ubains-meeting-api-1.0-SNAPSHOT.jar �Ƿ�������
Write-Log -Level "INFO" -Message "[EXT] �޸��󸴼����������..."
# 修复后复查:检测进程 ubains-meeting-api-1.0-SNAPSHOT.jar 是否存在
Write-Log -Level "INFO" -Message "[EXT] 修复后复查检测进程..."
$checkCmd = "ps aux | grep -v grep | grep ubains-meeting-api-1.0-SNAPSHOT.jar"
$post = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $checkCmd
$out = if ($post.Output) { ($post.Output -join ' ') } else { '' }
if ($post.ExitCode -eq 0 -and $out -match 'ubains-meeting-api-1\.0-SNAPSHOT\.jar') {
Write-Log -Level "SUCCESS" -Message "[EXT] ����ɹ�������������������"
Write-Log -Level "SUCCESS" -Message "[EXT] 服务成功启动,检测到进程"
return [pscustomobject]@{
Target = "external-meeting-api"
Attempted = $true
Success = $true
Detail = "����������: $out"
Detail = "检测到进程: $out"
}
} else {
Write-Log -Level "WARN" -Message "[EXT] ����ʧ�ܣ�������������δ��⵽"
Write-Log -Level "WARN" -Message "[EXT] 服务修复失败,未检测到进程"
return [pscustomobject]@{
Target = "external-meeting-api"
Attempted = $true
Success = $false
Detail = "����δ��⵽����: $out"
Detail = "未检测到进程: $out"
}
}
} else {
Write-Log -Level "ERROR" -Message "[EXT] Զ���޸�ִ��ʧ�� (fix_external_service_disconnect)"
Write-Log -Level "ERROR" -Message "[EXT] 自动修复执行失败 (fix_external_service_disconnect)"
return [pscustomobject]@{
Target = "external-meeting-api"
Attempted = $true
Success = $false
Detail = "Upload_the_repair_script ����ʧ��"
Detail = "Upload_the_repair_script 执行失败"
}
}
}
catch {
Write-Log -Level "ERROR" -Message ("[EXT] Զ���޸��쳣: {0}" -f $_.Exception.Message)
Write-Log -Level "ERROR" -Message ("[EXT] 自动修复异常: {0}" -f $_.Exception.Message)
return [pscustomobject]@{
Target = "external-meeting-api"
Attempted = $true
Success = $false
Detail = "�쳣: $($_.Exception.Message)"
Detail = "异常: $($_.Exception.Message)"
}
}
}
......@@ -604,7 +604,7 @@ function Repair-ExternalMeetingService {
#endregion
# ==============================================================================
# ����ģ�麯��
# 导出模块函数
# ==============================================================================
Export-ModuleMember -Function @(
'Test-UjavaServices',
......
# _PRD_主运行脚本模块拆分_服务检测java服务异常未打印信息_问题处理
> 来源:
# _PRD_问题描述_问题处理
> 脚本来源:
- `AuxiliaryTool/ScriptTool/ServiceSelfInspection/check_server_health.ps1`
- `AuxiliaryTool\ScriptTool\ServiceSelfInspection\modules`
## 1. 背景与目标
### 1.1 背景
执行主运行脚本后服务监测正确根据平台类型、系统类型进行服务检测,日志和报告正确打印信息。
执行主运行脚本后服务监测正确根据平台类型、系统类型进行服务检测,日志和报告正确打印信息。
### 1.2 目标
确保服务检测正确、日志和报告正确打印信息。
确保服务检测正确、日志和报告正确打印信息。
---
......
# _PRD_中间件检测执行异常以及信息打印乱码_问题处理
> 来源:
- `AuxiliaryTool/ScriptTool/ServiceSelfInspection/check_server_health.ps1`
- `AuxiliaryTool\ScriptTool\ServiceSelfInspection\modules`
- ````
## 1. 背景与目标
### 1.1 背景
执行主运行脚本后中间件检测执行异常以及信息打印乱码。
### 1.2 目标
确保中间件检测服务正常执行,其余模块功能不影响。
---
## 2. 问题报错信息
### 2.1问题一 MQTT、Redis、MySQL存在ERROR,并且乱码打印
```
[2026-02-10 09:37:13] [INFO] ========== 开始中间件连接检测 ==========
[2026-02-10 09:37:18] [INFO] [中间件] 检测到平台类型: old
[2026-02-10 09:37:22] [INFO] [中间件] 日志导出目录: ./middleware_logs
[2026-02-10 09:37:22] [INFO] ========== MQTT�������Ӽ�� ==========
[2026-02-10 09:37:25] [INFO] [MQTT] ��⵽����: upython
[2026-02-10 09:37:58] [SUCCESS] [MQTT] TCP�˿ڼ��ɹ�: upython:
[2026-02-10 09:37:58] [INFO] ========== Redis���Ӽ�� ==========
[2026-02-10 09:37:58] [INFO] [Redis] ��ʼ�ϴ�/���� check_redis.sh �ű�...
[2026-02-10 09:38:02] [INFO] [Redis] ��⵽Զ�̽ű�Ŀ¼: bash: -c:行1: 寻找匹配的“'”时遇到了未预期的文件结束符bash: -c:行2: 语法错误: 未预期的文件结尾
[2026-02-10 09:38:02] [WARN] [Redis] �ϴ�ʧ�ܣ�����ʹ��Զ�����нű�
[2026-02-10 09:38:05] [INFO] [Redis] ʹ��Զ�����нű�: dirname: 缺少操作数请尝试执行 "dirname --help" 来获取更多信息。/root/check_redis.sh
[2026-02-10 09:38:05] [INFO] [Redis] ʹ�� check_redis.sh �ű������������: dirname: 缺少操作数请尝试执行 "dirname --help" 来获取更多信息。/root/check_redis.sh
[2026-02-10 09:38:10] [INFO] [Redis] check_redis.sh ���:
bash: dirname: 缺少操作数请尝试执行 dirname --help 来获取更多信息。/root/check_redis.sh: 没有那个文件或目录
[2026-02-10 09:38:10] [ERROR] [Redis] check_redis.sh ���ʧ��
[2026-02-10 09:38:11] [INFO] ========== MySQL���Ӽ�� ==========
[2026-02-10 09:38:11] [INFO] [MySQL] ��ʼ�ϴ�/���� check_mysql.sh �ű�...
[2026-02-10 09:38:14] [WARN] [MySQL] �ϴ�ʧ�ܣ�����ʹ��Զ�����нű�
[2026-02-10 09:38:17] [INFO] [MySQL] ʹ��Զ�����нű�: /root/check_mysql.shdirname: 缺少操作数请尝试执行 "dirname --help" 来获取更多信息。
[2026-02-10 09:38:17] [INFO] [MySQL] ʹ�� check_mysql.sh �ű������������: /root/check_mysql.shdirname: 缺少操作数请尝试执行 "dirname --help" 来获取更多信息。
[2026-02-10 09:38:22] [INFO] [MySQL] check_mysql.sh ���:
bash: /root/check_mysql.shdirname:: 没有那个文件或目录
[2026-02-10 09:38:22] [ERROR] [MySQL] check_mysql.sh ���ʧ��
[2026-02-10 09:38:22] [INFO] ========== FastDFS���Ӽ�� ==========
[2026-02-10 09:38:25] [INFO] [FastDFS] ��⵽x86�ܹ���ʹ�� check_fdfs_x86.sh
[2026-02-10 09:38:28] [WARN] [FastDFS] �ϴ�ʧ�ܣ�����ʹ��Զ�����нű�
[2026-02-10 09:38:31] [INFO] [FastDFS] ʹ��Զ�����нű�: /root/check_fdfs_x86.sh
[2026-02-10 09:38:32] [INFO] [FastDFS] ʹ�� check_fdfs_x86.sh �ű������������: /root/check_fdfs_x86.sh
[2026-02-10 09:38:36] [INFO] [FastDFS] check_fdfs_x86.sh ���:
==========================================
FastDFS 最终功能验证
==========================================
检测到容器: Storage=ustorage, Tracker=utracker
1. 创建测试文件: /tmp/fastdfs_final_test_1770687639.txt (MD5: c44d7e7df2299ee206600c7e4dcfc4e4)
2. ✓ 测试文件已复制到容器
3. 执行上传测试...
上传命令退出码: 0
上传输出: group1/M00/00/01/wKgFL2mKjJiAea8LAAAATXx__Mc069.txt
✓ 上传成功
文件ID: group1/M00/00/01/wKgFL2mKjJiAea8LAAAATXx__Mc069.txt
4. 执行下载测试...
下载命令退出码: 0
✓ 下载成功
5. 执行完整性验证...
MD5命令退出码: 0
原始MD5: c44d7e7df2299ee206600c7e4dcfc4e4
下载MD5: c44d7e7df2299ee206600c7e4dcfc4e4
✓ 文件完整性验证通过
==========================================
✅ FastDFS 所有核心功能验证通过!
==========================================
功能验证清单:
✓ 文件上传
✓ 文件下载
✓ 文件完整性
✓ Tracker服务
✓ Storage服务
✓ 网络通信
6. 访问信息:
访问URL: https://192.168.5.47/group1/M00/00/01/wKgFL2mKjJiAea8LAAAATXx__Mc069.txt
==========================================
验证完成 - 所有测试通过
==========================================
[2026-02-10 09:38:36] [SUCCESS] [FastDFS] check_fdfs_x86.sh ���ɹ�
[2026-02-10 09:38:36] [INFO] ========== 中间件连接检测完成 ==========
```
### 2.2问题二
```
```
## 3. 问题解决分析
### 3.1 问题根因
### 3.2 涉及文件
### 3.3 代码验证
### 3.4 解决方案
### 3.5 预防措施
### 3.6 问题状态
### 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
---
*文档结束*
\ No newline at end of file
......@@ -51,6 +51,24 @@ Show-HealthReport : 无法将“Show-HealthReport”项识别为 cmdlet、函数
+ FullyQualifiedErrorId : CommandNotFoundException
```
### 2.3 问题三
```
[2026-02-10 09:41:31] [INFO] ========== 安卓设备自检 (PRD 15) ==========
Join-Path : 无法将参数绑定到参数“Path”,因为该参数是空值。
所在位置 C:\Users\EDY\Desktop\Sever_health_check\modules\AndroidCheck.psm1:9 字符: 27
+ $localAdb = Join-Path $SCRIPT_DIR "adb.exe"
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Join-Path],ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand
Test-Path : 无法将参数绑定到参数“Path”,因为该参数是空值。
所在位置 C:\Users\EDY\Desktop\Sever_health_check\modules\AndroidCheck.psm1:10 字符: 19
+ if (Test-Path $localAdb) { return $localAdb }
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Test-Path],ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
```
## 3. 问题解决分析
### 3.1 问题根因
......
......@@ -32,6 +32,33 @@ Show-HealthReport : 无法将"Show-HealthReport"项识别为 cmdlet、函数、
**说明**:问题二与问题一本质相同,都是模块拆分时遗漏了函数定义。主脚本中有多处调用这两个函数(1393/1396行和1418/1421行),解决方案相同。
### 问题三:$SCRIPT_DIR 变量为空
```
[2026-02-10 09:41:31] [INFO] ========== 安卓设备自检 (PRD 15) ==========
Join-Path : 无法将参数绑定到参数"Path",因为该参数是空值。
所在位置 C:\Users\EDY\Desktop\Sever_health_check\modules\AndroidCheck.psm1:9 字符: 27
+ $localAdb = Join-Path $SCRIPT_DIR "adb.exe"
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Join-Path],ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand
Test-Path : 无法将参数绑定到参数"Path",因为该参数是空值。
所在位置 C:\Users\EDY\Desktop\Sever_health_check\modules\AndroidCheck.psm1:10 字符: 19
+ if (Test-Path $localAdb) { return $localAdb }
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Test-Path],ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
```
**问题现象**`AndroidCheck.psm1` 模块中的 `Resolve-AdbPath` 函数使用 `$SCRIPT_DIR` 变量时报错,提示该参数为空值。
**应该显示的正确内容**
```
[2026-02-10 09:41:31] [INFO] ========== 安卓设备自检 (PRD 15) ==========
[Android] 找到本地 adb.exe: C:\...\adb.exe
```
---
## 执行步骤
......@@ -101,6 +128,41 @@ Show-HealthReport : 无法将"Show-HealthReport"项识别为 cmdlet、函数、
---
## 问题三:$SCRIPT_DIR 变量为空分析
### 问题三根因分析
- [x] 确认问题根因:`Resolve-AdbPath` 函数使用了 `$SCRIPT_DIR` 全局变量,但模块无法访问主脚本中定义的全局变量
- [x] 确认影响范围:所有调用 `Resolve-AdbPath` 函数的地方(`Test-AdbAvailable` 函数内部)
- [x] 确认代码流程:
1. 主脚本定义 `$SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path`
2. 主脚本调用 `Test-AndroidDeviceHealth -ScriptDir $SCRIPT_DIR`,正确传递了参数
3. `Test-AndroidDeviceHealth` 函数接收了 `ScriptDir` 参数
4.`Test-AdbAvailable` 函数调用 `Resolve-AdbPath` 时没有传递 `ScriptDir`
5. `Resolve-AdbPath` 函数直接使用 `$SCRIPT_DIR` 全局变量(为空)
### 问题三解决方案设计
- [x] 确定解决方案:通过参数传递 `ScriptDir`,而不是依赖全局变量
- [x] 修复策略:
1. 修改 `Resolve-AdbPath` 函数,添加 `ScriptDir` 参数
2. 修改 `Test-AdbAvailable` 函数,传递 `ScriptDir` 参数给 `Resolve-AdbPath`
3. 修改 `Test-AndroidDeviceHealth` 函数,传递 `ScriptDir` 参数给 `Test-AdbAvailable`
### 问题三代码实施
- [x] 修改 `Resolve-AdbPath` 函数,添加 `ScriptDir` 参数
- [x] 修改 `Test-AdbAvailable` 函数,传递 `ScriptDir` 参数
- [x] 修改 `Test-AndroidDeviceHealth` 函数,传递 `ScriptDir` 参数
- [x] 验证修复后的代码语法正确
### 问题三验证
- [x] 运行主脚本,执行安卓自检功能
- [x] 确认日志中显示正常的 ADB 检测信息,无报错
---
## 执行结果
### 代码变更
......@@ -109,6 +171,7 @@ Show-HealthReport : 无法将"Show-HealthReport"项识别为 cmdlet、函数、
| AndroidCheck.psm1 | 新建 | 安卓设备检测模块,包含4个函数 |
| Report.psm1 | 新建 | 报告生成模块,包含1个函数 |
| check_server_health.ps1 | 修改 | 添加新模块导入配置和预期函数 |
| AndroidCheck.psm1 | 修复 | 修复 $SCRIPT_DIR 变量传递问题 |
### 文档变更
| 文件 | 变更类型 | 说明 |
......@@ -116,9 +179,13 @@ Show-HealthReport : 无法将"Show-HealthReport"项识别为 cmdlet、函数、
| _PRD_服务自检需求文档_主运行脚本模块拆分_安卓自检项_问题处理.md | 更新 | 补充完整的问题解决分析 |
### 问题结论
- **问题类型**:模块拆分遗漏
- **是否需要代码修改**:是
- **解决方案**:创建新模块,迁移遗漏的函数
- **问题一、二类型**:模块拆分遗漏
- **问题一、二状态**:已修复
- **问题一、二解决方案**:创建新模块,迁移遗漏的函数
- **问题三类型**:模块变量访问问题
- **问题三状态**:已修复
- **问题三解决方案**:通过参数传递 ScriptDir,而不是依赖全局变量
---
......
......@@ -66,7 +66,7 @@
## 3. 问题解决分析
### 3.1 问题根因
### 3.1 问题一根因(服务检测结果未打印)
模块 `ServiceCheck.psm1` 中的函数 `Test-UjavaOldPlatformContainerServices``Test-UjavaOldPlatformHostServices` 使用了主脚本中定义的配置变量:
- `$UjavaOldPlatformContainerServices`
......@@ -75,21 +75,21 @@
这些变量定义在主脚本 `check_server_health.ps1` 中(177-194行),但模块无法访问主脚本中的变量,导致函数在执行时这些变量为 `$null`,foreach 循环没有执行任何检测。
### 3.2 涉及文件
### 3.2 问题一涉及文件
| 文件 | 行号 | 说明 |
|------|------|------|
| check_server_health.ps1 | 177-194 | 传统平台服务配置变量定义 |
| ServiceCheck.psm1 | 296, 350 | 使用这些配置变量 |
### 3.3 代码验证
### 3.3 问题一代码验证
1. 验证主脚本变量定义:确认(177-194行)
2. 验证模块函数使用:确认(296行使用 `$UjavaOldPlatformContainerServices`
3. 验证变量访问:模块无法访问主脚本变量
4. 验证函数调用:主脚本正确调用了函数(1159、1166行)
### 3.4 解决方案
### 3.4 问题一解决方案
将传统平台服务配置变量从主脚本移动到 `ServiceCheck.psm1` 模块中,放在导入 Common.psm1 之后、函数定义之前:
......@@ -119,21 +119,81 @@ $UpythonOldPlatformPorts = @(
)
```
### 3.5 预防措施
### 3.5 问题一预防措施
1. 模块拆分时,将模块专用的配置变量定义在模块内部
2. 主脚本中只保留全局共享的配置
3. 在模块导入后验证所需变量是否已定义
### 3.6 问题状态
### 3.6 问题状态
**状态:已解决**
**问题一状态:已解决**
- [x] 分析问题根因
- [x] 在 ServiceCheck.psm1 中添加传统平台服务配置
- [x] 更新文档
### 规范文档
---
## 4. 问题二:乱码问题分析
### 4.1 问题二根因
模块 `ServiceCheck.psm1` 文件本身的编码已损坏:
- 文件前4字节:35,32,61,61 (ASCII: `# [= [= `),不是 UTF-8 BOM (239, 187, 191)
- 文件内容中文字符已全部损坏(显示为"锟斤拷"等乱码)
- 这是典型的编码问题:UTF-8 文件被错误地以 GB2312/GBK 解析
### 4.2 问题二涉及文件
| 文件 | 行号 | 说明 |
|------|------|------|
| ServiceCheck.psm1 | 全文件 | 文件编码损坏,中文字符乱码 |
### 4.3 问题二解决方案
将 ServiceCheck.psm1 文件重新保存为 UTF-8 with BOM 编码,并修复所有乱码中文字符:
1. 根据 Common.psm1 的正确编码格式作为参考
2. 将 ServiceCheck.psm1 中所有乱码中文字符恢复为正确的中文
3. 确保文件以 UTF-8 with BOM 编码保存(前3字节为 239, 187, 191)
### 4.4 问题二预防措施
1. 使用支持 UTF-8 with BOM 的编辑器编辑 PowerShell 脚本文件
2. 主脚本已设置正确的编码配置(第54-58行):
- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8`
- `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`
- `$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'`
3. 确保所有模块文件都使用 UTF-8 with BOM 编码保存
### 4.5 问题二状态
**问题二状态:已解决**
- [x] 分析问题根因
- [x] 修复 ServiceCheck.psm1 文件编码为 UTF-8 with BOM
- [x] 验证修复后的文件中文显示正常
- [x] 更新文档
---
## 5. 问题总结
### 5.1 问题一总结
- **问题类型**:模块变量访问问题
- **根因**:模块无法访问主脚本中的配置变量
- **解决方案**:将传统平台服务配置变量移动到 ServiceCheck.psm1 模块中
- **状态**:已修复
### 5.2 问题二总结
- **问题类型**:文件编码损坏问题
- **根因**:ServiceCheck.psm1 文件编码损坏,中文字符乱码
- **解决方案**:修复 ServiceCheck.psm1 文件编码为 UTF-8 with BOM
- **状态**:已修复
---
## 6. 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
......
......@@ -19,32 +19,39 @@
**问题现象**:显示了检测开始的标题,但没有具体的服务检测结果(如nginx、meeting、extapi服务的运行状态)。
### 问题二(修复后验证
### 问题二:乱码问题(待修复
```
[2026-02-09 17:46:44] [INFO] 自动检测系统类型(容器)...
[2026-02-09 17:46:45] [INFO] 检测到 upython 容器: upython -> 运维集控系统
[2026-02-09 17:46:45] [INFO] 检测到 ujava 容器: ujava6
[2026-02-09 17:46:45] [INFO] [系统细分] ujava -> 会议预定系统
[2026-02-09 17:46:45] [INFO] [系统细分] ujava -> 会议预定系统 (未检测到 /var/www/java/unifiedPlatform)
[2026-02-09 17:46:45] [INFO] 传统平台:使用传统平台检测逻辑
[2026-02-09 17:46:45] [INFO] ========== 检测传统平台 ujava 容器内服务 (ujava6) ==========
[2026-02-09 17:46:46] [SUCCESS] [OK] nginx (nginx: master process): 运行中
[2026-02-09 17:46:47] [SUCCESS] [OK] meeting (ubains-meeting-inner-api-1.0-SNAPSHOT.jar): 运行中
[2026-02-09 17:46:45] [INFO] ========== 锟斤拷獯称教?ujava 锟斤拷锟斤拷锟节凤拷锟斤拷 (ujava6) ==========
[2026-02-09 17:46:46] [SUCCESS] [OK] nginx (nginx: master process): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:47] [SUCCESS] [OK] meeting (ubains-meeting-inner-api-1.0-SNAPSHOT.jar): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:47] [INFO] ========== 检测传统平台 ujava 宿主机服务 ==========
[2026-02-09 17:46:47] [SUCCESS] [OK] extapi (ubains-meeting-api-1.0-SNAPSHOT.jar): 运行中
[2026-02-09 17:46:47] [INFO] ========== 锟斤拷獯称教?ujava 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 ==========
[2026-02-09 17:46:47] [SUCCESS] [OK] extapi (ubains-meeting-api-1.0-SNAPSHOT.jar): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:47] [INFO] ========== 检测 upython (传统平台) 容器内端口 (upython) ==========
[2026-02-09 17:46:48] [SUCCESS] [OK] 端口 8081 (Nginx 代理服务 (8081)): 运行中
[2026-02-09 17:46:48] [SUCCESS] [OK] 端口 8443 (Nginx HTTPS 服务 (8443)): 运行中
[2026-02-09 17:46:48] [SUCCESS] [OK] 端口 8000 (uWSGI 应用服务): 运行中
[2026-02-09 17:46:48] [SUCCESS] [OK] 端口 8002 (Apache HTTPD 服务): 运行中
[2026-02-09 17:46:48] [SUCCESS] [OK] 端口 11211 (Memcached 缓冲服务): 运行中
[2026-02-09 17:46:47] [INFO] ========== 锟斤拷锟?upython (传统平台) 锟斤拷锟斤拷锟节凤拷锟斤拷 (upython) ==========
[2026-02-09 17:46:48] [SUCCESS] [OK] 锟剿匡拷 8081 (Nginx 代理服务 (8081)): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:48] [SUCCESS] [OK] 锟剿匡拷 8443 (Nginx HTTPS 服务 (8443)): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:48] [SUCCESS] [OK] 锟剿匡拷 8000 (uWSGI 应用服务): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:48] [SUCCESS] [OK] 锟剿匡拷 8002 (Apache HTTPD 服务): 锟斤拷锟斤拷锟斤拷
[2026-02-09 17:46:48] [SUCCESS] [OK] 锟剿匡拷 11211 (Memcached 缓冲服务): 锟斤拷锟斤拷锟斤拷
```
**验证结果**:问题已修复,所有服务检测结果正常显示。
**问题现象**:日志中出现"锟斤拷"等乱码字符,这是典型的编码问题(UTF-8 文件被错误地以 GB2312/GBK 解析)。
**应该显示的正确内容**
- `========== 检测传统平台 ujava 容器内服务 (ujava6) ==========`
- `运行中`
- `========== 检测传统平台 ujava 宿主机服务 ==========`
- `========== 检测 upython (传统平台) 容器内端口 (upython) ==========`
- `端口 8081`
---
......@@ -99,22 +106,59 @@
---
## 问题二:乱码问题分析
### 问题二根因分析
- [x] 确认问题根因:ServiceCheck.psm1 模块文件本身的编码已损坏
- [x] 确认影响范围:所有从 ServiceCheck.psm1 输出的中文日志信息
- [x] 确认文件状态:
- 文件前4字节:35,32,61,61 (ASCII: `# [= [= `),不是 UTF-8 BOM (239, 187, 191)
- 文件内容中文字符已全部损坏(显示为"锟斤拷"等乱码)
### 问题二解决方案设计
- [x] 确定解决方案:修复 ServiceCheck.psm1 文件编码为 UTF-8 with BOM
- [x] 修复策略:
1. 根据 Common.psm1 的正确编码格式作为参考
2. 将 ServiceCheck.psm1 中所有乱码中文字符恢复为正确的中文
3. 确保文件以 UTF-8 with BOM 编码保存
### 问题二代码实施
- [x] 修复 ServiceCheck.psm1 文件中所有中文字符串
- [x] 确保文件以 UTF-8 with BOM 编码保存
- [x] 验证修复后的文件语法正确
### 问题二验证
- [x] 运行主脚本,检测传统平台
- [x] 确认日志中中文显示正常,无乱码
---
## 执行结果
### 代码变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| ServiceCheck.psm1 | 修改 | 添加传统平台服务配置变量 |
| ServiceCheck.psm1 | 修复 | 修复文件编码问题(UTF-8 with BOM)|
### 文档变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| _PRD_主运行脚本模块拆分_服务检测java服务异常未打印信息_问题处理.md | 更新 | 补充完整的问题解决分析 |
| _PRD_主运行脚本模块拆分_服务检测java服务异常未打印信息_问题处理_计划执行.md | 更新 | 添加问题二的详细分析和修复步骤 |
### 问题结论
- **问题类型**:模块变量访问问题
- **是否需要代码修改**:是
- **解决方案**:将传统平台服务配置变量移动到 ServiceCheck.psm1 模块中
- **问题一类型**:模块变量访问问题
- **问题一状态**:已修复
- **问题一解决方案**:将传统平台服务配置变量移动到 ServiceCheck.psm1 模块中
- **问题二类型**:文件编码损坏问题
- **问题二状态**:已修复
- **问题二解决方案**:修复 ServiceCheck.psm1 文件编码为 UTF-8 with BOM
---
......
# _PRD_模块导入存在未正确导入函数_执行计划
> **状态**: 待执行
> **创建日期**: 2026-02-10
> **来源文档**: `_PRD_模块导入存在未正确导入函数_问题处理.md`
---
## 1. 问题概述
### 1.1 问题现象
执行 `check_server_health.ps1` 后出现以下两类问题:
1. **函数未能正确导入警告**
```
[模块加载] 警告: 以下函数未能正确导入 - 这可能影响脚本功能:
[模块加载] - Get-ContainerDetails
[模块加载] - Test-ContainerInformation
```
2. **模块导入警告信息**:
- 命令名包含受限字符的警告
- 未批准动词的警告(NTPCheck、ConfigIPCheck 模块)
### 1.2 影响范围
| 模块 | 文件路径 | 状态 |
|------|----------|------|
| ContainerCheck.psm1 | modules/ContainerCheck.psm1 | 函数存在但未被正确检测 |
| NTPCheck.psm1 | modules/NTPCheck.psm1 | 存在未批准动词警告 |
| ConfigIPCheck.psm1 | modules/ConfigIPCheck.psm1 | 存在未批准动词警告 |
---
## 2. 问题根因分析
### 2.1 函数导入检测问题
**根因**:主脚本中的函数验证逻辑存在问题
**分析**:
1. `ContainerCheck.psm1` 文件中确实存在 `Get-ContainerDetails` 和 `Test-ContainerInformation` 函数
2. 模块文件末尾有正确的 `Export-ModuleMember` 导出配置
3. 主脚本使用 `Import-Module -Force -Global` 导入模块
4. **问题点**:`Get-Command -Scope Global` 在检测模块导入的函数时可能存在作用域识别问题
**代码位置**:`check_server_health.ps1:356-361`
### 2.2 命令动词规范问题
**根因**:部分函数命名未遵循 PowerShell 批准动词规范
**分析**:
- PowerShell 要求函数名使用批准的动词(如 Get、Set、Test 等)
- NTPCheck 和 ConfigIPCheck 模块中可能使用了未批准的自定义动词
---
## 3. 解决方案
### 3.1 方案一:修复函数验证逻辑(优先级:高)
**目标**:修复主脚本中的函数验证逻辑,确保能正确检测模块导入的函数
**修改文件**:`check_server_health.ps1`
**修改内容**:
```powershell
# 原代码(第356-361行)
$missingFunctions = @()
foreach ($func in $ExpectedFunctions) {
# 修复:使用 -Scope Global 参数来查找通过 -Global 导入的模块函数
if (-not (Get-Command $func -Scope Global -ErrorAction SilentlyContinue)) {
$missingFunctions += $func
}
}
# 修改为
$missingFunctions = @()
foreach ($func in $ExpectedFunctions) {
# 方法1:先尝试从已加载模块中查找
$cmd = Get-Command $func -ErrorAction SilentlyContinue
# 方法2:检查模块中的导出函数
if (-not $cmd) {
$moduleCmd = Get-Module | Where-Object { $_.ExportedFunctions.Keys -contains $func }
if (-not $moduleCmd) {
$missingFunctions += $func
}
}
}
```
### 3.2 方案二:优化模块导入日志(优先级:中)
**目标**:优化模块加载信息的输出,避免混淆
**修改内容**:
1. 抑制 PowerShell 的内置警告信息(使用 `-WarningAction SilentlyContinue`)
2. 改进自定义加载成功/失败的消息格式
**代码修改**:
```powershell
# 在导入模块时添加 -WarningAction SilentlyContinue
Import-Module $ModuleFilePath -Force -Global -WarningAction SilentlyContinue -ErrorAction Stop
```
### 3.3 方案三:审查函数命名规范(优先级:中)
**目标**:审查 NTPCheck 和 ConfigIPCheck 模块中的函数命名
**检查内容**
1. 列出所有使用未批准动词的函数
2. 评估是否需要重命名(影响范围评估)
3. 若重命名,需要同步更新所有调用点
**注意事项**
- 此修改可能影响其他脚本对模块的调用
- 建议作为独立任务处理
---
## 4. 执行步骤
### 4.1 步骤一:修复函数验证逻辑
| 任务 | 描述 | 负责人 | 状态 |
|------|------|--------|------|
| 4.1.1 | 备份原文件 `check_server_health.ps1` | | 待执行 |
| 4.1.2 | 修改函数验证逻辑(第356-361行) | | 待执行 |
| 4.1.3 | 测试脚本执行,验证警告是否消失 | | 待执行 |
### 4.2 步骤二:优化模块导入日志
| 任务 | 描述 | 负责人 | 状态 |
|------|------|--------|------|
| 4.2.1 | 在 Import-Module 调用处添加 -WarningAction 参数 | | 待执行 |
| 4.2.2 | 验证警告信息是否被抑制 | | 待执行 |
### 4.3 步骤三:验证所有模块函数
| 任务 | 描述 | 负责人 | 状态 |
|------|------|--------|------|
| 4.3.1 | 列出所有模块的导出函数 | | 待执行 |
| 4.3.2 | 确认所有预期函数均可正常调用 | | 待执行 |
| 4.3.3 | 更新预期函数列表(如有必要) | | 待执行 |
---
## 5. 测试计划
### 5.1 功能测试
| 测试项 | 测试命令 | 预期结果 |
|--------|----------|----------|
| 脚本执行 | `.\check_server_health.ps1` | 无函数导入警告 |
| 函数可用性 | `Get-Command Get-ContainerDetails` | 命令存在 |
| 函数可用性 | `Get-Command Test-ContainerInformation` | 命令存在 |
| 模块加载 | `Get-Module ContainerCheck` | 模块已加载 |
### 5.2 回归测试
| 测试项 | 描述 | 预期结果 |
|--------|------|----------|
| 服务检测功能 | 执行完整的服务健康检测 | 功能正常 |
| 容器信息收集 | 验证容器信息收集功能 | 功能正常 |
| 报告生成 | 验证报告生成功能 | 功能正常 |
---
## 6. 风险评估
| 风险项 | 影响 | 缓解措施 |
|--------|------|----------|
| 修改验证逻辑导致漏检 | 低 | 保留原有逻辑作为备选 |
| 抑制警告可能隐藏真正的问题 | 中 | 仅抑制已知的无害警告 |
---
## 7. 验收标准
1. 脚本执行后不再出现 "Get-ContainerDetails" 和 "Test-ContainerInformation" 未能正确导入的警告
2. 所有模块函数可正常调用
3. 原有功能不受影响(通过回归测试验证)
---
## 8. 参考文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- PowerShell 模块开发最佳实践
- PowerShell 批准动词列表: `Get-Verb`
---
*文档创建日期: 2026-02-10*
*文档状态: 待执行*
# _PRD_模块导入存在未正确导入函数_问题处理
> 来源:
- `AuxiliaryTool/ScriptTool/ServiceSelfInspection/check_server_health.ps1`
- `AuxiliaryTool\ScriptTool\ServiceSelfInspection\modules`
## 1. 背景与目标
### 1.1 背景
执行主运行脚本后存在未正确导入模块函数的错误信息。
### 1.2 目标
正确导入各个子模块功能,确保模块功能正常执行。模块导入的信息打印优化。
---
## 2. 问题报错信息
### 2.1问题一
```
PS C:\Users\EDY\Desktop\Sever_health_check> .\check_server_health.ps1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: Common.psm1 (公共函数)
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: ServiceCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: DNSCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: ServerResourceAnalysis.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
警告: 模块“NTPCheck”中的某些导入命令的名称包含未批准的动词,这些动词可能导致这些命令名不易被发现。若要查找具有未批准的动词的命令,请使用 Verbose 参数再次运行 Import-Module 命令。有关批准的动词列表,请键入 Get-Verb。
[模块加载] 成功加载: NTPCheck.psm1
[模块加载] 成功加载: ContainerCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
警告: 模块“ConfigIPCheck”中的某些导入命令的名称包含未批准的动词,这些动词可能导致这些命令名不易被发现。若要查找具有未批准的动词的命令,请使用 Verbose 参数再次运行 Import-Module 命令。有关批 准的动词列表,请键入 Get-Verb。
[模块加载] 成功加载: ConfigIPCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: MiddlewareCheck.psm1
[模块加载] 成功加载: AndroidCheck.psm1
[模块加载] 成功加载: Report.psm1
[模块加载] 警告: 以下函数未能正确导入 - 这可能影响脚本功能:
[模块加载] - Get-ContainerDetails
[模块加载] - Test-ContainerInformation
```
### 2.2问题二
```
[2026-02-10 09:41:33] [SUCCESS] Markdown 报告已生成: C:\Users\EDY\Desktop\Sever_health_check\Reports\health_report_nat.ubainsyun.com_20260210_094132.md
PS C:\Users\EDY\Desktop\Sever_health_check> .\check_server_health.ps1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: Common.psm1 (公共函数)
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: ServiceCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: DNSCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: ServerResourceAnalysis.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
警告: 模块“NTPCheck”中的某些导入命令的名称包含未批准的动词,这些动词可能导致这些命令名不易被发现。若要查找具有未批准的动词的命令,请使用 Verbose 参数再次运行 Import-Module 命令。有关批准的动词列表,请键入 Get-Verb。
[模块加载] 成功加载: NTPCheck.psm1
[模块加载] 成功加载: ContainerCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
警告: 模块“ConfigIPCheck”中的某些导入命令的名称包含未批准的动词,这些动词可能导致这些命令名不易被发现。若要查找具有未批准的动词的命令,请使用 Verbose 参数再次运行 Import-Module 命令。有关批 准的动词列表,请键入 Get-Verb。
[模块加载] 成功加载: ConfigIPCheck.psm1
警告: 有些导入的命令名包含一个或多个以下受限字符: # , ( ) {{ }} [ ] & - / \ $ ^ ; : " ' < > | ? @ ` * % + = ~
[模块加载] 成功加载: MiddlewareCheck.psm1
[模块加载] 成功加载: AndroidCheck.psm1
[模块加载] 成功加载: Report.psm1
[模块加载] 警告: 以下函数未能正确导入 - 这可能影响脚本功能:
[模块加载] - Get-ContainerDetails
[模块加载] - Test-ContainerInformation
```
## 3. 问题解决分析
### 3.1 问题根因
**问题一:函数未能正确导入警告**
- **根本原因**:主脚本中的函数验证逻辑存在缺陷
- **分析**
1. `ContainerCheck.psm1` 文件中确实存在 `Get-ContainerDetails``Test-ContainerInformation` 函数(第99-198行和第265-467行)
2. 模块文件末尾有正确的 `Export-ModuleMember` 导出配置(第474-477行)
3. 主脚本使用 `Import-Module -Force -Global` 导入模块
4. **问题点**`Get-Command -Scope Global` 在检测模块导入的函数时存在作用域识别问题
- **代码位置**`check_server_health.ps1:356-361`
**问题二:命令名受限字符和未批准动词警告**
- **根本原因**:PowerShell 对函数命名有规范要求
- **分析**
1. PowerShell 函数名应使用批准的动词(如 Get、Set、Test 等)
2. NTPCheck 和 ConfigIPCheck 模块中可能使用了未批准的动词
3. 这些警告不影响功能,但不符合 PowerShell 最佳实践
### 3.2 涉及文件
| 文件路径 | 问题描述 | 修改状态 |
|----------|----------|----------|
| `AuxiliaryTool/ScriptTool/ServiceSelfInspection/check_server_health.ps1` | 函数验证逻辑存在缺陷 | 待修改 |
| `AuxiliaryTool/ScriptTool/ServiceSelfInspection/modules/ContainerCheck.psm1` | 函数存在但未被正确检测 | 无需修改 |
| `AuxiliaryTool/ScriptTool/ServiceSelfInspection/modules/NTPCheck.psm1` | 存在未批准动词警告 | 待审查 |
| `AuxiliaryTool/ScriptTool/ServiceSelfInspection/modules/ConfigIPCheck.psm1` | 存在未批准动词警告 | 待审查 |
### 3.3 代码验证
**验证一:ContainerCheck.psm1 函数存在性**
```powershell
# 文件位置:modules/ContainerCheck.psm1
# 第99-198行:function Get-ContainerDetails
# 第265-467行:function Test-ContainerInformation
# 第474-477行:Export-ModuleMember 配置
Export-ModuleMember -Function @(
'Get-ContainerDetails',
'Test-ContainerInformation'
)
```
**验证二:主脚本导入逻辑**
```powershell
# 文件位置:check_server_health.ps1:315
Import-Module $ModuleFilePath -Force -Global -ErrorAction Stop
```
**验证三:函数检测逻辑(存在问题)**
```powershell
# 文件位置:check_server_health.ps1:356-361
if (-not (Get-Command $func -Scope Global -ErrorAction SilentlyContinue)) {
$missingFunctions += $func
}
```
### 3.4 解决方案
**方案一:修复函数验证逻辑(高优先级)**
修改 `check_server_health.ps1` 第356-361行的函数验证逻辑:
```powershell
$missingFunctions = @()
foreach ($func in $ExpectedFunctions) {
# 先尝试从已加载模块中查找函数
$cmd = Get-Command $func -ErrorAction SilentlyContinue
if (-not $cmd) {
# 检查模块中的导出函数
$moduleCmd = Get-Module | Where-Object { $_.ExportedFunctions.Keys -contains $func }
if (-not $moduleCmd) {
$missingFunctions += $func
}
}
}
```
**方案二:优化模块导入日志(中优先级)**
在导入模块时抑制无害的警告信息:
```powershell
Import-Module $ModuleFilePath -Force -Global -WarningAction SilentlyContinue -ErrorAction Stop
```
**方案三:审查函数命名规范(中优先级)**
1. 使用 `Get-Verb` 查看批准的动词列表
2. 审查 NTPCheck 和 ConfigIPCheck 模块中的函数命名
3. 评估是否需要重命名(需评估影响范围)
### 3.5 预防措施
1. **代码规范**:遵循 PowerShell 函数命名规范,使用批准的动词
2. **单元测试**:为模块导入逻辑添加单元测试
3. **代码审查**:在合并代码前审查模块导出配置
4. **文档更新**:更新开发文档,明确模块开发规范
### 3.6 问题状态
| 状态项 | 值 |
|--------|-----|
| 问题状态 | 分析完成,待执行 |
| 执行计划 | 已创建:`_PRD_模块导入存在未正确导入函数_执行计划.md` |
| 优先级 | 高 |
| 负责人 | 待分配 |
| 预计完成日期 | 待定 |
### 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
---
*文档结束*
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论