260227-Linux-pid-proc(exe & cwd & fd & cmdline)查找文件位置

sudo netstat -tulnp | grep :<端口号>

  • -t:TCP 端口
  • -u:UDP 端口
  • -l:仅显示监听套接字
  • -n:不解析服务名(直接显示端口号)
  • -p:显示进程 PID 和名称

根据 PID 查找相关文件位置

有了 PID,就可以查看该进程的详细信息:

1️⃣ 找到进程的可执行文件路径

1
ls -l /proc/<PID>/exe

示例:ls -l /proc/12345/exe 会显示指向实际可执行文件的符号链接。

2️⃣ 找到进程的当前工作目录

1
pwdx <PID>

或者:

1
readlink /proc/<PID>/cwd

3️⃣ 查看进程打开的所有文件(包括配置文件、日志文件等)

1
ls -l /proc/<PID>/fd/

这列出了该进程打开的所有文件描述符,通过符号链接可以看到实际的文件路径。

4️⃣ 查看进程的完整命令行参数(可能包含配置文件路径)

1
2
3
ps -ef | grep <PID>
# 或者
cat /proc/<PID>/cmdline | tr '\0' ' '

cmdline 文件以 \0 分隔参数,用 tr 转换为空格以便阅读。

5️⃣ 如果进程是一个服务(systemd 管理的),可以查看其单元文件

1
2
systemctl status <服务名>   # 先找到服务名
systemctl cat <服务名> # 查看服务配置文件,其中可能包含 ExecStart 等路径

260225-git config --global全局配置参数

先配置好参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
git config --global user.email "css@110.com"
git config --global user.name "css"

git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
git config --global http.postBuffer 524288000
git config --global fetch.parallel 10

git config --global http.timeout 300
git config --global fetch.timeout 300
git config --global ssh.connectTimeout 300

git config --global http.postBuffer 524288000
git config --global core.packedGitWindowSize 128m
git config --global core.packedGitLimit 128m
git config --global core.compression 0
git config --global http.timeout 300
git config --global fetch.timeout 300
git config --global http.keepAlive false

Git Clone Depth=1

1
2
3
4
5
6
# 浅克隆(--depth=1 仅拉取最新提交)
git clone --depth=1 https://github.com/xxx/xxx.git

# 若需要完整历史,克隆后补全
cd xxx
git fetch --unshallow

配置参数中文描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
git config --global user.email "xx@qq.com"
git config --global user.name "xx"

git config --list # 查看配置的信息

# 设置低速超时时间为999999秒(几乎不超时)
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# 设置HTTP缓冲区大小为500MB(默认通常较小)
git config --global http.postBuffer 524288000

# 设置压缩级别(0-9,0是不压缩,9是最大压缩)
git config --global core.compression 0

# 设置并行下载数量-启用并行下载(同时下载多个对象)
git config --global fetch.parallel 10

# 设置连接超时(单位:秒,建议设为300)
git config --global http.timeout 300
# 设置拉取/推送超时
git config --global fetch.timeout 300
# 设置SSH连接超时(若用SSH协议)
git config --global ssh.connectTimeout 300

# 浅克隆(--depth=1 仅拉取最新提交)
git clone --depth=1 https://github.com/xxx/xxx.git
# 若需要完整历史,克隆后补全
cd xxx
git fetch --unshallow

未确认配置参数

1
2
3
4
5
6
7
8
9
10
11

git config --global core.autocrlf input #自动转换坑太大,提交到git是自动将换行符转换为lf

#拒绝提交包含混合换行符的文件
git config --global core.safecrlf true

#允许提交包含混合换行符的文件
git config --global core.safecrlf false

#提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

260210-mongodb(copyDatabase) show database 如何调整数据库名称

在 MongoDB 中,没有直接的 plain复制 rename database 命令

copydatabase()已过期
copydatabase()已过期
copydatabase()已过期

方法1:使用plain复制mongodump和plain复制mongorestore(适合大型数据库)

1
2
3
4
5
6
7
8
9
10
# 1. 导出旧数据库
mongodump --db old_db_name --out /backup/path/

# 2. 导入为新数据库名
mongorestore --db new_db_name /backup/path/old_db_name/

