Kamailio-超强dispatcher负载均衡模块

Kamailio 负载均衡的功能主要依靠 Dispatcher 模块完成,模块官方文档参看

  • 为什么要引入负载均衡?
  • 如何使用?
    • 引入和配置
    • 功能路由调用
    • 命令行指令

为什么要引入负载均衡?

Q: 如果单台VOIP服务的性能不能满足业务需求了,需要扩展至多个节点,那么Kamailio将如何进行请求的代理呢?

A: 就是需要负载均衡

Q: 如果多个后端VOIP服务有不可用,转过去的请求全部失败,那么Kamailio可以如何保障整体流程的健壮性?

A: 就是需要负载均衡剔除异常服务节点,转发至可用节点

此外,依赖负载均衡的基础功能,还可以实现AB测试、区分权重、通道量分发等业务相关逻辑

既然看上去功能强大且十分诱人的功能,要如何才能使用呢?

在这里插入图片描述

如何使用?

这个模块是自带的,不需要额外加入并构建,在modules的目录下存在

引入和配置

kamailio.cfg 中,引入模块,并增加配置项

常规的DB方式配置

loadmodule "dispatcher.so"# ----- dispatcher params -----
modparam("dispatcher", "db_url", DBURL)
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
modparam("dispatcher", "xavp_ctx", "_dsctx_")
modparam("dispatcher", "ds_ping_from", "sip:proxy@kamailio.org")
modparam("dispatcher", "ds_ping_interval", 60)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_timer_mode", 1)

可以通过DB的方式加载分发的列表,也可以通过最基础的文件的方式引入,都支持动态加载

以下是文件方式

loadmodule "dispatcher.so"# ----- dispatcher params -----
modparam("dispatcher", "list_file", "/usr/local/etc/kamailio/dispatcher.list")
modparam("dispatcher", "force_dst", 1)
#剩余参数取决于你的负载均衡模式

功能路由调用

request_route {....# dispatch destinationsroute(DISPATCH);
}# Dispatch requests
route[DISPATCH] {# round robin dispatching on gateways group '1'if(!ds_select_dst("1", "4")) {send_reply("404", "No destination");exit;}xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");t_on_failure("RTF_DISPATCH");route(RELAY);exit;
}

着重需要关注的方法就是 ds_select_dst(set, alg[, limit]),即挑选哪一个分组的地址列表,采用什么样的算法进行路由选择

第一个参数set,就是地址列表,第二参数alg就是算法,第三个limit是指在AVP列表中最多可以存储的item数 。

算法有很多种,也是对负载均衡流程核心的参数,除了12种官方支持的,还可以自定义开发去使用:

  • “0” - hash over callid
  • “1” - hash over from URI.
  • “2” - hash over to URI.
  • “3” - hash over request-URI user.
  • “4” - round-robin (next destination).
  • -“5” - hash over authorization-username (Proxy-Authorization or “normal” authorization). If no username is found, round robin is used.
  • “6” - random destination (using rand()).
  • “7” - hash over the content of PVs string. Note: This works only when the parameter hash_pvar is set.
  • “8” - select destination sorted by priority attribute value (serial forking ordered by priority).
  • “9” - use weight based load distribution. You have to set the attribute ‘weight’ for each address (gateway) in destination set. See also the description of the ‘weight’ attribute in the ‘Special Attributes’ section.
  • “10” - use call load distribution. You have to set the attribute ‘duid’ (as an unique string id) per each address in destination set. Also, you must set the parameter ‘ds_hash_size’.
  • “11” - use relative weight based load distribution. You have to set the attribute ‘rweight’ per each address in destination set. Active host usage probability is rweight/(SUM of all active host rweights in destination group).
  • “12” - dispatch to all destination in setid at once (parallel forking). Note that the XAVPs are no longer set with the values of the destination records, no re-routing making sense in this case.
  • “13” - latency optimized dispatching
  • “64” - round-robin (next destination) with over load control (destination record is skipped based on over load control rate).
  • “X” - if the algorithm is not implemented, the first entry in set is chosen.

