当前位置: 首页 > news >正文

Centos7 docker 容器内root身份应用自启动 /usr/sbin/init 问题


Centos7 docker 容器内root身份应用自启动 & /usr/sbin/init 问题

环境:我在一个 docker 容器内手动安装了 mysql、nginx、autotestsystem(自己的服务);
mysql 和 nginx 都做了服务脚本:mysqld.service、nginx.service,并设置了开机自启动:
systemctl enable mysqld.service
systemctl enable nginx.service

vi mysqld.service


vi nginx.service

自己的应用位置:
/opt/AutoTestSystem/ui/              #前端,前端用的nginx
/opt/AutoTestSystem/server/          #后端,后端用的python flask
/opt/AutoTestSystem/server/start.sh  #后端服务启动脚本
/opt/AutoTestSystem/server/stop.sh   #后端服务停止脚本
ln -s /opt/AutoTestSystem/server/start.sh /usr/bin/autotestsystem-start
ln -s /opt/AutoTestSystem/server/stop.sh /usr/bin/autotestsystem-stop

# cat /opt/AutoTestSystem/server/start.sh 
#!/bin/sh

pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
echo $pid
if [ -n "$pid" ]; then
  echo "WARNNING: main.py already is running, need not run again!"
  exit
fi

# start server
pushd /opt/AutoTestSystem/server  2>&1 >/dev/null
$(nohup python3 main.py >> log &)
sleep 2

pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
if [ -z "$pid" ]; then
 echo "ERROR: start failed!"
else
 echo "SUCCESS: start success!"
fi
popd 2>&1 >/dev/null

# cat /opt/AutoTestSystem/server/stop.sh  
#!/bin/sh

#pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
pid=$(ps aux |grep  "/opt/AutoTestSystem/server/main.py" |grep -v "grep" | awk '{print $2}')

if [ -z "$pid" ]; then
 echo "INFO: main.py is not running"
 exit
fi 

echo "INFO: to stop main.py, pid is: $pid"
$(kill -9 $pid)
sleep 3

pid2=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
if [ -n "$pid2" ]; then
 echo "ERROR: stop $pid2 failed!"
else
 echo "SUCCESS: stop $pid2 success!"
fi

执行docker commit保存持久化:

docker commit -a "hrf" -m "autotestsystem 1.0" 478394f89173 autotestsystem:1.0

注意:docker commit 时如果指定的 REPOSITORY:TAG 变化则会生成新的image,如果不变则不会生成新的image、只会合并,docker image查看会多出 REPOSITORY和TAG未空 <none> 的 IMAGE ID,这种是可以删除的(docker rmi IMAGE_ID)。

创建build目录 & Dockerfile & init_ats启动脚本,执行 docker build 把自启动脚本打包到容器里面去并设置自启动:

cd build

vi Dockerfile
FROM autotestsystem:1.0
WORKDIR /opt/AutoTestSystem
COPY init_ats /usr/bin/
RUN chmod +x /usr/bin/init_ats
ENTRYPOINT init_ats
LABEL user="hrf"
USER root

vi init_ats
#!/bin/bash
/usr/sbin/init
sleep 2
/usr/bin/autotestsystem-start


docker build -t autotestsystem:1.0 .
docker images
docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 

也尝试过docker run是传参替换: 
docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 /usr/sbin/init

docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 init_ats

docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 autotestsystem-start
都不行。

执行脚本,还尝试了多种,都不行:
ENTRYPOINT init_ats
ENTRYPOINT ["init_ats"]
ENTRYPOINT ["sh","init_ats"]
ENTRYPOINT ["sh","-c","init_ats"]
ENTRYPOINT autotestsystem-start
CMD init_ats
CMD autotestsystem-start

网上找了很多资料,原因是 root 身份运行docker容器,需要特权,需要加 /usr/sbin/init 运行容器。可是编写 Dockerfile 执行 docker build 的方式,无法支持启动时执行多个脚本或命令,只能执行一个或一条命令,即使写在一个shell脚本中也不行。


最后,换了一个思路,既然mysqld和nginx做成了service服务自启动可以(systemctl enable xxx),那我也尝创建自己应用的.service脚本,做成系统服务自启动。

查看当前容器:
[root@localhost build]# docker ps -a
CONTAINER ID   IMAGE      COMMAND            CREATED        STATUS        PORTS                                                                                                                           NAMES
478394f89173   centos:7   "/usr/sbin/init"   33 hours ago   Up 33 hours   0.0.0.0:9000->80/tcp, :::9000->80/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp, 0.0.0.0:9090->8080/tcp, :::9090->8080/tcp   autotest

查看镜像:
[root@localhost build]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
autotestsystem   1.0       a781ff5a15b8   46 minutes ago   1.72GB
centos           7         eeb6ee3f44bd   2 years ago      204MB

