add
This commit is contained in:
parent
6e02530275
commit
b263a7ab27
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -1,79 +0,0 @@
|
||||
```
|
||||
# 因清华大学开源镜像站 HTTP/403 换了中科大的镜像站,配置信息存放在这里
|
||||
cat /etc/apt/sources.list
|
||||
|
||||
# 安装 openssh 端口号是默认的 22 没有修改
|
||||
sudo apt install openssh-server -y
|
||||
sudo systemctl enable ssh
|
||||
sudo systemctl start ssh
|
||||
|
||||
# 安装 NVDIA 显卡驱动和
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
|
||||
sudo dpkg -i cuda-keyring_1.1-1_all.deb
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install cuda-toolkit-12-8
|
||||
sudo apt-get install -y cuda-drivers
|
||||
nvidia-smi
|
||||
|
||||
# 安装 nvidia-cuda-toolkit
|
||||
apt install nvidia-cuda-toolkit
|
||||
nvcc -V
|
||||
|
||||
# 创建了一个新的目录,用于存储 vllm 使用的模型或其他文件
|
||||
mkdir /home/ss/vllm-py12 && cd /home/ss/vllm-py12
|
||||
|
||||
# 用 conda 建了个新环境,以下 pip install 都是在该环境执行的
|
||||
conda create -n vllm-py12 python=3.12 -y
|
||||
conda activate vllm-py12
|
||||
|
||||
# 安装 vllm
|
||||
pip install vllm -i -i https://mirrors.cloud.tencent.com/pypi/simple/ --extra-index-url https://download.pytorch.org/whl/cu128
|
||||
|
||||
# 安装 modelscope
|
||||
pip install modelscope -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
|
||||
|
||||
# 拉取 gpt-oss-20b 模型,由于显存不足,运行失败了
|
||||
modelscope download --model openai-mirror/gpt-oss-20b --local_dir /home/ss/vllm-py12/gpt-oss-20b
|
||||
|
||||
# 下载了 Qwen3-0.6B
|
||||
modelscope download --model Qwen/Qwen3-0.6B --local_dir /home/ss/vllm-py12/qwen3-06b
|
||||
|
||||
# 运行 Qwen3-0.6B
|
||||
nohup vllm serve /home/ss/vllm-py12/qwen3-06b \
|
||||
--host 0.0.0.0 \
|
||||
--port 8000 \
|
||||
--served-model-name Qwen3-0.6B \
|
||||
--tensor-parallel-size 1 \
|
||||
--dtype auto \
|
||||
--gpu-memory-utilization 0.9 \
|
||||
--max-model-len 32768 \
|
||||
--trust-remote-code \
|
||||
>> /home/ss/vllm-py12/vllm.log 2>&1 \
|
||||
& echo $! > /home/ss/vllm-py12/vllm.pid
|
||||
|
||||
# 安装了抓包工具 tshark 和 ngrep
|
||||
sudo apt install ngrep
|
||||
sudo apt-get install tshark
|
||||
|
||||
# 通过 java 脚本调用 tshark 提取关键日志
|
||||
sudo nohup bash /home/ss/vllm-py12/tshark_bash.sh >> /home/ss/vllm-py12/tshark_bash.log 2>&1 & echo $! > /home/ss/vllm-py12/tshark_bash.pid
|
||||
|
||||
# 运行了1个定时任务脚本,清理 tshark 的临时文件并重启 java 脚本
|
||||
sudo nohup /home/ss/vllm-py12/timer_bash.sh > /home/ss/vllm-py12/timer_bash.log 2>&1 & echo $! > /home/ss/vllm-py12/timer_bash.pid
|
||||
|
||||
# 杀死上面3个进程的命令
|
||||
sudo kill -9 $(cat /home/ss/vllm-py12/timer_bash.pid)
|
||||
sudo kill -9 $(cat /home/ss/vllm-py12/tshark_bash.pid)
|
||||
sudo kill -9 $(cat /home/ss/vllm-py12/vllm.pid)
|
||||
|
||||
# 清理日志
|
||||
cd /home/ss/vllm-py12 && rm -rf timer_bash.log tshark_bash.log shark.log
|
||||
|
||||
# 通过docker托管了3个容器
|
||||
cd /home/ss/vllm-py12/skw && docker compose up -d
|
||||
# 移除容器
|
||||
cd /home/ss/vllm-py12/skw && docker compose down
|
||||
|
||||
# 创建了一个新的环境,python版本换成3.10
|
||||
conda create -n vllm-py310 python=3.10 -y
|
||||
```
|
||||
@ -1,145 +0,0 @@
|
||||
## 脚本说明
|
||||
|
||||
- 在 Linux 运行`TShark.java`必须先安装**tshark**,在 Windows 上运行必须先安装**Wireshark**客户端,在安装时勾选**tshark**组件。
|
||||
- 必须使用超级管理员账号运行`TShark.java`,这是**tshark**命令的限制,在 Windows 上可以使用管理员权限打开命令行运行。
|
||||
- Java 脚本基于**Java21**开发,可直接使用`java TShark.java`运行,运行后会在当前目录下创建一个**shark.log**文件,保存抓包日志。
|
||||
- 建议创建一个 bash 或者 cmd 脚本,在 bash 或 cmd 脚本中配置好 JDK 环境变量,然后再使用管理员权限运行 bash 或 cmd 脚本。
|
||||
|
||||
##### TShark.java
|
||||
|
||||
```java
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public final class TShark {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai")));
|
||||
Path path = Path.of("shark.log");
|
||||
File sharkLog = path.toFile();
|
||||
if (!sharkLog.exists() && !sharkLog.createNewFile()) {
|
||||
throw new RuntimeException("create shark.log failure");
|
||||
}
|
||||
// DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
Process process = startSharkProcess();
|
||||
System.out.println("start tshark success");
|
||||
startProcessSharkThread(process, sharkLog);
|
||||
System.out.println("start process thread success");
|
||||
int exitCode = process.waitFor();
|
||||
System.out.println("tshark process is dead, exit code: " + exitCode);
|
||||
}
|
||||
|
||||
private static void startProcessSharkThread(Process process, File sharkLog) {
|
||||
Thread thread = new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(sharkLog, true))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
fileWriter.write(line + System.lineSeparator());
|
||||
}
|
||||
fileWriter.flush();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
thread.setName("TShark-thread");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static Process startSharkProcess() throws IOException {
|
||||
List<String> cmd = List.of(
|
||||
"tshark",
|
||||
"-l",
|
||||
"-i",
|
||||
"\\Device\\NPF_{807C63AC-179D-4AC8-BD56-85CE8AA179DB}",
|
||||
"-Y",
|
||||
"tcp.port == 33000 && http.request.method == \"POST\"",
|
||||
"-V"
|
||||
);
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
|
||||
processBuilder.redirectErrorStream(true);
|
||||
return processBuilder.start();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### 通过 NEWAPI 调用 vLLM 运行的 gpt-oss-120b 模型
|
||||
|
||||
```java
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class HttpPost {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (HttpClient httpClient = HttpClient.newHttpClient()) {
|
||||
HttpRequest httpRequest = HttpRequest.newBuilder()
|
||||
.uri(URI.create(apiUrl))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", apiKey)
|
||||
.timeout(Duration.ofMinutes(5L))
|
||||
.POST(HttpRequest.BodyPublishers.ofString(request))
|
||||
.build();
|
||||
CompletableFuture<Void> completableFuture = httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines()).thenAccept(response -> {
|
||||
System.out.println("SSE success status " + response.statusCode() + ", response body: ");
|
||||
response.body().forEach(System.out::println);
|
||||
}).exceptionally(throwable -> {
|
||||
System.out.println("SSE failure error message: " + throwable.getMessage());
|
||||
throwable.printStackTrace();
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
completableFuture.get();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final String apiUrl = "http://10.159.252.49:33000/v1/chat/completions";
|
||||
|
||||
static final String apiKey = "Bearer sk-rbWEGdsaZ47e2hQFZt2xRHqWRZaipYlkyLqHdU2z9FlWj7D3";
|
||||
|
||||
static final String request = """
|
||||
{
|
||||
"model": "gpt-oss-120b",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "成龙今年71岁,请把这句话的信息,按照`user_response`结构生成一个JSON"
|
||||
}
|
||||
],
|
||||
"stream": true,
|
||||
"extra_body":{
|
||||
"structured_outputs": true,
|
||||
"guided_decoding": true
|
||||
},
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": "user_response",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"age": {"type": "number"}
|
||||
},
|
||||
"required": ["name", "age"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
}
|
||||
""".strip();
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
@ -1,139 +0,0 @@
|
||||
## LLM基础应用框架评测对象
|
||||
|
||||
- Spring AI Alibaba(SAA)
|
||||
- Spring AI
|
||||
- LangChain4J
|
||||
- LangChain
|
||||
|
||||
## 多智能体框架评测对象
|
||||
|
||||
- LangGraph
|
||||
- Spring AI Alibaba Graph
|
||||
- AutoGen
|
||||
- CrewAI
|
||||
|
||||
## 第一部分:LLM基础应用框架
|
||||
|
||||
| - | SAA| Spring AI | LangChain4J | LangChain |
|
||||
|:-----|:-----|:-----|:-----|:-----|
|
||||
| 语言 | Java | Java | Java | Python |
|
||||
| 聊天模型 | ✅ | ✅ | ✅ | ✅ |
|
||||
| 嵌入模型 | ✅ | ✅ | ✅ | ✅ |
|
||||
| 图片、音视频模型 | ✅ | ✅ | ✅ | ✅ |
|
||||
| RAG | ✅ | ✅ | ✅ | ✅ |
|
||||
| 向量数据库 | ✅ | ✅ | ✅ | ✅ |
|
||||
| MCP | ✅ | ✅ | ✅ | ✅ |
|
||||
| 函数调用 | ✅ | ✅ | ✅ | ✅ |
|
||||
| 提示词模板 | ✅ | ✅ | ✅ | ✅ |
|
||||
| 聊天记忆 | ✅ | ✅ | ✅ | ✅ |
|
||||
| 模型评估 | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
> 💡SAA 在向量数据库的支持上扩展了 AnalyticDB (ADB)、OpenSearch,支持 Nacos MCP Registry,支持 Nacos 配置提示词模板,同时支持热更新。
|
||||
|
||||
## 第二部分:与模型提供商之间的适配程度
|
||||
|
||||
> 打❌号的只能通过OpenAI API 兼容
|
||||
|
||||
| 对比项 | Open AI | Anthropic | 阿里百炼 | 百度千帆 | Xinference |
|
||||
|:-----|:-----|:-----|:-----|:-----|:-----|
|
||||
| SAA | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Spring AI | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| LangChain4J | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| LangChain | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||
| AutoGen | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||
| CrewAI | ✅ | ✅ | ❌ | ❌ | ✅ |
|
||||
|
||||
> 💡阿里百炼和百度千帆都是通过 langchain-openai 组件适配了 LangChain 框架,但是阿里百炼是残血版,**不支持多模态模型**,百度千帆则是**支持多模态模型的**。**AutoGen**和**CrewAI**对于模型提供商的支持在下文有详细说明。
|
||||
|
||||
## 第三部分:可观测性(OpenTelemetry)
|
||||
|
||||
**OpenTelemetry** 通常缩写为**OTel**,是一个开源的、厂商中立的可观测性框架,旨在实现遥测数据的标准化生成、收集和管理。遥测数据包括日志、指标和追踪,对于监控和理解软件系统的行为至关重要。
|
||||
|
||||
| Spring AI | SAA | LangChain4J | LangChain | AutoGen | CrewAI |
|
||||
|:-----|:-----|:-----|:-----|:-----|:-----|
|
||||
| ✅ | ✅ | ❌ | ✅ | ✅| ✅ |
|
||||
|
||||
- **Spring AI**为其核心组件提供了指标和追踪能力,例如 ChatClient(包括 Advisor)、ChatModel、EmbeddingModel、ImageModel 和 VectorStore 等。
|
||||
- **SAA**除了拥有**Spring AI**的能力,还提供了配套工具,无需额外编写代码,即可扇出至阿里云ARMS。
|
||||
- **LangChain4J**提供了一系列**Listener**,通过 OTel 扇出数据,需要自行实现或借助三方工具。
|
||||
- **LangChain**自带**LangSmith**,并且支持了OTel,仅需少量代码即可扇出数据。
|
||||
- **AutoGen和CrewAI**官方均提供了对 OTel 的支持。
|
||||
|
||||
## 第四部分:多智能体框架对比
|
||||
|
||||
#### 一、LangGraph
|
||||
|
||||
- 开源协议:MIT
|
||||
- 语言:Python
|
||||
- 核心:使用图结构编排智能体,相比链式调用,能够应对更多场景、更复杂的任务。
|
||||
- 亮点:内置 Checkpoint 和中断、持久化机制,在执行期间发生中断,恢复时可以从 Checkpoint 继续执行。适合通过**人工干预**保障执行过程的正确性,以及**长时间运行的任务**发生异常中断从 Checkpoint 恢复执行,而不必重新开始。
|
||||
- 补充:官方的 LangGraph Platform 还提供了配套的 LangGraph Studio 用于开发智能体的 IDE,它支持可视化、交互和调试,还与 LangSmith 集成,以实现追踪、评估和提示工程。
|
||||
- 模型:参见上文对于 LangChain 支持的模型提供商说明
|
||||
|
||||
> 💡LangGraph Platform 是**收费**的,适合企业部署的自托管版本仅支持 AWS。
|
||||
|
||||
#### 二、Spring AI Alibaba Graph
|
||||
|
||||
- 开源协议:Apache 2.0
|
||||
- 语言:Java
|
||||
- 亮点:LangGraph 的核心能力基本上都抄了
|
||||
- 模型:参见上文对于 SAA 支持的模型提供商说明
|
||||
|
||||
官方原话:Spring AI Alibaba Graph 是社区核心实现之一,也是整个框架在设计理念上区别于 Spring AI 只做底层原子抽象的地方,Spring AI Alibaba 期望帮助开发者更容易的构建智能体应用。基于 Graph 开发者可以构建工作流、多智能体应用。**Spring AI Alibaba Graph 在设计理念上借鉴 LangGraph,因此在一定程度上可以理解为是 Java 版的 LangGraph 实现**,社区在此基础上增加了大量预置 Node、简化了 State 定义过程等,让开发者更容易编写对等低代码平台的工作流、多智能体等。
|
||||
|
||||
#### 三、AutoGen
|
||||
|
||||
- 开源协议:MIT
|
||||
- 语言:Python、.NET
|
||||
- 核心:用多个智能体扮演不同的角色,让其更专注于细粒度的任务。使用团队去关联多个智能体,用消息作为团队成员之间的通信方式,让团队之间"沟通"并共同完成任务。
|
||||
- 亮点:命令行代码执行器能够将Python代码块打包成1个文件,丢到 Docker 容器执行,或者在本机开启1个新的进程执行。这种方式更安全,也是 LangGraph
|
||||
不具备的特性。除此之外,官方提供了一系列多智能体的设计模式,来辅助开发者设计与开发多智能体。AutoGen 还提供了一个免费的、本地化部署的 AutoGen Studio 可视化工具,旨在帮助开发团队快速原型化多智能体。
|
||||
- 模型:OpenAI API 兼容的模型提供商、托管在 Azure 上的模型、Ollama、Anthropic,通过 SKChatCompletionAdapter 已适配的其它 LLM 提供商有:Google、MistralAI、AWS、Hugging
|
||||
Face。暂未支持阿里百炼和百度千帆平台,只能通过 OpenAI API 兼容。
|
||||
|
||||
官方提供了多种多智能体设计模式:Concurrent Agents(并发智能体)、Sequential Workflow(顺序工作流)、Group Chat(群聊)、Handoffs(交接,源自OpenAI Swarm)、Mixture of Agents(混合代理)、Multi-Agent
|
||||
Debate(多智能体辩论)、Reflection(反思)、Code Execution(代码执行)
|
||||
|
||||
#### 四、Crew AI
|
||||
|
||||
- 开源协议:MIT
|
||||
- 语言:Python
|
||||
- 核心:与 AutoGen 类似,也是用角色扮演和团队去组织多个智能体,也支持使用流程编排。
|
||||
- 亮点:相比 AutoGen 来说 CrewAI 提供的 API 更精简、逻辑更清晰、代码语义更强,相比 LangGraph 更轻量。
|
||||
- 模型:CrewAI 通过 LiteLLM 连接到 LLM 提供商,暂未适配阿里百炼和百度千帆平台,只能通过 OpenAI API 兼容。
|
||||
|
||||
[点击查看 LiteLLM 支持的模型提供商](https://docs.litellm.com.cn/docs/providers),[点击查看对于 Xinference 的支持说明](https://docs.litellm.com.cn/docs/providers/xinference)
|
||||
|
||||
## 总结
|
||||
|
||||
如果语言倾向于Java,则 SAA(Graph)更适合作为多智能体开发框架。从图结构的编排和团队及其角色扮演的2种架构设计来看,AutoGen 和 CrewAI对于开发人员和使用者来说,心智负担更低,基于团队、成员(角色扮演)会比图的方式,更明确地规划智能体工作内容和任务目标。CrewAI
|
||||
相比 AutoGen 来说,使用更为简单,上手更容易一些。
|
||||
|
||||
## 参考资料
|
||||
|
||||
- SAA 官网:https://java2ai.com
|
||||
- Spring AI 官方文档:https://docs.springframework.org.cn/spring-ai/reference/index.html
|
||||
- LangChain4J 官方文档:https://docs.langchain4j.info/get-started
|
||||
- LangChain 官方文档:https://python.langchain.ac.cn/docs/introduction
|
||||
- 使用 OpenTelemetry 跟踪 LangChain:https://langsmith.langchain.ac.cn/observability/how_to_guides/trace_langchain_with_otel
|
||||
- 使用 OpenTelemetry 客户端将记录到 LangSmith:https://langsmith.langchain.ac.cn/observability/how_to_guides/trace_with_opentelemetry
|
||||
- Spring AI 可观测性:https://docs.springframework.org.cn/spring-ai/reference/observability/index.html
|
||||
- Spring AI 对于聊天模型可观测性的支持说明:https://docs.springframework.org.cn/spring-ai/reference/observability/index.html#_chat_model
|
||||
- 阿里百炼对于 LangChain 的适配:https://help.aliyun.com/zh/model-studio/use-bailian-in-langchain
|
||||
- 百度千帆对于 LangChain 的适配:https://cloud.baidu.com/doc/qianfan-docs/s/Mm9cr5bs6
|
||||
- LangGraph 官方文档:https://github.langchain.ac.cn/langgraph/
|
||||
- LangGraph Platform 官方文档:https://github.langchain.ac.cn/langgraphjs/concepts/langgraph_platform/
|
||||
- LangGraph Platform 定价说明:https://langchain.ac.cn/pricing-langgraph-platform
|
||||
- LangGraph Studio 使用说明:https://github.langchain.ac.cn/langgraphjs/concepts/langgraph_studio/
|
||||
- AutoGen 官方文档:https://msdocs.cn/autogen/stable/user-guide/core-user-guide/quickstart.html
|
||||
- AutoGen 运行时环境:https://msdocs.cn/autogen/stable/user-guide/core-user-guide/core-concepts/architecture.html
|
||||
- AutoGen 主题和订阅(消息传递):https://msdocs.cn/autogen/stable/user-guide/core-user-guide/core-concepts/topic-and-subscription.html
|
||||
- AutoGen 多智能体设计模式:https://msdocs.cn/autogen/stable/user-guide/core-user-guide/design-patterns/intro.html
|
||||
- AutoGen Studio 使用教程:https://www.aidoczh.com/autogen/stable/user-guide/autogenstudio-user-guide/index.html
|
||||
- CrewAI 官方文档:https://docs.crewai.org.cn/introduction
|
||||
- CrewAI Github地址:https://github.com/crewAIInc/crewAI
|
||||
|
||||
## 视频教程
|
||||
|
||||
- AutoGen:https://www.bilibili.com/video/BV1WJ4m137dk
|
||||
- CrewAI:https://www.bilibili.com/video/BV1GZ42147am
|
||||
@ -1,141 +0,0 @@
|
||||
## 修改vLLM运行gpt-oss-120b的脚本
|
||||
|
||||
在 nohup 的启动命令末尾追加如下片段,保存 vLLM 的进程 PID 号。
|
||||
|
||||
```
|
||||
echo $! > /hook/gpt-oss-120b.pid
|
||||
```
|
||||
|
||||
## 创建一个定时任务 bash 脚本
|
||||
|
||||
```
|
||||
vim /hook/timer_bash.sh
|
||||
```
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
# 目标进程的 PID 文件路径
|
||||
TARGET_PID_FILE="/hook/gpt-oss-120b.pid"
|
||||
|
||||
# tshark_bash 的 PID 文件路径
|
||||
TSARK_PID_FILE="/hook/tshark_bash.pid"
|
||||
|
||||
# tshark_bash 脚本路径
|
||||
TSARK_SCRIPT_PATH="/hook/tshark_bash.sh"
|
||||
|
||||
# tshark_bash 日志文件路径
|
||||
TSARK_LOG_FILE="/hook/tshark_bash.log"
|
||||
|
||||
# shark.log 文件路径
|
||||
SHARK_LOG_FILE="/hook/shark.log"
|
||||
|
||||
# 临时目录下要删除的 pcapng 文件路径模式
|
||||
PCAPNG_FILES_PATTERN="/tmp/*.pcapng"
|
||||
|
||||
# 5分钟检查一次 vllm 进程是否存活
|
||||
# 若 vllm 进程存活,清理 tshark 的临时文件,然后重启 tshark 脚本继续抓包
|
||||
# 若 vllm 进程已死亡则 kill tshark 的进程
|
||||
|
||||
while true; do
|
||||
if [[ -f "$TARGET_PID_FILE" ]]; then
|
||||
TARGET_PID=$(cat "$TARGET_PID_FILE" 2>/dev/null)
|
||||
if [[ "$TARGET_PID" =~ ^[0-9]+$ ]] && ps -p "$TARGET_PID" > /dev/null 2>&1; then
|
||||
echo "$(date): 目标进程 (PID: $TARGET_PID) 存活,执行相应操作..."
|
||||
if [[ -f "$TSARK_PID_FILE" ]]; then
|
||||
TSHARK_PID=$(cat "$TSARK_PID_FILE" 2>/dev/null)
|
||||
if [[ "$TSHARK_PID" =~ ^[0-9]+$ ]]; then
|
||||
kill -9 "$TSHARK_PID" 2>/dev/null
|
||||
echo "已强制杀死 tshark_bash 进程 (PID: $TSHARK_PID)"
|
||||
else
|
||||
echo "tshark_bash.pid 文件内容无效或为空,跳过 kill 操作"
|
||||
fi
|
||||
else
|
||||
echo "tshark_bash.pid 文件不存在,跳过 kill 操作"
|
||||
fi
|
||||
|
||||
if [[ -f "$SHARK_LOG_FILE" ]]; then
|
||||
rm -rf "$SHARK_LOG_FILE"
|
||||
echo "已删除 $SHARK_LOG_FILE"
|
||||
else
|
||||
echo "$SHARK_LOG_FILE 文件不存在,跳过删除"
|
||||
fi
|
||||
|
||||
if ls $PCAPNG_FILES_PATTERN >/dev/null 2>&1; then
|
||||
rm -rf $PCAPNG_FILES_PATTERN
|
||||
echo "已删除 $PCAPNG_FILES_PATTERN 文件"
|
||||
else
|
||||
echo "没有找到 $PCAPNG_FILES_PATTERN 文件,跳过删除"
|
||||
fi
|
||||
|
||||
echo "重启 tshark_bash.sh..."
|
||||
sudo nohup bash "$TSARK_SCRIPT_PATH" >> "$TSARK_LOG_FILE" 2>&1 &
|
||||
NEW_TSHARK_PID=$!
|
||||
echo "$NEW_TSHARK_PID" > "$TSARK_PID_FILE"
|
||||
echo "已启动 tshark_bash.sh,新 PID: $NEW_TSHARK_PID,已写入 $TSARK_PID_FILE"
|
||||
|
||||
else
|
||||
echo "$(date): 目标进程 (PID: ${TARGET_PID:-未知}) 不存在或已挂掉,执行清理操作..."
|
||||
|
||||
if [[ -f "$TSARK_PID_FILE" ]]; then
|
||||
TSHARK_PID=$(cat "$TSARK_PID_FILE" 2>/dev/null)
|
||||
if [[ "$TSHARK_PID" =~ ^[0-9]+$ ]]; then
|
||||
kill -9 "$TSHARK_PID" 2>/dev/null
|
||||
echo "已强制杀死 tshark_bash 进程 (PID: $TSHARK_PID)"
|
||||
else
|
||||
echo "tshark_bash.pid 文件内容无效或为空,跳过 kill 操作"
|
||||
fi
|
||||
else
|
||||
echo "tshark_bash.pid 文件不存在,跳过 kill 操作"
|
||||
fi
|
||||
|
||||
if ls $PCAPNG_FILES_PATTERN >/dev/null 2>&1; then
|
||||
rm -rf $PCAPNG_FILES_PATTERN
|
||||
echo "已删除 $PCAPNG_FILES_PATTERN 文件"
|
||||
else
|
||||
echo "没有找到 $PCAPNG_FILES_PATTERN 文件,跳过删除"
|
||||
fi
|
||||
|
||||
echo "目标进程已挂掉,已执行清理操作。"
|
||||
fi
|
||||
else
|
||||
echo "$(date): 目标 PID 文件 $TARGET_PID_FILE 不存在,跳过本次检查。"
|
||||
fi
|
||||
|
||||
sleep 300
|
||||
done
|
||||
```
|
||||
|
||||
## 定时任务
|
||||
|
||||
##### 第一次运行先赋权
|
||||
|
||||
```
|
||||
chmod +x vim /hook/timer_bash.sh
|
||||
```
|
||||
|
||||
##### 运行
|
||||
|
||||
```
|
||||
sudo nohup /hook/timer_bash.sh > /hook/timer_bash.log 2>&1 & echo $! > /hook/timer_bash.pid
|
||||
```
|
||||
|
||||
##### 停止
|
||||
|
||||
```
|
||||
kill $(cat /hook/timer_bash.pid)
|
||||
```
|
||||
|
||||
## 抓包脚本
|
||||
|
||||
##### 运行
|
||||
|
||||
```
|
||||
sudo nohup bash /hook/tshark_bash.sh >> /hook/tshark_bash.log 2>&1 & echo $! > /hook/tshark_bash.pid
|
||||
```
|
||||
|
||||
##### 停止
|
||||
|
||||
```
|
||||
kill -9 $(cat /hook/tshark_bash.pid)
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user