# 3. 删除旧数据库(通过 mongo shell)
mongo
> use old_db_name
> db.dropDatabase()

方法2:使用plain复制mongosh的聚合管道(MongoDB 4.2+)

1
2
3
4
5
6
7
// 遍历所有集合并复制
use
old_db_name

db.getCollectionNames().forEach(function (coll) {
db[coll].aggregate([{$out: {db: "new_db_name", coll: coll}}]);
});

⚠️ 注意事项

项目 说明
索引 复制后需要重新创建索引
用户权限 数据库用户不会自动复制,需手动创建
磁盘空间 确保有足够空间存储两份数据
生产环境 建议在维护窗口操作,或先备份

快速检查命令

1
2
3
4
5
6
7
8
9
10
// 查看所有数据库
show
dbs

// 查看当前数据库
db.getName()

// 切换数据库
use
database_name

**推荐在生产环境使用 plain复制 mongodump/mongorestore**,更加稳定可靠,且可以验证数据完整性。

260210-MongoDBHA-MongoDB集群-重置绑定关系-(Replica Set)副本集集群搭建

这是一个涉及数据库运维的操作,需要谨慎处理。

MongoDB 集群配置删除与重新绑定

1. 理解 MongoDB 集群配置存储位置

MongoDB 集群配置主要存储在 Config Servers 中:

  • Config Database (plain复制 config): 包含分片集群的元数据
  • Local Database: 每个节点存储的副本集配置

2. 删除集群配置的方法

场景 A: 完全重置分片集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1. 停止所有 mongos 路由进程
killall mongos # 或使用 systemctl stop mongos

# 2. 停止所有分片 mongod 实例
# 在每个分片节点上执行
killall mongod

# 3. 停止 Config Server 副本集
# 在所有 config server 节点上执行
killall mongod