容器 478394f89173 是以root运行的,里面的mysqld服务和nginx服务自启正常,但自己服务编写的自启动脚本 init_ats 自启不生效。


接下来,我尝试把我的 autotestsystem 做成系统服务:

进入docker容器:
docker exec -it 478394f89173 /bin/bash

创建.service文件:
[root@478394f89173 system]# vi /lib/systemd/system/autotestsystem.service

[Unit]
Description=autotestsystem
After=network.target
 
[Service]
Type=forking
ExecStart=/opt/AutoTestSystem/server/start.sh
ExecReload=/opt/AutoTestSystem/server/start.sh
ExecStop=/opt/AutoTestSystem/server/stop.sh
PrivateTmp=true
User=root
#Group=root
WorkingDirectory=/opt/AutoTestSystem/server/
RestartSec=2s
 
[Install]
WantedBy=multi-user.target


[root@478394f89173 system]# chmod 754 /lib/systemd/system/autotestsystem.service

[root@478394f89173 system]# systemctl daemon-reload    # 每次修改service后需要刷新生效

[root@478394f89173 system]# systemctl  start autotestsystem.service 
[root@478394f89173 system]# systemctl  enable autotestsystem.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/autotestsystem.service to /usr/lib/systemd/system/autotestsystem.service.
[root@478394f89173 system]# ps aux |grep main.py       #启动服务成功

退出容器、停止容器、启动容器,进入容器,再查看 autotestsystem 能正常自启动:
exit
docker stop 478394f89173
docker start 478394f89173
docker exec -it 478394f89173 /bin/bash
ps aux |grep main.py
 

退出容器,在宿主机下重新 docker build 构建/保存镜像(image),即持久化:
做成.service系统服务了,用不到docker启动脚本,可以直接docker commit持久化、并删除none镜像:
 docker commit -a "hrf" -m "autotestsystem 1.0" 478394f89173 autotestsystem:1.0
 docker rmi `docker images | grep  '<none>' | awk '{print $3}'`

当然如果要使用docker build方式持久化镜像也是可以的。

如果是在宿主机上build目录下直接vi创建和编写的autotestsystem.service服务器脚本(而不是在容器内创建服务脚本和设置自启动),则可以使用docker build方式构建镜像、打脚本包到容器里面去:

cd build

vi autotestsystem.service

[Unit]
Description=autotestsystem
After=network.target
 
[Service]
Type=forking
ExecStart=/opt/AutoTestSystem/server/start.sh
ExecReload=/opt/AutoTestSystem/server/start.sh
ExecStop=/opt/AutoTestSystem/server/stop.sh
PrivateTmp=true
User=root
#Group=root
WorkingDirectory=/opt/AutoTestSystem/server/
RestartSec=2s
 
[Install]
WantedBy=multi-user.target

vi Dockerfile

FROM autotestsystem:1.0
WORKDIR /opt/AutoTestSystem
#COPY  init_ats  /usr/bin/
#RUN  chmod +x /usr/bin/init_ats
#ENTRYPOINT ["init_ats"]
COPY autotestsystem.service /lib/systemd/system/
COPY autotestsystem.service /etc/systemd/system/multi-user.target.wants/
RUN chmod 754 /lib/systemd/system/autotestsystem.service
RUN chmod 754 /etc/systemd/system/multi-user.target.wants/autotestsystem.service
ENTRYPOINT ["/usr/sbin/init"]
LABEL user="hrf"
USER root

说明:
build目录下创建和编写下面2个文件:autotestsystem.service、Dockerfile。
docker build构建时会执行Dockerfile中的COPY命名,COPY是构件阶段执行的。RUN、CMD、ENTRYPOINT命令则是在容器启动阶段执行的。
COPY autotestsystem.service /lib/systemd/system/  这条命令会在docker build构件阶段把build目录下的utotestsystem.service文件拷贝到容器内的/lib/systemd/system/这个目录下。


重新构建:
docker build -t autotestsystem:1.0 . 

[root@localhost build]#  docker build -t autotestsystem:1.0 .
[+] Building 22.0s (11/11) FINISHED                                                                                                  docker:default
 => [internal] load .dockerignore                                                                                                              0.7s
 => => transferring context: 2B                                                                                                                0.0s
 => [internal] load build definition from Dockerfile                                                                                           1.8s
 => => transferring dockerfile: 550B                                                                                                           0.0s
 => [internal] load metadata for docker.io/library/autotestsystem:1.0                                                                          0.0s
 => [1/6] FROM docker.io/library/autotestsystem:1.0                                                                                            6.6s
 => [internal] load build context                                                                                                              0.8s
 => => transferring context: 461B                                                                                                              0.0s
 => [2/6] WORKDIR /opt/AutoTestSystem                                                                                                          0.7s
 => [3/6] COPY autotestsystem.service /lib/systemd/system/                                                                                     1.4s
 => [4/6] COPY autotestsystem.service /etc/systemd/system/multi-user.target.wants/                                                             1.3s
 => [5/6] RUN chmod 754 /lib/systemd/system/autotestsystem.service                                                                             2.3s
 => [6/6] RUN chmod 754 /etc/systemd/system/multi-user.target.wants/autotestsystem.service                                                     2.3s
 => exporting to image                                                                                                                         2.9s
 => => exporting layers                                                                                                                        2.9s
 => => writing image sha256:a1750b9abb21ba65b122edfdf21c37b81896ec68ffbe2f510bfff7ce97e4a95b                                                   0.0s
 => => naming to docker.io/library/autotestsystem:1.0                                                                                          0.1s
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 
06ce37919cf068e20fdd676fa51ce1988e3a1d40ba7424d645fd5f561b758a27