默认样例都是用round-robin去做负载,初期使用可以用这个方式,后续生产中,应该 9、10、11、13 结合实际业务压力做更好地拥塞控制

alg-4 测试示例:

...
#!KAMAILIO
#
# sample config file for dispatcher module
# - load balancing of VoIP calls with round robin
# - no TPC listening
# - don't dispatch REGISTER and presence requests
#
# Kamailio SIP Server
#     - web: https://www.kamailio.org
#     - git: http://github.com/kamailio/
#
# Direct your questions about this file to: sr-users@lists.kamailio.org
#
# Refer to the Core CookBook at https://www.kamailio.org/w/documentation/
# for an explanation of possible statements, functions and parameters.
#
# Several features can be enabled using '#!define WITH_FEATURE' directives:
#
# *** To run in debug mode:
#     - define WITH_DEBUG
##!ifndef DBURL
#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
#!endif# - flags
#   FLT_ - per transaction (message) flags
#	FLB_ - per branch flags
#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3####### Global Parameters ##########!ifdef WITH_DEBUG
debug=4
log_stderror=yes
#!else
debug=2
log_stderror=no
#!endifmemdbg=5
memlog=5log_facility=LOG_LOCAL0fork=yes
children=4/* comment the next line to enable TCP */
disable_tcp=yes/* uncomment the next line to disable the auto discovery of local aliasesbased on revers DNS on IPs (default on) */
auto_aliases=no/* add local domain aliases */
# alias="mysipserver.com"port=5060/* uncomment and configure the following line if you want Kamailio tobind on a specific interface/port/proto (default bind on all available) */
# listen=udp:127.0.0.1:5060sip_warning=no####### Modules Section ######### set module path
#mpath="/usr/local/lib/kamailio/modules/"loadmodule "db_mysql.so"
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "acc.so"
loadmodule "dispatcher.so"# ----------------- setting module-specific parameters ---------------# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)# ----- acc params -----
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
modparam("acc", "log_extra","src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si")# ----- tm params -----
modparam("tm", "fr_timer", 2000)
modparam("tm", "fr_inv_timer", 40000)# ----- dispatcher params -----
modparam("dispatcher", "db_url", DBURL)
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
modparam("dispatcher", "xavp_ctx", "_dsctx_")
modparam("dispatcher", "ds_ping_from", "sip:proxy@kamailio.org")
modparam("dispatcher", "ds_ping_interval", 60)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_timer_mode", 1)####### Routing Logic ######### main request routing logicrequest_route {# per request initial checksroute(REQINIT);# CANCEL processingif (is_method("CANCEL")) {if (t_check_trans()) {route(RELAY);}exit;}# handle retransmissionsif (!is_method("ACK")) {if(t_precheck_trans()) {t_check_trans();exit;}t_check_trans();}# handle requests within SIP dialogsroute(WITHINDLG);### only initial requests (no To tag)# record routing for dialog forming requests (in case they are routed)# - remove preloaded route headersremove_hf("Route");if (is_method("INVITE|SUBSCRIBE")) {record_route();}# account only INVITEsif (is_method("INVITE")) {setflag(FLT_ACC); # do accounting}# handle presence related requestsroute(PRESENCE);# handle registrationsroute(REGISTRAR);if ($rU==$null) {# request with no Username in RURIsl_send_reply("484","Address Incomplete");exit;}# dispatch destinationsroute(DISPATCH);
}route[RELAY] {if (!t_relay()) {sl_reply_error();}exit;
}# Per SIP request initial checks
route[REQINIT] {if (!mf_process_maxfwd_header("10")) {sl_send_reply("483","Too Many Hops");exit;}if(!sanity_check("1511", "7")) {xlog("Malformed SIP message from $si:$sp\n");exit;}
}# Handle requests within SIP dialogs
route[WITHINDLG] {if (!has_totag()) {return;}# sequential request within a dialog should# take the path determined by record-routingif (loose_route()) {if (is_method("BYE")) {setflag(FLT_ACC); # do accounting ...setflag(FLT_ACCFAILED); # ... even if the transaction fails}route(RELAY);}if (is_method("SUBSCRIBE") && uri == myself) {# in-dialog subscribe requestsroute(PRESENCE);}if ( is_method("ACK") ) {if ( t_check_trans() ) {# non loose-route, but stateful ACK;# must be ACK after a 487 or e.g. 404 from upstream servert_relay();exit;} else {# ACK without matching transaction ... ignore and discard.exit;}}sl_send_reply("404","Not here");exit;
}# Handle SIP registrations
route[REGISTRAR] {if(!is_method("REGISTER"))return;sl_send_reply("404", "No registrar");exit;
}# Presence server route
route[PRESENCE] {if(!is_method("PUBLISH|SUBSCRIBE"))return;sl_send_reply("404", "Not here");exit;
}# Dispatch requests
route[DISPATCH] {# round robin dispatching on gateways group '1'if(!ds_select_dst("1", "4")) {send_reply("404", "No destination");exit;}xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");t_on_failure("RTF_DISPATCH");route(RELAY);exit;
}# Try next destionations in failure route
failure_route[RTF_DISPATCH] {if (t_is_canceled()) {exit;}# next DST - only for 500 or local timeoutif (t_check_status("500")or (t_branch_timeout() and !t_branch_replied())) {if(ds_next_dst()) {xdbg("--- SCRIPT: retrying to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");t_on_failure("RTF_DISPATCH");route(RELAY);exit;}}
}...

