<div dir="ltr">I'm trying to set up kamailio dispatcher to distribute calls to 2 asterisk servers. So far, the failover case seems ok, but I cannot get the dispatcher to distribute load. All calls are going to the last destination entry in the dispatcher table even if I have set the maxload attributes. I'm using algorithm 10 for load distribution. The number of calls sent to one asterisk is well above the maxload. Hope someone more experienced in dispatcher can review my config and give me some recommendations. Thanks in advance.<div><br></div><div>Here is the content of dispatcher table in postgresql db.</div><div><br><div><div>select * from dispatcher;</div><div> id | setid |    destination     | flags | priority |           attrs           | description</div><div>----+-------+--------------------+-------+----------+---------------------------+-------------</div><div>  1 |     1 | sip:<a href="http://10.0.1.31:5061">10.0.1.31:5061</a> |     0 |        0 | duid=asterisk1;maxload=25 | Asterisk1</div><div>  2 |     1 | sip:<a href="http://10.0.1.33:5061">10.0.1.33:5061</a> |     0 |        0 | duid=asterisk2;maxload=25 | Asterisk2</div><div>(2 rows)</div></div></div><div><br></div><div>Here are the dispatcher sections in kamailio.cfg.</div><div><div># ----- dispatcher params -----</div><div>#!ifdef WITH_DISPATCHER</div><div>modparam("dispatcher", "db_url", DBASTURL)</div><div>modparam("dispatcher", "table_name", "dispatcher")</div><div>modparam("dispatcher", "force_dst", 1). </div><div># If flag 2 is set, then failover support is enabled.<br></div><div>modparam("dispatcher", "flags", 3)</div><div># the last address in destination set is used as a final option to send the request to</div><div>modparam("dispatcher", "use_default", 1)</div><div># load balancing fail over</div><div>modparam("dispatcher", "dst_avp", "$avp(dsdst)")</div><div>modparam("dispatcher", "grp_avp", "$avp(dsgrp)")</div><div>modparam("dispatcher", "cnt_avp", "$avp(dscnt)")</div><div>modparam("dispatcher", "dstid_avp", "$avp(dsdstid)")</div><div>modparam("dispatcher", "attrs_avp", "$avp(dsattrs)")</div><div># PVs for hashing</div><div>modparam("dispatcher", "hash_pvar", "$fU@$ci")</div><div># PVs to store results when calling ds_is_from_list</div><div>modparam("dispatcher", "setid_pvname", "$var(setid)")</div><div>modparam("dispatcher", "attrs_pvname", "$var(attrs)")</div><div># method to probe the gateways</div><div>modparam("dispatcher", "ds_ping_method", "OPTIONS")</div><div>modparam("dispatcher", "ds_ping_from", "sip:dispatcher@localhost")</div><div>modparam("dispatcher", "ds_ping_interval", 30)</div><div>modparam("dispatcher", "ds_probing_threshhold", 10)</div><div>modparam("dispatcher", "ds_ping_reply_codes", "class=2;code=403;code=404;code=484;code=488;class=3")</div><div>modparam("dispatcher", "ds_probing_mode", 1)</div><div># size of hash table storing data for call load dispatching, power of two</div><div>modparam("dispatcher", "ds_hash_size", 10)</div><div># expiration time in seconds to remove the load on a destination if no BYE was received</div><div>modparam("dispatcher", "ds_hash_expire", 3600)</div><div># expiration time in seconds to remove the load on a destination if no 200 OK for INVITE was received</div><div># and state updated with ds_load_update</div><div>modparam("dispatcher", "ds_hash_initexpire", 60)</div><div>modparam("dispatcher", "ds_hash_check_interval", 30)</div><div>#!endif</div></div><div><br></div><div><div>route[WITHINDLG] {</div><div><span class="" style="white-space:pre">   </span>if (has_totag()) {</div><div><span class="" style="white-space:pre">         </span># sequential request withing a dialog should</div><div><span class="" style="white-space:pre">               </span># take the path determined by record-routing</div><div><br></div><div>#!ifdef WITH_DISPATCHER</div><div><span class="" style="white-space:pre">                </span>if(is_method("BYE|CANCEL") && ds_is_from_list("1", "3"))</div><div><span class="" style="white-space:pre">                     </span>ds_load_update();</div><div>#!endif</div></div><div>......</div><div>       }</div><div>}</div><div><br></div><div><div>route[FROMASTERISK] {</div><div>#!ifdef WITH_DISPATCHER<br></div><div><span class="" style="white-space:pre">        </span>if(ds_is_from_list("1", "3")) {</div><div><span class="" style="white-space:pre">                </span>xlog("L_DBG","$rm from $fU@$si:$sp: Call from Asterisk cluster\n");</div><div><span class="" style="white-space:pre">            </span>return 1;</div><div><span class="" style="white-space:pre">  </span>}</div><div><span class="" style="white-space:pre">  </span>return -1;</div><div>#!else</div><div><span class="" style="white-space:pre">    </span>if ($si==$sel(cfg_get.asterisk.bindip)) {</div><div><span class="" style="white-space:pre">          </span>return 1;</div><div><span class="" style="white-space:pre">  </span>}</div><div><span class="" style="white-space:pre">  </span>return -1;</div><div>#!endif</div><div>}</div></div><div><br></div><div><div>onreply_route[MANAGE_REPLY] {</div><div><span class="" style="white-space:pre">       </span>xdbg("incoming reply\n");</div><div>#!ifdef WITH_DISPATCHER</div><div><span class="" style="white-space:pre">  </span>if(is_method("INVITE") && ds_is_from_list("1", "3")) {</div><div><span class="" style="white-space:pre">               </span>if(status=~"2[0-9][0-9]") {</div><div><span class="" style="white-space:pre">                      </span>ds_load_update();</div><div><span class="" style="white-space:pre">          </span>}</div><div><span class="" style="white-space:pre">          </span>else if(status=~"[3-7][0-9][0-9]") {</div><div><span class="" style="white-space:pre">                     </span>ds_load_unset();</div><div><span class="" style="white-space:pre">           </span>}</div><div><span class="" style="white-space:pre">  </span>}</div><div>#!endif</div><div><span class="" style="white-space:pre">    </span>if(status=~"[12][0-9][0-9]")</div><div><span class="" style="white-space:pre">             </span>route(NATMANAGE);</div><div>}</div></div><div><br></div><div><div>#!ifdef WITH_DISPATCHER</div><div>failure_route[RTF_DISPATCH] {</div><div><span class="" style="white-space:pre">        </span>if (t_is_canceled()) {</div><div><span class="" style="white-space:pre">             </span>exit;</div><div><span class="" style="white-space:pre">      </span>}</div><div><span class="" style="white-space:pre">  </span># next DST - only for 500 or local timeout</div><div><span class="" style="white-space:pre"> </span>if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) {</div><div>                # mark the destination Inactive and Probing</div><div><span class="" style="white-space:pre">           </span>ds_mark_dst("IP");</div><div>                # select the new destination</div><div><span class="" style="white-space:pre">            </span>if(ds_next_dst()) {</div><div><span class="" style="white-space:pre">                        </span>t_on_failure("RTF_DISPATCH");</div><div><span class="" style="white-space:pre">                    </span>route(RELAY);</div><div><span class="" style="white-space:pre">                      </span>exit;</div><div><span class="" style="white-space:pre">              </span>}</div><div>                else {</div><div>                        # last available node failed to reply, no other destinations available</div><div>                        send_reply("404", "No destination");</div><div>                        exit;</div><div>                }</div><div><span class="" style="white-space:pre"> </span>}</div><div>}</div><div>#!endif</div></div><div><br></div><div><div>route[TOASTERISK] {</div><div>#!ifdef WITH_DISPATCHER</div><div><span class="" style="white-space:pre">    </span># ds_mark_dst("IP");</div><div><span class="" style="white-space:pre">     </span># Call load distribution</div><div><span class="" style="white-space:pre">   </span>if(!ds_select_dst("1", "10")) {</div><div><span class="" style="white-space:pre">                </span>sl_send_reply("500", "Service Unavailable");</div><div><span class="" style="white-space:pre">           </span>xlog("L_INFO","$rm from $fU@$si:$sp: No destinations available for $rd\n");</div><div>                exit;</div><div>        }</div><div><span class="" style="white-space:pre">    </span>xlog("L_DBG", "--- SCRIPT: going to <$ru> via <$du>\n");</div><div><span class="" style="white-space:pre">   </span>t_on_failure("RTF_DISPATCH");</div><div>#!else</div><div><br></div><div>   <span class="" style="white-space:pre"> </span>$du = "sip:" + $sel(cfg_get.asterisk.bindip) + ":"</div><div><span class="" style="white-space:pre">                     </span>+ $sel(cfg_get.asterisk.bindport);</div><div>#!endif</div><div><span class="" style="white-space:pre">   </span>route(RELAY);</div><div><span class="" style="white-space:pre">      </span>exit;</div><div>}</div></div><div><br></div><div><div><br></div><div># Dispatcher detects a destination goes down</div><div>event_route[dispatcher:dst-down] {</div><div>    xlog("L_ERR", "Destination down: $rm $ru ($du)\n");</div><div>}</div><div><br></div><div># Dispatcher detects a destination comes up </div><div>event_route[dispatcher:dst-up] {</div><div>    xlog("L_ERR", "Destination up: $rm $ru\n");</div><div>}</div></div></div>