6.8.2 qmgr_transport_select函数: 选择QMGR_TRANSPORT 与round borin策略
2016-04-07 15:28
423 查看
/qmgr/qmgr_transport.c/qmgr_transport_select函数使用roundborin策略选择MDA进行发信。
先来回顾一下QMGR_QUEUE结构体的三个字段:
window:即参数initial_destination_concurrency,表示MDA默认并发发信量,随运行状况变化。
todo_refcount和busy_refcount记录QMGR_QUEUE当前的todo和busy收件人数量。
288-304 用双重循环来选择QMGR_TRANSPORT,外层循环针对QMGR_TRANSPORT链表(288行),内层循环针对QMGR_QUEUE(293行),选择条件如下:
1 为其分配的QMGR_TRANSPORT_ALLOC不超过QMGR_TRANSPORT_MAX_PEND(290行,QMGR_TRANSPORT_MAX_PEND默认为2) 。
2 该QMGR_TRANSPORT依然有QMGR_QUEUE可以承受本服务器向其并发发信(294行):
#define QMGR_QUEUE_READY(q) ((q)->window > 0)。
3 该QMGR_TRANSPORT依然有QMGR_QUEUE有未发送的(todo)QMGR_ENTRY_LIST供QMGR_TRANSPORT_ALLOC发送。
总之一句话:按“最近最少”原则,先选择没有充分完成任务的MDA来发信,这样对MDA的利用是平衡的,类似于linux的“完全公平调度算法”的思路——因为他们追求的都是“吞吐量”。qmgr_peer_select的实现和这里类似。
/qmgr/qmgr_transport.c 268 /* qmgr_transport_select - selecttransport for allocation */ 269 270 QMGR_TRANSPORT*qmgr_transport_select(void) 271 { 272 QMGR_TRANSPORT *xport; 273 QMGR_QUEUE *queue; 274 int need; 275 276 /* 277 * If we find a suitable transport, rotate the list of transports to 278 * effectuate round-robin selection. See similar selection code in 279 * qmgr_peer_select(). 280 * 281 * This function is called repeatedly until all transports have maxed out 282 * the number of pending delivery agent connections, until all delivery 283 * agent concurrency windows are maxed out, or until we run out of"todo" 284 * queue entries. 285 */ 286 #define MIN5af51743e4eef(x, y) ((x)< (y) ? (x) : (y)) 287 288 for (xport = qmgr_transport_list.next; xport; xport =xport->peers.next) { 289 if ((xport->flags & QMGR_TRANSPORT_STAT_DEAD) != 0 290 || xport->pending >=QMGR_TRANSPORT_MAX_PEND) 291 continue; 292 need = xport->pending + 1; 293 for (queue = xport->queue_list.next; queue; queue =queue->peers.next) { 294 if (QMGR_QUEUE_READY(queue) == 0) 295 continue; 296 if ((need -=MIN5af51743e4eef(queue->window - queue->busy_refcount, 297 queue->todo_refcount)) <= 0) { 298 QMGR_LIST_ROTATE(qmgr_transport_list, xport, peers); 299 if (msg_verbose) 300 msg_info("qmgr_transport_select: %s", xport->name); 301 return (xport); 302 } 303 } 304 } 305 return (0); 306 }
先来回顾一下QMGR_QUEUE结构体的三个字段:
window:即参数initial_destination_concurrency,表示MDA默认并发发信量,随运行状况变化。
todo_refcount和busy_refcount记录QMGR_QUEUE当前的todo和busy收件人数量。
288-304 用双重循环来选择QMGR_TRANSPORT,外层循环针对QMGR_TRANSPORT链表(288行),内层循环针对QMGR_QUEUE(293行),选择条件如下:
1 为其分配的QMGR_TRANSPORT_ALLOC不超过QMGR_TRANSPORT_MAX_PEND(290行,QMGR_TRANSPORT_MAX_PEND默认为2) 。
2 该QMGR_TRANSPORT依然有QMGR_QUEUE可以承受本服务器向其并发发信(294行):
#define QMGR_QUEUE_READY(q) ((q)->window > 0)。
3 该QMGR_TRANSPORT依然有QMGR_QUEUE有未发送的(todo)QMGR_ENTRY_LIST供QMGR_TRANSPORT_ALLOC发送。
总之一句话:按“最近最少”原则,先选择没有充分完成任务的MDA来发信,这样对MDA的利用是平衡的,类似于linux的“完全公平调度算法”的思路——因为他们追求的都是“吞吐量”。qmgr_peer_select的实现和这里类似。
相关文章推荐
- SQL Server 索引和视图
- expandview可实现区域选择,可实现类似58筛选功能
- only available on JDK 1.5 and higher
- scala中的method和function的区别
- pca的具体应用QT+OPENCV人脸主成分提取和还原
- 基于.NET平台常用的框架整理
- SqlServer 汉字转换拼音首字母函数
- 自定义UICollectionViewLayout(一) ----LineLayout
- C++ map的基本操作和使用
- Android性能典范:拯救计划
- SQL Server T-SQL高级查询1
- 开始学习了(C++版)
- CSS 制作三角形原理剖析
- android 界面控件 textview 全解
- webService调用
- iOS 使用AFNetWorking监听APP网络状态变化(可用于更改缓存策略、提示网络等)
- linux ssh基本
- iOS开发数据库篇—SQLite的应用
- 月份,星期几的英文表示
- springmvc常用注解与类型转换