Kamailio-超强dispatcher负载均衡模块

news2024/9/20 3:15:32

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 destinations
	route(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
#!endif

memdbg=5
memlog=5

log_facility=LOG_LOCAL0

fork=yes
children=4

/* comment the next line to enable TCP */
disable_tcp=yes

/* uncomment the next line to disable the auto discovery of local aliases
   based 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 to
   bind on a specific interface/port/proto (default bind on all available) */
# listen=udp:127.0.0.1:5060

sip_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 logic

request_route {

	# per request initial checks
	route(REQINIT);

	# CANCEL processing
	if (is_method("CANCEL")) {
		if (t_check_trans()) {
			route(RELAY);
		}
		exit;
	}

	# handle retransmissions
	if (!is_method("ACK")) {
		if(t_precheck_trans()) {
			t_check_trans();
			exit;
		}
		t_check_trans();
	}

	# handle requests within SIP dialogs
	route(WITHINDLG);

	### only initial requests (no To tag)

	# record routing for dialog forming requests (in case they are routed)
	# - remove preloaded route headers
	remove_hf("Route");
	if (is_method("INVITE|SUBSCRIBE")) {
		record_route();
	}

	# account only INVITEs
	if (is_method("INVITE")) {
		setflag(FLT_ACC); # do accounting
	}

	# handle presence related requests
	route(PRESENCE);

	# handle registrations
	route(REGISTRAR);

	if ($rU==$null) {
		# request with no Username in RURI
		sl_send_reply("484","Address Incomplete");
		exit;
	}

	# dispatch destinations
	route(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-routing
	if (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 requests
		route(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 server
			t_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 timeout
	if (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:5060
	FLAGS: AP
	PRIORITY: 12
	ATTRS: {
		BODY: rweight=50;weight=50;cc=1 # configuration values
		DUID:
		MAXLOAD: 0
		WEIGHT: 50
		RWEIGHT: 50
		SOCKET:
		SOCKNAME:
		OBPROXY:
	}
	LATENCY: {
		AVG: 20.104000
		STD: 1.273000
		# estimated congestion is currently 25ms = 45ms(EST) -20ms(AVG)
		EST: 45.005000
		MAX: 132
		TIMEOUT: 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 xyz

kamcmd dispatcher.list
...
DEST: {
        URI: sip:192.168.0.1:5060
        FLAGS: AP
        PRIORITY: 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.coloradmin.cn/o/2128422.html

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

相关文章

掌握ZooKeeper的二阶段提交及其优缺点

1. ZooKeeper的协议 1.1 ZAB协议 要深入学习ZooKeeper前&#xff0c;胡广认为我们要先学习ZooKeeper的核心理念&#xff0c;所有的ZooKeeper行为都是围绕这个核心来进行的。说了那么多&#xff0c;它就是——ZAB协议。 ZAB协议英文全称叫ZooKeeper Atomic Broadcast&#xf…

TIDB的整体架构和主要功能

1. 基础架构 PD &#xff1a;负责集群管理和调度。TiDB Server &#xff1a;负责 SQL 查询处理。TiKV/TiFlash&#xff1a;负责数据存储和事务处理。 1.1 PD (Placement Driver) Server 1.1.1 基础介绍 整个 TiDB 集群的元信息管理模块&#xff0c;负责存储每个 TiKV 节点实时…

让我们聊一下小团队也可以用的敏捷开发

使用敏捷开发的团队往往需要寻找一个更佳的平衡点&#xff1a; 较少的团队成员&#xff1a;通常更容易沟通和协作&#xff0c;减少了协调成本。小团队&#xff08;如 5 到 9 人&#xff09;能够更灵活地适应变化&#xff0c;且管理和决策过程较为高效。 较多的团队成员&#x…

喜报 | 知从科技荣获 “AutoSec 安全之星 - 优秀汽车软件供应链安全方案奖”

近日&#xff0c;「AutoSec 2024第八届中国汽车网络安全周暨第五届智能汽车数据安全展」在上海盛大举行。本届大会由谈思实验室和谈思汽车主办、上海市车联网协会联合主办&#xff0c;以汽车“网络数据安全、软件安全、功能安全”为主题&#xff0c;设置了“31X”模式&#xff…

Docker学习笔记-部署MySQL-命令解读

部署MySQL 先停掉虚拟机中的MySQL&#xff0c;确保你的虚拟机已经安装Docker&#xff0c;且网络开通的情况下&#xff0c;在MobaXterm中执行下面命令即可安装MySQL。 docker run -d \--name mysql \-p 3306:3306 \-e TZAsia/Shanghai \-e MYSQL_ROOT_PASSWORD123456 \mysql …

c++修炼之路之AVL树与红黑树

目录 一&#xff1a;AVL树 1.AVL树的概念 2.AVL树插入数据后平衡因子及更新的情况 3.AVL树节点的定义 4.AVL树的插入及旋转 二&#xff1a;红黑树 1.红黑树的概念及性质 2.红黑树节点的定义 3.红黑树的插入操作情况 4.红黑树与AVL树的比较 接下来的日子会顺顺利利…

多方位实测运动耳机排行榜前十名,助你选出靠谱的运动耳机!

非常荣幸能与各位运动爱好者共聚本次的骨传导耳机知识分享&#xff01;作为一名深耕运动科技领域多年的专家&#xff0c;今天将主要跟大家分析一下市面上比较热门的骨传导耳机。骨传导耳机作为当下市面上非常新颖且有创意的耳机种类&#xff0c;相信有很多用户都想入手一款&…

流片为啥那么重要?

很多微电子与集成电路专业的学生、初入IC职场的工程师&#xff0c;以及电子/机械大类专业的同学&#xff0c;在进入芯片设计行业时&#xff0c;都或多或少听说了参与流片的重要性。 但是却并不是很清楚——流片到底有多重要&#xff1f;流片为什么重要&#xff1f; 研0的同学…

从基础到进阶:利用EasyCVR安防视频汇聚平台实现高效视频监控系统的五步走

随着科技的飞速发展&#xff0c;视频监控技术在社会安全、企业管理、智慧城市构建等领域扮演着越来越重要的角色。一个高效智能的视频监控管理系统不仅能够提升监控效率&#xff0c;还能在预防犯罪、事故预警、数据分析等方面发挥巨大作用。 一、需求分析 在设计视频监控管理…

存在分包的微信小程序解包反编译还原(含报错处理与代码修复)

01前言 本文主要对微信小程序的解包步骤进行复现梳理&#xff0c;网上虽然已有明确详细的文章&#xff0c;但是实际复现过程中程序报错的情况并不少见。对此情况进行了梳理以及对相关工具的代码、调用方式等进行了优化修复。 本文内容&#xff1a; 常规微信小程序逆向解析的…

el-input设置后缀显示单位并阻止滚轮微调

项目中收集form表单信息时&#xff0c;有时会需要在el-input后面显示单位&#xff0c;效果如图&#xff1a; 当然&#xff0c;我们可以直接在输入框后面加上单位&#xff0c;但直接给输入框上加单位不管是视图上还是用户体验上看起来都要好一点 element-plus / element-ui给我…

MySQL数据库 — Explain命令

EXPLAIN 命令在 MySQL 查询优化中发挥了重要作用。通过 EXPLAIN 的输出&#xff0c;可以获取有关查询执行计划的详细信息&#xff0c;从而有助于优化和调试查询。不过&#xff0c;它也有一定的局限性。 使用Explain EXPLAIN 语句通过在查询前加上 EXPLAIN 关键字来展示查询的…

正则表达式三板斧

推荐练习网站&#xff1a;https://regex101.com/ 解释一下: 1、最常用的就是[]&#xff0c;表示匹配任意字符&#xff0c;[]中所有的变量只需要输入一次&#xff08;比如搜索三个点…&#xff0c;只需要输入[.]即可&#xff09; 2、*表示>0次&#xff0c;表示>1次&#x…

计算机毕业设计选题推荐-推拿知识互动平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

大白话!解析大模型原理!

LLM的工作原理对大多数人来说是个谜。虽然它们本质上在于“预测下一个词”&#xff0c;并需要大量文本进行训练&#xff0c;但具体细节往往令人困惑。原因在于这些系统独特的开发方式&#xff1a;**基于数十亿词汇训练的神经网络&#xff0c;不同于传统的人类编写的软件。**尽管…

SpringCache源码解析(三)——@EnableCaching

一、源码阅读 让我们进行源码阅读把。 1.1 阅读源码基础&#xff1a; Import(xxx.class)里的类可以有两种类&#xff1a; ImportSelector接口的实现类&#xff1b;ImportBeanDefinitionRegistrar接口的实现类&#xff1b; 两种接口简介&#xff1a; ImportSelector接口&am…

如何在算家云搭建Open-Sora1.0

一、模型介绍 2024 年 3 月 18 日&#xff0c;Colossal-AI 团队发布了 Open-Sora 1.0 项目&#xff0c;该项目是一个全面开源的视频生成模型项目&#xff0c;项目旨在高效制作高质量视频&#xff0c;并使所有人都能使用其模型、工具和内容。 模型架构 &#xff1a; Open-Sor…

ubuntu20.04 编译vtk 9.3.1+vtkDicom+GDCM 3.0.24

1 下载vtk源码 链接地址如下&#xff1a; Download | VTK 使用cmake-gui编译&#xff08;如何安装使用&#xff0c;查看前两篇文章&#xff09;&#xff0c;运行命令&#xff1a; cmake-gui 如下图所示&#xff0c;选择源码目录和build目录&#xff1a; 勾选 BUILD_SHARED…

基于SpringBoot+Vue+MySQL的志愿服务管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着社会对志愿服务需求的日益增长&#xff0c;传统的志愿服务管理方式已难以满足高效、透明、精准的管理需求。为提升志愿服务组织的运营效率&#xff0c;优化资源配置&#xff0c;增强志愿者参与度和满意度&#xff0c;开发基…

项目启动 | 盘古信息携手晶捷电子,开启数字化生产管理新纪元

随着智能制造技术的不断成熟与普及&#xff0c;一个全新的制造业时代已经到来&#xff0c;智能制造已成为推动全球制造业转型升级的重要引擎。在日新月异的市场环境中&#xff0c;传统制造业更需加快转型升级的步伐&#xff0c;以智能化、精细化的生产模式&#xff0c;实现生产…