You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ansible以Round-Robin(轮询)方式分配工单给用户?

问题描述

我有两个列表:

inc_numbers: [A, B, C, D, E, F, G] 

users:
- username: u1
  status: active
  
- username: u2
  status: active
  
- username: u3
  status: active

- username: u4
  status: active

第一个列表是工单,第二个是用户,需要在Ansible中通过轮询(Round-Robin)方式分配这些工单。

我尝试了以下代码,但未能得到预期输出,仅完成一轮用户循环就结束了:

- name: with_together -> loop
    set_fact:
      inc_user_map: "{{ inc_user_map|default([]) + [{ 'inc_numbers':item.0, 'users':item.1.username }] }}"
      with_together:
      - "{{ inc_numbers }}"
      - "{{ users }}"

  - name: Nested loop
    set_fact:
        inc_sel: "{{ inc_sel|d([]) + [item|combine({'selection': selection})] }}"
    loop: "{{ users }}"
    vars:
      username: "{{ item.username }}"
      selection: "{{ inc_numbers|\n                     zip(username)|\n                     rejectattr('0', 'eq', '0') }}"

预期输出:

A : u1 
B : u2 
C : u3 
D : u1 
E : u2
F : u3 
G : u1
解决方案

可以通过索引取模的方式实现轮询分配,步骤如下:

1. 提取目标用户列表

先从用户列表中筛选出需要参与分配的用户(比如预期输出里用到的u1-u3,这里以活跃用户且取前3个为例,可按需调整):

- name: 提取目标用户用户名列表
  set_fact:
    target_users: "{{ users | selectattr('status', 'equalto', 'active') | map(attribute='username') | list | slice(3) | first }}"

如果直接指定用户,也可以写成:

target_users: ["u1", "u2", "u3"]

2. 轮询分配工单

利用enumerate过滤器获取工单的索引,再通过索引对用户列表长度取模,实现循环分配:

- name: 轮询分配工单到用户
  set_fact:
    inc_user_map: "{{ inc_user_map | default([]) + [{'ticket': item.1, 'user': target_users[item.0 % target_users|length]}] }}"
  loop: "{{ inc_numbers | enumerate }}"

3. 输出分配结果

如果需要打印成预期的格式,执行以下任务:

- name: 打印分配结果
  debug:
    msg: "{{ item.ticket }} : {{ item.user }}"
  loop: "{{ inc_user_map }}"

原理说明

  • enumerate会为每个工单添加从0开始的索引,比如第一个工单A的索引是0,第二个B是1,以此类推
  • item.0 % target_users|length 用索引对用户列表的长度取模,确保索引超出用户列表长度时,会重新从第一个用户开始分配,实现轮询效果

内容的提问来源于stack exchange,提问作者SoorajRaju Spowers4u

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:12:08