[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# docker ps -a
CONTAINER ID   IMAGE                COMMAND            CREATED         STATUS         PORTS                                                                                                                               NAMES
06ce37919cf0   autotestsystem:1.0   "/usr/sbin/init"   7 seconds ago   Up 4 seconds   0.0.0.0:29000->80/tcp, :::29000->80/tcp, 0.0.0.0:23306->3306/tcp, :::23306->3306/tcp, 0.0.0.0:29090->8080/tcp, :::29090->8080/tcp   autotest2
478394f89173   centos:7             "/usr/sbin/init"   33 hours ago    Up 33 hours    0.0.0.0:9000->80/tcp, :::9000->80/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp, 0.0.0.0:9090->8080/tcp, :::9090->8080/tcp       autotest
[root@localhost build]# 

最后导出、备份镜像文件:

cd release
docker save -o autotestsystem-1.0.tar autotestsystem:1.0
 

相关文章:

Centos7 docker 容器内root身份应用自启动 /usr/sbin/init 问题

Centos7 docker 容器内root身份应用自启动 & /usr/sbin/init 问题 环境&#xff1a;我在一个 docker 容器内手动安装了 mysql、nginx、autotestsystem&#xff08;自己的服务&#xff09;&#xff1b; mysql 和 nginx 都做了服务脚本&#xff1a;mysqld.service、nginx.se…...

STL学习笔记之容器

首先我们要学习的是容器 第一个是容器的初始化&#xff08;构造方式&#xff09;有三种方式 分别是 第一种 int arr[]{1,2,3} vector<int> v1(arr,arr3) 即容器存放的种类和从另外一个数组去拷贝一段数据。 第二种 vector<int> v2(3,10); 第一个3是指存放…...

Java基础---第十二篇

系列文章目录 文章目录 系列文章目录一、获取一个类Class对象的方式有哪些?二、ArrayList 和 LinkedList 的区别有哪些?三、用过 ArrayList 吗?说一下它有什么特点?一、获取一个类Class对象的方式有哪些? 搞清楚类对象和实例对象,但都是对象。 第一种:通过类对象的 get…...

Acwing 841. 字符串哈希

Acwing 841. 字符串哈希 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 #include <iostream> #include <algorithm>using namespace std;typedef unsigned long long ULL;const int N 100010, P 131; // P 131 或者13331(经验值)int n, m; char str[N]…...

NEON优化:性能优化经验总结

NEON优化&#xff1a;性能优化经验总结 1. 什么是 NEONArm Adv SIMD 历史 2. 寄存器3. NEON 命名方式4. 优化技巧5. 优化 NEON 代码(Armv7-A内容&#xff0c;但区别不大)5.1 优化 NEON 汇编代码5.1.1 Cortex-A 处理器之间的 NEON 管道差异5.1.2 内存访问优化 Reference: NEON优…...

C++ 并发编程实战 第九章

目录 9.1 线程池 9.1.1 最简易可行的线程池 9.1.2 等待提交给线程池的任务完成运行 9.1.3等待其他任务完成的任务 9.1.4 避免任务队列上的争夺 9.1.5 任务窃取 9.2 中断线程 9.2.1 发起一个线程&#xff0c;以及把他中断 9.2.2 检测线程是否被中断 9.2.3 中断条件变…...

【Java】super 关键字用法

目录 this与super区别 1.访问成员变量-示例代码 继承中构造方法的访问特点 2.访问构造方法-示例代码&#xff1a; 继承中成员方法访问特点 3.访问成员方法-示例代码&#xff1a; super 关键字的用法和 this 关键字相似 this : 代表本类对象的引用super : 代表父类存储空间…...

前端笔试题总结,带答案和解析

1. 执行以下程序&#xff0c;输出结果为&#xff08;&#xff09; var x 10; var y 20; var z x < y ? x:y; console.log(xx;yy;zz);A x11;y21;z11 B x11;y20;z10 C x11;y21;z10 D x11;y20;z11 初始化x的值为10&#xff0c;y的值为20&#xff0c;x < y返回结果为tru…...

Omniverse Machinima

Omniverse Machinima App | NVIDIA Omniverse Machinima 是 NVIDIA 推出的一款实时动画创作工具&#xff0c;可用于在虚拟世界中制作和操纵角色及其环境。该工具使用 Universal Scene Description (USD) 作为其通用场景描述格式&#xff0c;可与多种 3D 建模、动画和渲染应用程…...

【测试人生】游戏业务测试落地精准测试专项的一些思路

精准测试在互联网领域有广泛的应用。以变更为出发点&#xff0c;通过对变更内容进行分析&#xff0c;可以确定单次变更具体涉及到哪些模块和功能点&#xff0c;以及是否存在夹带风险&#xff0c;从而从QA的视角&#xff0c;可以知道哪些功能模块需要做测试&#xff0c;以及哪些…...

Redis 数据类型底层原理

String 内部编码有三种&#xff1a;int、embstr、raw int&#xff1a;如果一个字符串对象保存的是整数值&#xff0c;并且这个整数值可以用 long类型来表示(不超过 long 的表示范围&#xff0c;如果超过了 long 的表示范围&#xff0c;那么按照存储字符串的编码来存储&#xf…...

EasyEdge 智能边缘控制台通过sdk发布应用

离线部署SDK生成 模型部署完成后会出现下载SDK的按钮&#xff0c;点击按钮下载SDK并保存好SDK。 进入EasyDL官网的技术文档 安装智能边缘控制台 跟着教程&#xff0c;完成安装&#xff1a;点此链接 树莓派4b是Linux arm64的架构&#xff0c;点击对应的链接进行下载。 下载完成…...

centos软件设置开机启动的方式

以下以redis作为案例&#xff1a; 开机启动方式一 [Unit] Descriptionredis-server Afternetwork.target [Service] Typeforking # 这里需要修改自己的配置文件 ExecStart/usr/local/bin/redis-server /etc/redis/redis.conf PrivateTmptrue [Install] WantedBymulti-user.tar…...

二叉树和堆

二叉树不存在度大于2的结点&#xff08;每个根最多只有两个子结点&#xff09;二叉树的子树有左右之分&#xff0c;次序不能颠倒&#xff0c;因此二叉树是有序树 两个特殊的二叉树——&#xff08;满二叉树&#xff0c;完全二叉树&#xff09; 满二叉树——每个根结点都有左右…...

洛谷P5732 【深基5.习7】杨辉三角题解

目录 题目【深基5.习7】杨辉三角题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1传送门 代码解释亲测 题目 【深基5.习7】杨辉三角 题目描述 给出 n ( n ≤ 20 ) n(n\le20) n(n≤20)&#xff0c;输出杨辉三角的前 n n n 行。 如果你不知道什么是杨辉三角&#xf…...

Docker 精简安装 Nacos 2.2.1 单机版本

准备工作&#xff1a; 1&#xff09;已安装docker 2&#xff09;数据库准备&#xff0c;演示使用MySql5.7版本 1、拉取 [rootTseng-HW ~]# docker pull nacos/nacos-server:v2.2.1 v2.2.1: Pulling from nacos/nacos-server 2d473b07cdd5: Already exists 77c5a601c050: Pul…...

IntelliJ IDEA配置Cplex12.6.3详细步骤

Cplex12.6.3版IntelliJ IDEA配置详细步骤 一、Cplex12.6.3版下载地址二、Cplex安装步骤三、IDEA配置CPLEX3.1 添加CPLEX安装目录的cplex.jar包到项目文件中3.2 将CPLEX的x64_win64文件夹添加到IDEA的VM options中 四、检查IDEA中Cplex是否安装成功卸载Cplex 一、Cplex12.6.3版下…...

2023 年最佳多 GPU 深度学习系统指南

动动发财的小手&#xff0c;点个赞吧&#xff01; 本文[1]提供了有关如何构建用于深度学习的多 GPU 系统的指南&#xff0c;并希望为您节省一些研究时间和实验时间。 1. GPU 让我们从有趣&#xff08;且昂贵&#xff09;的部分开始&#xff01; 购买 GPU 时的主要考虑因素是&am…...

Kotlin异常处理runCatching,getOrNull,onFailure,onSuccess(1)

Kotlin异常处理runCatching&#xff0c;getOrNull&#xff0c;onFailure&#xff0c;onSuccess&#xff08;1&#xff09; fun main(args: Array<String>) {var s1 runCatching {1 / 1}.getOrNull()println(s1) //s11&#xff0c;打印1println("-")var s2 ru…...

【深入探究人工智能】:历史、应用、技术与未来

深入探究人工智能 前言人工智能的历史人工智能的应用人工智能的技术人工智能的未来当代的人工智能产物结语&#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &am…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...