# 4. 清除 Config Server 数据目录(⚠️ 危险操作)
# 假设数据目录为 /data/configdb
rm -rf /data/configdb/*

# 5. 重新初始化 Config Server 副本集
mongod --configsvr --replSet configRS --dbpath /data/configdb --port 27019

# 连接主节点初始化
rs.initiate({
_id: "configRS",
configsvr: true,
members: [
{ _id: 0, host: "cfg1.example.com:27019" },
{ _id: 1, host: "cfg2.example.com:27019" },
{ _id: 2, host: "cfg3.example.com:27019" }
]
})

场景 B: 仅移除分片(保留集群框架)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 连接到 mongos
mongo--
host
mongos.example.com--
port
27017

// 1. 查看当前分片
sh.status()

// 2. 移除分片(会迁移数据)
use
admin
db.runCommand({removeShard: "shard0000"})

// 3. 检查移除进度,直到状态为 "completed"
db.runCommand({removeShard: "shard0000"})

// 4. 如果需要强制移除(数据已备份)
db.runCommand({removeShard: "shard0000", drop: true})

场景 C: 重置副本集配置(非分片集群)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 连接到副本集成员
mongo--
host
mongod.example.com--
port
27017

// 1. 查看当前配置
rs.conf()

// 2. 强制重新配置(适用于节点变更)
rs.reconfig({
_id: "myReplicaSet",
members: [
{_id: 0, host: "newhost1:27017"},
{_id: 1, host: "newhost2:27017"},
{_id: 2, host: "newhost3:27017"}
]
}, {force: true}) // force: true 用于强制重新配置

// 3. 或者完全重置(先删除 local 数据库的配置)
use
local
db.system.replset.remove({}) // ⚠️ 仅在确定要重置时执行
// 然后重启 mongod,重新执行 rs.initiate()

3. 重新绑定新配置

步骤 1: 重新配置 Config Server

1
2
3
4
5
6
7
8
9
10
// 初始化新的 Config Server 副本集
rs.initiate({
_id: "configRS",
configsvr: true,
members: [
{_id: 0, host: "new-cfg1:27019", priority: 2},
{_id: 1, host: "new-cfg2:27019"},
{_id: 2, host: "new-cfg3:27019", arbiterOnly: true}
]
})

步骤 2: 启动 mongos 并配置分片

1
2
# 启动 mongos,指向新的 config server
mongos --configdb configRS/new-cfg1:27019,new-cfg2:27019,new-cfg3:27019 --port 27017
1
2
3
4
5
6
7
8
9
// 连接到 mongos 添加分片
sh.addShard("shardRS1/shard1-node1:27018,shard1-node2:27018")
sh.addShard("shardRS2/shard2-node1:27018,shard2-node2:27018")

// 启用数据库分片
sh.enableSharding("myDatabase")

// 对集合进行分片
sh.shardCollection("myDatabase.myCollection", {shardKey: 1})

4. 关键注意事项

操作 风险等级 说明
删除 Config Server 数据 🔴 极高 会丢失所有分片元数据
强制 rs.reconfig 🟡 中等 可能导致脑裂
removeShard 🟢 较低 数据会自动迁移
停止 mongos 🟢 低 仅影响路由,不丢数据

5. 安全操作建议

1
2
3
4
# 操作前务必备份
mongodump --host configRS/cfg1:27019 --db config --out /backup/config_$(date +%Y%m%d)

# 或者使用文件系统快照(如果使用 WiredTiger)

6. 常见问题排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 检查 Config Server 状态
use
admin
db.runCommand({getShardMap: 1})

// 查看分片连接状态
sh.status()

// 检查 balancer 状态
sh.getBalancerState()

// 如果配置不一致,强制刷新
use
admin
db.adminCommand({flushRouterConfig: 1})

⚠️ 重要提醒

  • 在生产环境执行前,务必在测试环境验证
  • 确保有完整的数据备份
  • 操作期间会有服务中断,选择维护窗口执行
  • 如果是云托管 MongoDB (Atlas),请使用提供商的控制台操作,不要手动修改

2602-(perfmon.msc)Windows定位和排查CPU占用高进程问题

perfmon.msc(定位CPU问题)

perfmon.msc(性能监视器)定位 Windows CPU 问题,核心是通过添加关键计数器实时监控 / 日志分析,先判断 CPU
瓶颈类型,再定位到进程 / 线程,最后结合 JDK 工具深挖 Java 问题,以下是精准可落地的完整流程

二、添加 CPU 核心计数器(必选)

这是判断 CPU 瓶颈的核心步骤,优先添加以下计数器,覆盖整体、用户 / 内核、进程、线程与中断维度:

计数器路径 作用 正常阈值 异常判断
\Processor(*)% Processor Time 整体 CPU 使用率(* 含所有核心,_Total 为总和) < 70% 持续 > 80% 为瓶颈,>90% 严重
\Processor(*)% User Time 用户态 CPU(如 Java 应用) < 50% 持续 > 80% 多为应用代码问题
\Processor(*)% Privileged Time 内核态 CPU(如驱动、系统调用) < 30% 持续 > 50% 多为驱动 / 系统服务问题
\Process(*)% Processor Time 单个进程 CPU 占用(筛选 java.exe/javaw.exe) 占比高的进程优先排查
\Thread(*)% Processor Time 单个线程 CPU 占用(需指定进程 PID) 定位进程内高 CPU 线程
\System\Processor Queue Length CPU 等待队列长度 每核心 < 2 持续 > 2 且 CPU 高,说明调度拥堵
\Processor(*)% Interrupt Time 中断占用时间 < 5% 持续 > 10% 多为硬件 / 驱动问题

添加操作步骤

  1. 右键性能监视器图表→「添加计数器」;
  2. 在弹出窗口中,依次展开上述计数器类别,选中目标计数器→「添加」→「确定」;
  3. 若需监控特定 Java 进程,在 \Process 类别中筛选 PID 对应的 java.exe/javaw.exe。

通过arthas thread -n 5 指定进程PID查看

1
2
3
4
5
6
7
8
9
10
11
12
"flow-execute290488" Id=930149 cpuUsage=46.42% deltaTime=93ms time=31828ms RUNNABLE
at com.oracle.truffle.api.library.LibraryFactory.dispatch(LibraryFactory.java:548)
at com.oracle.truffle.api.library.LibraryFactory.getUncached(LibraryFactory.java:396)
at com.oracle.truffle.api.interop.InteropLibraryGen$UncachedDispatch.getArraySize(InteropLibraryGen.java:7348)
at com.oracle.truffle.host.HostProxy.getMembers(HostProxy.java:271)
at com.oracle.truffle.host.HostProxyGen$InteropLibraryExports$Cached.getMembers(HostProxyGen.java:941)
at com.oracle.truffle.api.interop.InteropLibrary.getMembers(InteropLibrary.java:734)
at com.oracle.truffle.polyglot.PolyglotMap$Cache$EntrySet.doCached(PolyglotMap.java:589)
at com.oracle.truffle.polyglot.PolyglotMapFactory$CacheFactory$EntrySetNodeGen.executeImpl(PolyglotMapFactory.java:323)
at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:118)
at com.oracle.truffle.polyglot.PolyglotMap.entrySet(PolyglotMap.java:131)

jenkins配置保存-重启无效(XML保存异常)-Plugins(ssh-server)-保存了,重启又还原了,是怎么回事.


异常日志 tail -f /jenkins/apache-tomcat-10.1.50/logs/catalina.out -n500

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

1
2
3
4
05-Feb-2026 14:42:19.252 警告 [Handling POST /jenkins/manage/configSubmit from 192.168.0.75 : http-nio-8080-exec-1] hudson.model.Descriptor.save Failed to save /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
1
2
3
4
5
6
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
at PluginClassLoader for publish-over-ssh//jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor.configure(BapSshPublisherPluginDescriptor.java:158)
at jenkins.model.Jenkins.configureDescriptor(Jenkins.java:4049)
at jenkins.model.Jenkins.doConfigSubmit(Jenkins.java:4013)

Caused by: com.thoughtworks.xstream.io.StreamException: Invalid character 0x0 in XML stream
Invalid character 0x0 表示 SSH 配置的代理密码字段 (proxyPassword) 包含空字符(NULL character),这是 XML 不允许的字符!
这不是权限问题,而是 数据污染问题!

🔍 问题分析

错误链:
Jenkins 尝试保存 Publish Over SSH 配置
序列化 BapSshHostConfiguration#proxyPassword 字段时失败
密码中包含 0x0(空字符),XML 写入器拒绝写入
导致整个配置文件无法保存
可能原因:
之前配置的代理密码包含特殊字符或空字符
配置文件损坏,密码字段被污染
从其他环境复制配置时编码问题

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

看到了关键信息!您是用 Tomcat 启动 Jenkins,而且注意到这个参数:

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
这就是问题根源!

1
2
3
4
5
6
7
ps -ef | grep jenkins
avahi 677 1 0 13:35 ? 00:00:01 avahi-daemon: running [jenkins171.local]
root 8020 1 62 14:16 ? 00:00:53 /usr/local/jdk//bin/java -Djava.util.logging.config.file=/jenkins/apache-tomcat-10.1.50/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xmx14G -Djava.awt.headless=true -DJENKINS_HOME=/jenkins/jenkins_home -Duser.timezone=GMT+08 -Difile.encoding=utf-8 -Dorg.jenkinsci.plugins.gitclient.Git.timeOut=1200 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -DJENKINS_HOME=/jenkins/jenkins_home -classpath /jenkins/apache-tomcat-10.1.50/bin/bootstrap.jar:/jenkins/apache-tomcat-10.1.50/bin/tomcat-juli.jar -Dcatalina.base=/jenkins/apache-tomcat-10.1.50 -Dcatalina.home=/jenkins/apache-tomcat-10.1.50 -Djava.io.tmpdir=/jenkins/apache-tomcat-10.1.50/temp org.apache.catalina.startup.Bootstrap start
ubuntu 8159 3314 0 14:17 pts/1 00:00:00 grep --color=auto jenkins

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027

问题分析
UMASK=0027 是 Tomcat 的安全机制,它会:
覆盖 root 用户的默认 umask(通常是 0022)
强制新创建文件的权限为 640(即 -rw-r—–)
移除其他用户的写权限
虽然进程是 root,但 Jenkins 在写入配置文件时,Tomcat 的安全监听器会强制应用这个 umask,导致:
文件权限被限制为 640
Jenkins 无法再次写入(因为实际运行中 Jenkins 会检查并尝试重写)


查看文件是否被锁定

1
2
3
4
5
6
7
8
# 检查文件是否被其他进程占用
lsof /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 检查文件属性(是否有 immutable 标志)
lsattr /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 如果有 i 标志,移除它
chattr -i /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

查看SSH-Server配置是否生效 Publish Over SSH

1
sudo cat /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml | grep -A5 "jenkins(prod-online)"

查询配置文件权限

1
2
3
4
5
6
7
ls -lh *sh*
-rwxr-x--- 1 root root 366 8月 18 2022 com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r----- 1 root root 4.3K 2月 5 14:11 hudson.plugins.emailext.ExtendedEmailPublisher.xml
-rw-r----- 1 root root 683 1月 21 19:07 hudson.plugins.powershell.PowerShellInstallation.xml
-rw-r----- 1 root root 1.9K 2月 5 14:11 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
-rwxr-xr-x 1 root root 42K 2月 5 13:53 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205
-rwxr-xr-x 1 root root 42K 2月 5 14:05 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205003

Tomcat 部署修复

1
2
3
4
5
6
7
8
9
10
11
12
13
# 找到 Tomcat 的 setenv.sh(如果没有则创建)
sudo vi /jenkins/apache-tomcat-10.1.50/bin/setenv.sh

# 添加以下内容
export JENKINS_HOME=/jenkins/jenkins_home
export CATALINA_OPTS="-DJENKINS_HOME=/jenkins/jenkins_home"

# 确保目录存在且有权限
sudo mkdir -p /jenkins/jenkins_home
sudo chown -R tomcat:tomcat /jenkins/jenkins_home

# 重启 Tomcat
sudo systemctl restart tomcat9

2602-DockerMongoDB重置密码

启动临时容器,不加载任何认证

1
2
3
4
5
6
7
8
9
10
11
12
# 2. 启动临时容器,不加载任何认证
docker run -d \
--name mongo_reset \
-v mongo_data:/data/db \
-p 27017:27017 \
registry.cn-hangzhou.aliyuncs.com/farerboy/mongo:8.0.5-rc1 \
mongod --bind_ip_all

# 3. 尝试无认证连接
docker exec -it mongo_reset mongosh


如果能连进去,执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 查看所有数据库
show dbs

// 切换到 admin(如果不存在就创建)
use admin

// 查看是否有用户
db.system.users.find().pretty();

// 删除用户
db.dropUser('usertest')

// 如果没有用户,直接创建
db.createUser({
user: "admin",
pwd: "xxxxxxxx",
mechanisms: ["SCRAM-SHA-1"],
roles: [{ role: "clusterMonitor", db: "admin" },{ role: "clusterManager", db: "admin" },{ role: "clusterMonitor", db: "admin" },{ role: "clusterManager", db: "admin" },'readWriteAnyDatabase', 'dbAdminAnyDatabase', {
role: "dbAdmin",
db: 'dbName'
}, {
role: "readWrite",
db: 'dbName'
}]
});

重新绑定MongoDB

1
2
3
4
5
6
7
8
# 3. 重新启动(相当于全新实例,但数据文件还在,需要修复)
docker run -d \
--name mongo_new \
-v mongo_data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=NewPassword123 \
-p 27017:27017 \
registry.cn-hangzhou.aliyuncs.com/farerboy/mongo:8.0.5-rc1

260123-windows 11 开机后必须在电脑上输入密码后,才能远程,是怎么回事


SUCCESS

计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全

3. Administrator账户是否被禁用

1
Win+R → lusrmgr.msc → 用户 → Administrator → 取消勾选"账户已禁用"

4. 远程桌面服务的安全层设置

1
2
Win+R → gpedit.msc
计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全

检查这两项:

  • “要求使用网络级别的身份验证…” → 设为已启用(推荐)或已禁用测试
  • “设置客户端连接加密级别” → 设为已禁用或”客户端兼容”

5. 防火墙是否放行

1
2
控制面板 → Windows Defender 防火墙 → 允许应用通过防火墙
确认"远程桌面"勾选了"专用"和"公用"

6. 最粗暴测试:先关掉NLA

1
2
gpedit.msc → 计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全
"要求使用网络级别的身份验证..." → 已禁用

重启后再试。如果能连,说明是NLA凭据问题;如果连不上,是网络或防火墙问题。


SUCCESS

想让“重启后远程直接能连”,就得让系统在开机后自动完成一次交互式登录,把会话跑起来。做法有两种:

  1. 注册表手动写 AutoAdminLogon(备用方案)

  2. Win+R → regedit

  3. 定位到
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

  4. 右侧新建/修改以下键值(都是 REG_SZ):

    1
    2
    3
    4
    AutoAdminLogon = 1
    DefaultUserName = Administrator
    DefaultDomainName = . (或你的计算机名)
    DefaultPassword = 你的密码
  5. 重启即可。

安全提醒

  • 自动登录等于把密码明文存在注册表(或 netplwiz 保管),任何能物理接触机器的人都能看到;只建议在受控的机房/家里使用。
  • 如果机器要放在公网,最好改用“开机后先本地输一次密码”的手动方式,或者给 BIOS/BitLocker 加电口令,再配 VPN 跳板,而不是单纯依赖自动登录。

这是 Windows 11 的默认安全机制:
如果本地还没“真正”用密码登录过一次,系统里就没有缓存可供 NLA(网络级身份验证)使用的凭据,远程桌面就会直接拒绝连接,表现为“必须先在本机输完密码,远程才能连”。

为什么会这样

  1. 很多人第一次激活系统用的是 Microsoft 账号,但随后只设了 PIN 或 Windows Hello 刷脸/指纹。

  2. PIN/Hello 只能解锁“已登录的本地会话”,不能当作 NLA 的凭据;而 Microsoft 账号的密码又从未在本地输入过,所以缓存里找不到有效凭据。

  3. 远程桌面服务启动时,NLA 阶段就要求出示“用户名+密码”,本地没有缓存只能失败,于是出现“必须本地先登录一次”的现象

解决思路(任选其一,推荐前两种)

  1. 本地用“账号密码”重新登录一次 a. 先锁屏 Win+L → 登录选项 → 选“密码”并输入 Microsoft 账号密码。 b.
    成功后该凭据会被缓存,今后无需再本地登录即可远程 。

  2. 干脆新建一个本地管理员,专门做远程

    1
    2
    3
    powershell
    net user rdpuser 你的密码 /add
    net localgroup administrators rdpuser /add

然后在“设置 → 系统 → 远程桌面 → 远程桌面用户”里把 rdpuser 加进去。以后远程就用这个本地账户即可

  1. 关闭“仅允许 Windows Hello 登录” 设置 → 账户 → 登录选项 → 关闭“为提高安全性,仅允许 Windows Hello 登录 Microsoft
    账号”。这样你就能在锁屏界面直接选“密码”,完成一次缓存 。

  2. 组策略放行“空密码”(仅家庭版不可用)

  3. 彻底关掉 NLA(降低安全性)

一句话总结
“先本地输一次密码”只是为了让 Windows 把真正的账号密码缓存下来;只要凭据存在,远程桌面就能在 NLA 阶段完成验证,之后再也不需要本地先登录。按上面
1 或 2 操作即可根治。

可以,直接把“Administrator”设为远程桌面用户即可,不需要再新建一个 rdpuser。
步骤如下(Win11 专业版/企业版):

  1. 先在本机用 Administrator 的「密码」登录一次
    ‑ 锁屏 → 登录选项 → 选「密码」并输入 Administrator 的密码,让系统把凭据缓存下来;这是解决“必须本地先登录”的关键。

  2. 把 Administrator 加入「远程桌面用户」组
    Win+X → 终端(管理员) →

    1
    net localgroup "Remote Desktop Users" administrator /add
  3. 确认远程桌面已开启
    设置 → 系统 → 远程桌面 → 打开「启用远程桌面」。

  4. 客户端连接时
    用户名填 .\Administrator(或计算机名\Administrator),再输入密码即可直接远程,无需再本地先登录。

注意

  • 如果系统用的是 Microsoft 在线账号,密码要输入「Microsoft 账号密码」而不是 PIN/Hello。

  • 出于安全考虑,建议给 Administrator 设一个强密码,并在路由器或防火墙里限制可访问 3389 的 IP 范围