一、趣味类比:责任链 = 邮局多级分拣流水线
我们给邮局搭建全自动分拣流水线:
- 一级分拣员:只处理系统紧急消息,处理完毕终止流转,不匹配交给下一级
- 二级分拣员:只处理普通业务消息,不匹配交给下一级
- 三级分拣员:兜底处理器,处理所有未知异常消息
核心思想:每一个处理器只负责自己的职责,不越权、不遗漏,消息自动逐级传递,这就是责任链模式。
二、责任链模式四大角色(适配消息队列)
表格
| 角色 | 对应代码 | 邮局类比 |
|---|---|---|
| 抽象处理者 | MsgHandler | 分拣员通用模板,设置下一级继任者 |
| 具体处理者 A | SysHandler | 处理系统紧急消息 type=1 |
| 具体处理者 B | BizHandler | 处理普通业务消息 type=2 |
| 兜底处理者 | DefaultHandler | 处理未知类型消息,日志兜底 |
三、完整可运行:责任链 + System V 消息队列工程代码
c
运行
cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#define MSG_LEN 128
// 消息结构体
typedef struct {
long type;
char data[MSG_LEN];
} Message;
// ====================== 责任链:抽象处理者 ======================
typedef struct MsgHandler {
// 设置下一级处理器
void (*setNext)(struct MsgHandler*, struct MsgHandler*);
// 处理消息接口
void (*handle)(struct MsgHandler*, Message*);
struct MsgHandler* next;
} MsgHandler;
// ====================== 具体处理器1:系统紧急消息 type=1 ======================
void sys_handle(MsgHandler* thiz, Message* msg) {
if(msg->type == 1) {
printf("[系统处理器] 处理紧急消息:%s\n", msg->data);
return;
}
// 不匹配,传递给下一级
if(thiz->next) thiz->next->handle(thiz->next, msg);
}
// ====================== 具体处理器2:普通业务消息 type=2 ======================
void biz_handle(MsgHandler* thiz, Message* msg) {
if(msg->type == 2) {
printf("[业务处理器] 处理普通消息:%s\n", msg->data);
return;
}
if(thiz->next) thiz->next->handle(thiz->next, msg);
}
// ====================== 兜底处理器:未知消息 ======================
void default_handle(MsgHandler* thiz, Message* msg) {
printf("[兜底处理器] 未知类型消息,记录日志:%s\n", msg->data);
}
// 通用设置下一级
void set_next(MsgHandler* thiz, MsgHandler* next) {
thiz->next = next;
}
// 创建处理器
MsgHandler* create_handler(void (*handle)(MsgHandler*, Message*)) {
MsgHandler* h = malloc(sizeof(MsgHandler));
h->handle = handle;
h->setNext = set_next;
h->next = NULL;
return h;
}
// ====================== 消息队列工具 ======================
int get_msg_queue(key_t key) {
return msgget(key, IPC_CREAT | 0666);
}
void send_msg(int msqid, long type, char* buf) {
Message msg;
msg.type = type;
strncpy(msg.data, buf, MSG_LEN);
msgsnd(msqid, &msg, MSG_LEN, 0);
}
void recv_and_dispatch(int msqid, MsgHandler* head) {
Message msg;
while(1) {
// 非阻塞接收
if(msgrcv(msqid, &msg, MSG_LEN, 0, IPC_NOWAIT) < 0) {
break;
}
// 责任链统一分发处理
head->handle(head, &msg);
}
}
// ====================== 主函数测试 ======================
int main() {
// 1. 构建责任链流水线
MsgHandler* sys_handler = create_handler(sys_handle);
MsgHandler* biz_handler = create_handler(biz_handle);
MsgHandler* def_handler = create_handler(default_handle);
// 串联链路:系统处理器 -> 业务处理器 -> 兜底处理器
sys_handler->setNext(sys_handler, biz_handler);
biz_handler->setNext(biz_handler, def_handler);
// 2. 创建消息队列
key_t key = ftok("./msgtest.txt", 0x33);
int msqid = get_msg_queue(key);
// 3. 模拟发送三类消息
send_msg(msqid, 1, "服务器CPU告警,紧急处理!");
send_msg(msqid, 2, "用户普通登录日志");
send_msg(msqid, 99, "未知非法数据包");
// 4. 责任链自动分发处理
recv_and_dispatch(msqid, sys_handler);
// 释放资源
msgctl(msqid, IPC_RMID, NULL);
free(sys_handler);
free(biz_handler);
free(def_handler);
return 0;
}
运行结果:
plaintext
[系统处理器] 处理紧急消息:服务器CPU告警,紧急处理!
[业务处理器] 处理普通消息:用户普通登录日志
[兜底处理器] 未知类型消息,记录日志:未知非法数据包
四、本篇横向树状思维导图

五、最终三篇全套总结
- 第一篇:吃透 System V 消息队列内核机制、原生 API、通信原理,打好底层基础;
- 第二篇:剖析原生开发工程痛点,完成基础封装,明确「多级消息处理」的需求缺口;
- 第三篇:落地责任链设计模式,实现消息分级、分层、流水线自动化处理,达到企业工程级可用性。
整套架构完美解决了 System V 消息队列消息混杂、处理耦合、扩展性差的致命问题,是 Linux 进程通信 + 设计模式的经典落地方案。
谢谢