alg-11 测试示例:

...
# sample of SQL provisioning statements
INSERT INTO "dispatcher"
VALUES(1,1,'sip:192.168.0.1:5060',0,12,'rweight=50;weight=50;cc=1;','');
INSERT INTO "dispatcher"
VALUES(2,1,'sip:192.168.0.2:5060',0,12,'rweight=50;weight=50;cc=1;','');
...
modparam("dispatcher", "ds_ping_interval", 1) # ping gateways once/second
modparam("dispatcher", "ds_ping_latency_stats", 1) # update congestion metrics
# configure the latency estimator
modparam("dispatcher", "ds_latency_estimator_alpha", 900)
...
if (!ds_select_dst("1", "11")) { # use relative weight based load distribution
...
# sample of output from 'kamcmd dispatcher.list'
DEST: {URI: sip:192.168.0.1:5060FLAGS: APPRIORITY: 12ATTRS: {BODY: rweight=50;weight=50;cc=1 # configuration valuesDUID:MAXLOAD: 0WEIGHT: 50RWEIGHT: 50SOCKET:SOCKNAME:OBPROXY:}LATENCY: {AVG: 20.104000STD: 1.273000# estimated congestion is currently 25ms = 45ms(EST) -20ms(AVG)EST: 45.005000MAX: 132TIMEOUT: 3}
}
...

命令行指令

Kamailio的命令行操作 dispatcher

# prototype: kamcmd dispatcher.set_state _state_ _group_ _address_
kamcmd dispatcher.set_state ip 2 sip:127.0.0.1:5080
kamcmd dispatcher.set_state ip 3 all# prototype: kamcmd dispatcher.set_duid_state _state_ _group_ _duid_
kamcmd dispatcher.set_duid_state ip 2 xyzkamcmd dispatcher.list
...
DEST: {URI: sip:192.168.0.1:5060FLAGS: APPRIORITY: 12
}
...kamcmd dispatcher.reload# prototype: kamcmd dispatcher.ping_active _state_
kamcmd dispatcher.ping_active 0# prototype: kamcmd dispatcher.add _group_ _address_ _flags_ _priority_ _attrs_
kamcmd dispatcher.add 2 sip:127.0.0.1:5080
kamcmd dispatcher.add 3 sip:127.0.0.1:5075 8
kamcmd dispatcher.add 3 sip:127.0.0.1:5075 0 0 duid=abc;socket=udp:127.0.0.1:5060
...# prototype: kamcmd dispatcher.remove _group_ _address_
kamcmd dispatcher.remove 2 sip:127.0.0.1:5080
kamcmd dispatcher.remove 3 sip:127.0.0.1:5075;transport=udp# prototype: kamctl rpc dispatcher.hash _nslots_ _val1_ [_val2_]
kamctl rpc dispatcher.hash 0 alice server.com
kamctl rpc dispatcher.hash 4 bob server.com# prototype: kamcli dispatcher.oclist _group_
kamcli dispatcher.oclist 1

最为常用的就是增、删、查、热加载,因为通常是新节点加入、老节点剔除、配置热加载这样的需求。


如果我的文章对你有帮助的话,帮忙给一个免费的关注吗?持续更新中…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中的I/O流

本节主要看代码理解 I/O流继承关系 iostream 主要类 cin cout cerr clog while&#xff08;cin>>str&#xff09; &#xff5b; //处理 &#xff5d; 当接收ctrl z 或 ctrl c时&#xff0c;会停止&#xff0c; 原理&#xff1a;重载操作符bool&#xff0c;令指定istr…

Meta:大语言模型可以通过自我批判取得大幅提升!

夕小瑶科技说 原创 作者 | 谢年年 论文的审稿模式想必大家都不会陌生&#xff0c;一篇论文除了分配多个评审&#xff0c;最后还将由PC综合评估各位审稿人的reviews撰写meta-review。 最近&#xff0c;来自Meta的研究团队将这一模式引进到大模型的对齐训练中。模型同时扮演 执…

poker (GuanDan)

poker &#xff08;GuanDan&#xff09; 掼蛋 基础比大小规则: ①单牌 2最小与以往不太一样&#xff08;2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A < Joker&#xff09; 如果本级打9&#xff0c;那么9就比A大&#xff0c;…

安装Anaconda(过程)

Anaconda是一个开源的Python发行版本&#xff0c;用来管理Python相关的包&#xff0c;安装Anaconda可以很方便的切换不同的环境&#xff0c;使用不同的深度学习框架开发项目&#xff0c;本文将详细介绍Anaconda的安装。 一、安装 1、安装方式 官网&#xff1a;“https://www.…

JVM - GC垃圾回收

文章目录 目录 文章目录 1. 自动垃圾回收 1.1 垃圾回收区域 2. 方法区回收 3. 堆回收 3.1 对象已死&#xff1f; 3.1.1 引用计数算法 3.1.2 可达性分析算法 3.1.3 再谈引用 强引用 软引用 弱引用 虚引用 3.2 垃圾收集算法 3.2.1 分代收集理论 3.2.2 垃圾回收算…

FlinkCDC 3.2.0 新增优点 Pattern Replacement in routing rules

新增优点&#xff1a;Pattern Replacement in routing rules flinkcdc 3.2.0版本相较于3.1.0版本&#xff0c;避免了多表多sink多次写 route 路由的麻烦&#xff0c;类似于统一前后缀的形式多表多sink&#xff0c;通过<>正则&#xff0c;大大减少了书写 官网&#xff1…

初始Linux 和 各种常见指令

目录 Linux背景 1. 发展史 Linux发展历史 1.历史 2. 开源 Linux下基本指令 01. ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令&#xff08;重要&#xff09;&#xff1a; 06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a; …

【Vue3】自动化路由配置:Vue3与unplugin-vue-router的完美结合

引言 在Vue3项目中&#xff0c;路由管理是构建复杂应用不可或缺的一部分。传统上&#xff0c;手动编写路由配置既繁琐又容易出错。本文将介绍如何利用unplugin-vue-router插件&#xff0c;实现Vue3项目的自动化路由配置&#xff0c;从而提升开发效率和准确性。 unplugin-vue-…

基于SpringBoot+Vue+MySQL的考研互助交流平台

系统展示 用户前台界面 管理员后台界面 系统背景 本文设计并实现了一个基于SpringBoot、Vue.js和MySQL的考研互助交流平台。该平台旨在为广大考研学子提供一个集资源共享、学习交流、经验分享、心理辅导等功能于一体的综合性在线社区。通过SpringBoot构建高效稳定的后端服务&am…

轻松实现游戏串流,内网穿透

一、部署Gemini Gemini使用教程 二、部署Moonlight 过程大概说一下&#xff0c;网上有太多太多moonlight的东西了 需要运行游戏的机器上安装GFE&#xff08;GeForce Experience&#xff09;&#xff0c;登录并开启GAMESTREAM&#xff08;游戏串流&#xff09;功能 注&…

网络安全 L2 Introduction to Cryptography 密码学

Definitions 1. crypto - hidden/secret grafia - writing 2. “the science and study of secret writing” 3. Cryptography is the science of protecting data, which provides means of converting data into unreadable form, so that 1. the data cannot be ac…

vue + Element UI table动态合并单元格

一、功能需求 1、根据名称相同的合并工作阶段和主要任务合并这两列&#xff0c;但主要任务内容一样&#xff0c;但要考虑主要任务一样&#xff0c;但工作阶段不一样的情况。&#xff08;枞向合并&#xff09; 2、落实情况里的定量内容和定性内容值一样则合并。&#xff08;横向…

9.11 QT ( Day 4)

一、作业 1.Widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器类 #include <QTime> #include <QtTextToSpeech> //文本转语音类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcl…

杨氏矩阵中查找某个数字是否存在(不能使用遍历)

杨氏矩阵&#xff1a; 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的 如图所示&#xff1a; i为行&#xff0c;j为列 如果要找9&#xff0c;先从arr【0】【2】处开始找&#xff0c;3<9,i,排除第一行&#xff0c;6<9,i,排除第…

上海亚商投顾:沪指探底回升 华为产业链午后爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日探底回升&#xff0c;深成指、创业板指盘中跌逾1%&#xff0c;午后集体拉升翻红。华为产业链午后走强…

B-树底层原理

一、B-树介绍 定义&#xff1a; B-树&#xff08;B-Tree&#xff09;是一种自平衡的树形数据结构&#xff0c;广泛应用于数据库和操作系统中。它的设计目标是减少搜索、顺序访问、插入和删除操作中比较次数和移动次数&#xff0c;特别适合于磁盘中数据的存储和检索。 性质&a…

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1&#xff08;高级消息队列协议&#xff09;是一种网络协议&#xff0c;它允许遵从该协议的客户端&#xff08;Publisher或者Consumer&#xff09;应用程序与遵从该协议的消息中间件代理&#xff08;Broker&#xff0c;如RabbitMQ&#xff09;…

欺诈文本分类检测(十四):GPTQ量化模型

1. 引言 量化的本质&#xff1a;通过将模型参数从高精度&#xff08;例如32位&#xff09;降低到低精度&#xff08;例如8位&#xff09;&#xff0c;来缩小模型体积。 本文将采用一种训练后量化方法GPTQ&#xff0c;对前文已经训练并合并过的模型文件进行量化&#xff0c;通…

【电子通识】规格书上的%FS和%RD具体指什么?

在仪器仪表类的手册上&#xff0c;常见的精度表达规格显示方式&#xff1a;%FS 和%RD 究竟如何解读呢&#xff1f; 术语解说 %RD(Reading)&#xff1a;用于表示对比显示值(读值)存在多少(%)的误差 %FS(Full Scale)&#xff1a;用于表示对比全量程存在多少(%)的误差 %SP(Set Poi…

基于ssm+vue+uniapp的电影交流平台小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…