Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because: - sngrep does capture all the SIP packets and shows the flows - though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite - picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCraft https://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Blog https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg:
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases
- based on reverse DNS on IPs (default on) */
# auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.com"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.id = value 'desc' description * Access: $sel(cfg_get.group.id) or @cfg_get.group.id */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) {
file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n");
file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; }
$xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply
sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
What are your http query times like? You're using http_client, which functions in a blocking manner: The http request is sent, and that thread does nothing else until a response is received and then it continues. If your request time is even moderately high try http_async_client.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Sergio Charrua via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 9:08 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Sergio Charrua sergio.charrua@voip.pt Subject: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because: - sngrep does capture all the SIP packets and shows the flows - though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite - picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCrafthttps://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Bloghttps://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060http://10.242.17.125:5060/ 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060http://10.242.17.146:5060/ 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg: ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases * based on reverse DNS on IPs (default on) */ # auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.comhttp://sip.mydomain.com/"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.idhttp://group.id/ = value 'desc' description * Access: $sel(cfg_get.group.idhttp://cfg_get.group.id/) or @cfg_get.group.idhttp://cfg_get.group.id/ */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; }
$xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
On Dec 19, 2024, at 10:49 AM, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
What are your http query times like? You're using http_client, which functions in a blocking manner: The http request is sent, and that thread does nothing else until a response is received and then it continues. If your request time is even moderately high try http_async_client.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com mailto:bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768 https://www.sip.us/ https://www.siptrunk.com/ https://www.flowroute.com/
From: Sergio Charrua via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> Sent: Thursday, December 19, 2024 9:08 AM To: Kamailio (SER) - Users Mailing List <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> Cc: Sergio Charrua <sergio.charrua@voip.pt mailto:sergio.charrua@voip.pt> Subject: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because:
- sngrep does capture all the SIP packets and shows the flows
- though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite
- picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCraft https://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Blog https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060 http://10.242.17.125:5060/ 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060 http://10.242.17.146:5060/ 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg: ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases
- based on reverse DNS on IPs (default on) */
# auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.com http://sip.mydomain.com/"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface
- see the documentation of 'cfg_rpc' module.
- Format: group.id http://group.id/ = value 'desc' description
- Access: $sel(cfg_get.group.id http://cfg_get.group.id/) or @cfg_get.group.id http://cfg_get.group.id/ */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; } $xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
The http_async_client module is not the async module. They work differently. I have here a repo that illustrates the advantage of http_async_client specifically for addressing latency in getting a response from an http server. If you doubt me, you can feel free to pull the repo and run it for yourself:
https://github.com/whosgonna/kamailio_http_async
One of the key differences between http_async_client and async is that this doesn't move the long running request to a different process. It sends the http request, and then doesn't resume in a new process until a response is recieved. You may need to increase shared memory as a trade off, but the general blocking as it relates to http response time should be removed.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alexis Fidalgo alzrck@gmail.com Sent: Thursday, December 19, 2024 10:19 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Ben Kaufman bkaufman@bcmone.com Subject: Re: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
On Dec 19, 2024, at 10:49 AM, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
What are your http query times like? You're using http_client, which functions in a blocking manner: The http request is sent, and that thread does nothing else until a response is received and then it continues. If your request time is even moderately high try http_async_client.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.commailto:bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768 [img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Sergio Charrua via sr-users <sr-users@lists.kamailio.orgmailto:sr-users@lists.kamailio.org> Sent: Thursday, December 19, 2024 9:08 AM To: Kamailio (SER) - Users Mailing List <sr-users@lists.kamailio.orgmailto:sr-users@lists.kamailio.org> Cc: Sergio Charrua <sergio.charrua@voip.ptmailto:sergio.charrua@voip.pt> Subject: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because: - sngrep does capture all the SIP packets and shows the flows - though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite - picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCrafthttps://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Bloghttps://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060http://10.242.17.125:5060/ 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060http://10.242.17.146:5060/ 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg: ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases * based on reverse DNS on IPs (default on) */ # auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.comhttp://sip.mydomain.com/"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.idhttp://group.id/ = value 'desc' description * Access: $sel(cfg_get.group.idhttp://cfg_get.group.id/) or @cfg_get.group.idhttp://cfg_get.group.id/ */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; }
$xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-...
TL;DR don't do HTTP queries from Kamailio. Just don't.
-- Alex
Alex,
In this case, the "moving food around on the plate" is moving the process blocking of the http request (which is just wait time) to increased memory usage by storing the request in memory. The number of message able to be handled over a sustained period increases (full stop). Of course there' still an upper bound based on memory and that should be considered. It's not a "limitless fix", but buy creating a queue for the requests in memory the upper bound gets increased.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 10:49 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alexis Fidalgo alzrck@gmail.com; Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fblog.evari...https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/
TL;DR don't do HTTP queries from Kamailio. Just don't.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 12:04 pm, Ben Kaufman bkaufman@bcmone.com wrote:
In this case, the "moving food around on the plate" is moving the process blocking of the http request (which is just wait time) to increased memory usage by storing the request in memory. The number of message able to be handled over a sustained period increases (full stop). Of course there' still an upper bound based on memory and that should be considered. It's not a "limitless fix", but buy creating a queue for the requests in memory the upper bound gets increased.
I think we've had this polemic before. Yes, the upper bound is increased in some non-zero amount, but the returns to actual call throughput per se can be marginal vs just increasing core children drastically, just depending on the exact parameters of the situation. Increasing core children invites contention problems beyond a certain point, and the same is true of background async workers.
There are better and worse ways of dealing with the latter; individuated mqueues are a good solution. core_hash() over Call-ID helps with pseudo-random distribution over independent pipelines to background workers, versus having them share queue lock.
The best use-case for background async workers is for stuff that isn't in the critical path of call processing and is highly deferrable, such as call accounting. Otherwise, the results aren't that great in the end, if throughput is your top concern. Alexis Fidalgo said it:
"[...] still 'hiding' the problem. Improves? Yes. Fixes? Not at all."
-- Alex
The existence and popularity of HTTP client modules (of both flavours) suggests that this is a contentious topic, but HTTP queries can serve lots of purposes.
Based on my experience, my position within that discourse is to not do HTTP from Kamailio at all, at least not in high-volume environments where the HTTP query is also part of the call processing. That is the most honest and best advice I can give to anyone concerned specifically with maximising throughput.
Kamailio is good at SIP, though. You should use that.
-- Alex
On Dec 19, 2024, at 12:24 pm, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 19, 2024, at 12:04 pm, Ben Kaufman bkaufman@bcmone.com wrote:
In this case, the "moving food around on the plate" is moving the process blocking of the http request (which is just wait time) to increased memory usage by storing the request in memory. The number of message able to be handled over a sustained period increases (full stop). Of course there' still an upper bound based on memory and that should be considered. It's not a "limitless fix", but buy creating a queue for the requests in memory the upper bound gets increased.
I think we've had this polemic before. Yes, the upper bound is increased in some non-zero amount, but the returns to actual call throughput per se can be marginal vs just increasing core children drastically, just depending on the exact parameters of the situation. Increasing core children invites contention problems beyond a certain point, and the same is true of background async workers.
There are better and worse ways of dealing with the latter; individuated mqueues are a good solution. core_hash() over Call-ID helps with pseudo-random distribution over independent pipelines to background workers, versus having them share queue lock.
The best use-case for background async workers is for stuff that isn't in the critical path of call processing and is highly deferrable, such as call accounting. Otherwise, the results aren't that great in the end, if throughput is your top concern. Alexis Fidalgo said it:
"[...] still 'hiding' the problem. Improves? Yes. Fixes? Not at all."
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
I think there are many sane reasons to not insert an http request (or even worse multiple http requests) inline on a Kamailio server who's primary function is routing SIP requests. If someone has a large number of http requests to make, then I would strongly advocate for creating a dedicated SIP redirect server to handle those http requests.
But on that dedicated SIP redirect server I wouldn't hesitate to use Kamailio, and would absolutely use http_async_client over http_client. In the context of the original post in this thread, it appears that the poster was already building a dedicated redirect server:
using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE
The responses I see read like "don't use Kamailio, it can't do this", and to THAT I strongly disagree.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 11:34 AM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
The existence and popularity of HTTP client modules (of both flavours) suggests that this is a contentious topic, but HTTP queries can serve lots of purposes.
Based on my experience, my position within that discourse is to not do HTTP from Kamailio at all, at least not in high-volume environments where the HTTP query is also part of the call processing. That is the most honest and best advice I can give to anyone concerned specifically with maximising throughput.
Kamailio is good at SIP, though. You should use that.
-- Alex
On Dec 19, 2024, at 12:24 pm, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 19, 2024, at 12:04 pm, Ben Kaufman bkaufman@bcmone.com wrote:
In this case, the "moving food around on the plate" is moving the process blocking of the http request (which is just wait time) to increased memory usage by storing the request in memory. The number of message able to be handled over a sustained period increases (full stop). Of course there' still an upper bound based on memory and that should be considered. It's not a "limitless fix", but buy creating a queue for the requests in memory the upper bound gets increased.
I think we've had this polemic before. Yes, the upper bound is increased in some non-zero amount, but the returns to actual call throughput per se can be marginal vs just increasing core children drastically, just depending on the exact parameters of the situation. Increasing core children invites contention problems beyond a certain point, and the same is true of background async workers.
There are better and worse ways of dealing with the latter; individuated mqueues are a good solution. core_hash() over Call-ID helps with pseudo-random distribution over independent pipelines to background workers, versus having them share queue lock.
The best use-case for background async workers is for stuff that isn't in the critical path of call processing and is highly deferrable, such as call accounting. Otherwise, the results aren't that great in the end, if throughput is your top concern. Alexis Fidalgo said it:
"[...] still 'hiding' the problem. Improves? Yes. Fixes? Not at all."
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 12:50 pm, Ben Kaufman bkaufman@bcmone.com wrote:
If someone has a large number of http requests to make, then I would strongly advocate for creating a dedicated SIP redirect server to handle those http requests.
I would strongly agree that this is preferable. If HTTP is a must, as the redirect server can be tuned for that kind of workload much more effectively, taking into account that every query is a comparatively monstrous lift.
And in this context, http_async_client will greatly out perform http_client. This is, as far as I can tell, the basis of the OP.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 12:02 PM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 12:50 pm, Ben Kaufman bkaufman@bcmone.com wrote:
If someone has a large number of http requests to make, then I would strongly advocate for creating a dedicated SIP redirect server to handle those http requests.
I would strongly agree that this is preferable. If HTTP is a must, as the redirect server can be tuned for that kind of workload much more effectively, taking into account that every query is a comparatively monstrous lift.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
You're still conflating `http_async_client` with async. I'm not arguing the former as an absolute panacea, but the behavior you describe is consistent with how async works, not http_async_client.
Async will move the message handling to another process immediately. If it sends an http request using http_client, then that new process will be blocked. This is very useful when a small percentage of requests will require doing something that takes a long time.
Unless I'm wrong (and testing shows this to be the case), http_async_client will send an http request, store the request to memory, and release the process. As long as there is no http reply, there is no blocked process. Only when a reply is received is the SIP request processing resumed.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 11:24 AM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 12:04 pm, Ben Kaufman bkaufman@bcmone.com wrote:
In this case, the "moving food around on the plate" is moving the process blocking of the http request (which is just wait time) to increased memory usage by storing the request in memory. The number of message able to be handled over a sustained period increases (full stop). Of course there' still an upper bound based on memory and that should be considered. It's not a "limitless fix", but buy creating a queue for the requests in memory the upper bound gets increased.
I think we've had this polemic before. Yes, the upper bound is increased in some non-zero amount, but the returns to actual call throughput per se can be marginal vs just increasing core children drastically, just depending on the exact parameters of the situation. Increasing core children invites contention problems beyond a certain point, and the same is true of background async workers.
There are better and worse ways of dealing with the latter; individuated mqueues are a good solution. core_hash() over Call-ID helps with pseudo-random distribution over independent pipelines to background workers, versus having them share queue lock.
The best use-case for background async workers is for stuff that isn't in the critical path of call processing and is highly deferrable, such as call accounting. Otherwise, the results aren't that great in the end, if throughput is your top concern. Alexis Fidalgo said it:
"[...] still 'hiding' the problem. Improves? Yes. Fixes? Not at all."
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 12:41 pm, Ben Kaufman bkaufman@bcmone.com wrote:
Unless I'm wrong (and testing shows this to be the case), http_async_client will send an http request, store the request to memory, and release the process. As long as there is no http reply, there is no blocked process. Only when a reply is received is the SIP request processing resumed.
The query is initiated by a delegate as well:
https://github.com/kamailio/kamailio/blob/master/src/modules/http_async_clie...
But you are correct that there's a libevent loop that prevents these from blocking while waiting for a response.
These questions of mechanics don't change the argument about the limited benefit of async processing, IMHO. The question is more fundamental and isn't really related to Kamailio per se. There's only so much work a system can do, and HTTP is intensive and slow. Run the queries here, run them there, there are better and worse ways to do it, but this doesn't change the broader picture.
Think of it this way: you get 2000 CPS and a modestly-resourced Kamailio system. You build your call processing architecture with http_async_client. I build mine without doing HTTP queries at all. Then, we measure units of throughput per cloud resource spend. Who do you think wins?
-- Alex
I'm not arguing that Kamailio's http processing is equal or better than its SIP processing. There's a variety of reasons why it's not. I'm arguing that http requests can be done sanely, and you're saying they shouldn't be done at all.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 11:54 AM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 12:41 pm, Ben Kaufman bkaufman@bcmone.com wrote:
Unless I'm wrong (and testing shows this to be the case), http_async_client will send an http request, store the request to memory, and release the process. As long as there is no http reply, there is no blocked process. Only when a reply is received is the SIP request processing resumed.
The query is initiated by a delegate as well:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com...https://github.com/kamailio/kamailio/blob/master/src/modules/http_async_client/async_http.c#L631
But you are correct that there's a libevent loop that prevents these from blocking while waiting for a response.
These questions of mechanics don't change the argument about the limited benefit of async processing, IMHO. The question is more fundamental and isn't really related to Kamailio per se. There's only so much work a system can do, and HTTP is intensive and slow. Run the queries here, run them there, there are better and worse ways to do it, but this doesn't change the broader picture.
Think of it this way: you get 2000 CPS and a modestly-resourced Kamailio system. You build your call processing architecture with http_async_client. I build mine without doing HTTP queries at all. Then, we measure units of throughput per cloud resource spend. Who do you think wins?
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 1:08 pm, Ben Kaufman bkaufman@bcmone.com wrote:
I'm arguing that http requests can be done sanely, and you're saying they shouldn't be done at all.
Not if you want the most performance, no.
Alex,
I read the OP's requirements like this. They want to implement a redirect server that will:
* Receive a SIP INVITE * Make a single http request that has a RTT of 200ms * Copy a header from the HTTP reply to a SIP 300 reply * Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio on a 4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 12:17 PM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 1:08 pm, Ben Kaufman bkaufman@bcmone.com wrote:
I'm arguing that http requests can be done sanely, and you're saying they shouldn't be done at all.
Not if you want the most performance, no.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 1:54 pm, Ben Kaufman bkaufman@bcmone.com wrote:
Alex,
I read the OP's requirements like this. They want to implement a redirect server that will: • Receive a SIP INVITE • Make a single http request that has a RTT of 200ms • Copy a header from the HTTP reply to a SIP 300 reply • Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio on a 4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
I have no idea. That's an empirical question. In my experience, that's an ambitious ask given the stochastic variation in HTTP API response time (i.e. it's not exactly and literally 200 ms), but it's probably possible with enough processes.
My only argument--from first principles-- is that you'll get a lot more throughput if you ditch HTTP, and I joined the conversation at the point at which Alexis Fidalgo expressed that async isn't a cure-all. I wanted to sign onto this sentiment.
-- Alex
BTW: Not sure what the state of HTTP/2 support is in http_async_client.
If existent, and the server is HTTP/2, you can make multiple sequential and parallel requests over the same connection. Given Kamailio's concurrency and isolation model, this would probably mean sequential requests over multiple persistent connections attached to each process.
While HTTP backends are still characteristically sluggish from the perspective of the tight timing tolerances of traditional real-time communications, this would be a real game-changer and probably vacate much of what I'm saying, and the basis of my opposition to HTTP as an integration path out of Kamailio.
HTTP/1.1 is for these kinds of systems, though. If high throughput is your goal, I'd go a different route. Whatever you do to squeeze a few hundred requests/sec out of it will most likely amount to a Pyrrhic victory.
-- Alex
On Dec 19, 2024, at 2:06 pm, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 19, 2024, at 1:54 pm, Ben Kaufman bkaufman@bcmone.com wrote:
Alex,
I read the OP's requirements like this. They want to implement a redirect server that will: • Receive a SIP INVITE • Make a single http request that has a RTT of 200ms • Copy a header from the HTTP reply to a SIP 300 reply • Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio on a 4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
I have no idea. That's an empirical question. In my experience, that's an ambitious ask given the stochastic variation in HTTP API response time (i.e. it's not exactly and literally 200 ms), but it's probably possible with enough processes.
My only argument--from first principles-- is that you'll get a lot more throughput if you ditch HTTP, and I joined the conversation at the point at which Alexis Fidalgo expressed that async isn't a cure-all. I wanted to sign onto this sentiment.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Hello,
according to this discussion: https://kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.org/th...
and the linked PR in it, HTTP/2 should be available. Its probably something to tested, as certain features (e.g. HTTP/2 multiplexing) are deactivated in the http_async_client for example.
Cheers,
Henning
Hi all!
Well, i wasn't expecting to generate such debate on this matter! :) Thanks to all for the provided feedback.
The async_http_client seems an interesting test to do, even though it doesn't solve the issue, "per se". I will try that tomorrow, 1st thing in the morning.
@Ben Kaufman bkaufman@bcmone.com The math exercise you explained makes sense. I was already doing some math and very close to the same results! Thanks mate!
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Thu, Dec 19, 2024 at 8:11 PM Henning Westerholt via sr-users < sr-users@lists.kamailio.org> wrote:
Hello,
according to this discussion: https://kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.org/th...
and the linked PR in it, HTTP/2 should be available. Its probably something to tested, as certain features (e.g. HTTP/2 multiplexing) are deactivated in the http_async_client for example.
Cheers,
Henning
-- Henning Westerholt – https://skalatan.de/blog/ Kamailio services – https://gilawa.com
-----Original Message----- From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Donnerstag, 19. Dezember 2024 20:16 To: sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
BTW: Not sure what the state of HTTP/2 support is in http_async_client.
If existent, and the server is HTTP/2, you can make multiple sequential
and
parallel requests over the same connection. Given Kamailio's concurrency
and
isolation model, this would probably mean sequential requests over
multiple
persistent connections attached to each process.
While HTTP backends are still characteristically sluggish from the
perspective of
the tight timing tolerances of traditional real-time communications,
this would
be a real game-changer and probably vacate much of what I'm saying, and
the
basis of my opposition to HTTP as an integration path out of Kamailio.
HTTP/1.1 is for these kinds of systems, though. If high throughput is
your
goal, I'd go a different route. Whatever you do to squeeze a few hundred requests/sec out of it will most likely amount to a Pyrrhic victory.
-- Alex
On Dec 19, 2024, at 2:06 pm, Alex Balashov abalashov@evaristesys.com
wrote:
On Dec 19, 2024, at 1:54 pm, Ben Kaufman bkaufman@bcmone.com
wrote:
Alex,
I read the OP's requirements like this. They want to implement a
redirect
server that will:
• Receive a SIP INVITE • Make a single http request that has a RTT of 200ms • Copy a header from the HTTP reply to a SIP 300 reply • Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio
on a
4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
I have no idea. That's an empirical question. In my experience, that's
an
ambitious ask given the stochastic variation in HTTP API response time
(i.e. it's
not exactly and literally 200 ms), but it's probably possible with enough processes.
My only argument--from first principles-- is that you'll get a lot more
throughput if you ditch HTTP, and I joined the conversation at the point
at
which Alexis Fidalgo expressed that async isn't a cure-all. I wanted to
sign onto
this sentiment.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr- users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to
the
sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Oh, that's exciting, and may breathe fresh life into the relatively high-performing HTTP routing API idea.
On Dec 19, 2024, at 2:51 pm, Henning Westerholt hw@gilawa.com wrote:
Hello,
according to this discussion: https://kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.org/th...
and the linked PR in it, HTTP/2 should be available. Its probably something to tested, as certain features (e.g. HTTP/2 multiplexing) are deactivated in the http_async_client for example.
Cheers,
Henning
-- Henning Westerholt – https://skalatan.de/blog/ Kamailio services – https://gilawa.com
-----Original Message----- From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Donnerstag, 19. Dezember 2024 20:16 To: sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
BTW: Not sure what the state of HTTP/2 support is in http_async_client.
If existent, and the server is HTTP/2, you can make multiple sequential and parallel requests over the same connection. Given Kamailio's concurrency and isolation model, this would probably mean sequential requests over multiple persistent connections attached to each process.
While HTTP backends are still characteristically sluggish from the perspective of the tight timing tolerances of traditional real-time communications, this would be a real game-changer and probably vacate much of what I'm saying, and the basis of my opposition to HTTP as an integration path out of Kamailio.
HTTP/1.1 is for these kinds of systems, though. If high throughput is your goal, I'd go a different route. Whatever you do to squeeze a few hundred requests/sec out of it will most likely amount to a Pyrrhic victory.
-- Alex
On Dec 19, 2024, at 2:06 pm, Alex Balashov abalashov@evaristesys.com
wrote:
On Dec 19, 2024, at 1:54 pm, Ben Kaufman bkaufman@bcmone.com
wrote:
Alex,
I read the OP's requirements like this. They want to implement a redirect
server that will:
• Receive a SIP INVITE • Make a single http request that has a RTT of 200ms • Copy a header from the HTTP reply to a SIP 300 reply • Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio on a
4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
I have no idea. That's an empirical question. In my experience, that's an
ambitious ask given the stochastic variation in HTTP API response time (i.e. it's not exactly and literally 200 ms), but it's probably possible with enough processes.
My only argument--from first principles-- is that you'll get a lot more
throughput if you ditch HTTP, and I joined the conversation at the point at which Alexis Fidalgo expressed that async isn't a cure-all. I wanted to sign onto this sentiment.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr- users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Certainly ill test the http/2 in the near future and run tests at least on my lab (luckily I have all the tests I run over and over again trying to improve my current scenario) will be helpful to compare.
On Dec 19, 2024, at 4:55 PM, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
Oh, that's exciting, and may breathe fresh life into the relatively high-performing HTTP routing API idea.
On Dec 19, 2024, at 2:51 pm, Henning Westerholt hw@gilawa.com wrote:
Hello,
according to this discussion: https://kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.org/th...
and the linked PR in it, HTTP/2 should be available. Its probably something to tested, as certain features (e.g. HTTP/2 multiplexing) are deactivated in the http_async_client for example.
Cheers,
Henning
-- Henning Westerholt – https://skalatan.de/blog/ Kamailio services – https://gilawa.com
-----Original Message----- From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Donnerstag, 19. Dezember 2024 20:16 To: sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
BTW: Not sure what the state of HTTP/2 support is in http_async_client.
If existent, and the server is HTTP/2, you can make multiple sequential and parallel requests over the same connection. Given Kamailio's concurrency and isolation model, this would probably mean sequential requests over multiple persistent connections attached to each process.
While HTTP backends are still characteristically sluggish from the perspective of the tight timing tolerances of traditional real-time communications, this would be a real game-changer and probably vacate much of what I'm saying, and the basis of my opposition to HTTP as an integration path out of Kamailio.
HTTP/1.1 is for these kinds of systems, though. If high throughput is your goal, I'd go a different route. Whatever you do to squeeze a few hundred requests/sec out of it will most likely amount to a Pyrrhic victory.
-- Alex
On Dec 19, 2024, at 2:06 pm, Alex Balashov abalashov@evaristesys.com
wrote:
On Dec 19, 2024, at 1:54 pm, Ben Kaufman bkaufman@bcmone.com
wrote:
Alex,
I read the OP's requirements like this. They want to implement a redirect
server that will:
• Receive a SIP INVITE • Make a single http request that has a RTT of 200ms • Copy a header from the HTTP reply to a SIP 300 reply • Handle the ACK for the reply
Is it your opinion this cannot be implemented reliably with Kamailio on a
4vCPUs and 4GB RAM host at a rate of 750 INVITE requests per second?
I have no idea. That's an empirical question. In my experience, that's an
ambitious ask given the stochastic variation in HTTP API response time (i.e. it's not exactly and literally 200 ms), but it's probably possible with enough processes.
My only argument--from first principles-- is that you'll get a lot more
throughput if you ditch HTTP, and I joined the conversation at the point at which Alexis Fidalgo expressed that async isn't a cure-all. I wanted to sign onto this sentiment.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr- users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 5:32 pm, Alexis Fidalgo alzrck@gmail.com wrote:
Certainly ill test the http/2 in the near future and run tests at least on my lab (luckily I have all the tests I run over and over again trying to improve my current scenario) will be helpful to compare.
It should help a lot. The basic reason why HTTP is terrible is that it has to initiate a new connection every time, although a close secondary reason is that the backend services responding to HTTP requests don't tend to be very performant (e.g. Node), since they're not built for the demands of telephony, nor with a view to honouring timing interoperability with a circuit-switched world. Still, addressing the first one should help a lot.
-- Alex
On 19 Dec 2024, at 17:49, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-...
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
But in high volume, I would not _depend_ on any TCP-based external process, regardless if it’s HTTP or databases.
/O
On Dec 19, 2024, at 12:09 pm, Olle E. Johansson oej@edvina.net wrote:
YES! You've just summarised the central thesis about async that I made in this blog post:
https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-...
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
Indeed, and this is what I do when I absolutely must use HTTP. We've built some relatively performant SIP-to-HTTP data query bridges that way.
But when something is a poor fit, it's a poor fit. Kamailio is not a natural habitat for HTTP queries.
-- Alex
Note that despite my support for using http_async_query, I do agree with this point: If queries are more than very occasional, I'd build a purpose driven kamailio instance for handling a SIP to HTTP bridge.
HOWEVER given the original post context and code, it appears that this is their goal.
Given the number of services that are offered -ONLY- over http, the response of "TL;DR don't do HTTP queries from Kamailio. Just don’t," can easily be taken to mean "don't use kamailio, because it can't do HTTP request", which I completely reject. Be smart, understand the intricacies of using it, but don't act like it is a world killer.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 11:14 AM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 19, 2024, at 12:09 pm, Olle E. Johansson oej@edvina.net wrote:
YES! You've just summarised the central thesis about async that I made in this blog post:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fblog.evari...https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
Indeed, and this is what I do when I absolutely must use HTTP. We've built some relatively performant SIP-to-HTTP data query bridges that way.
But when something is a poor fit, it's a poor fit. Kamailio is not a natural habitat for HTTP queries.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
In our case we did it (a lot of backend replicas inside a k8), but still “hiding” the problem. Improves? Yes. Fixes? Not at all
On Dec 19, 2024, at 12:09 PM, Olle E. Johansson oej@edvina.net wrote:
On 19 Dec 2024, at 17:49, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-...
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
But in high volume, I would not _depend_ on any TCP-based external process, regardless if it’s HTTP or databases.
/O
Playing devil's advocate here:
Aren't DB queries generally over TCP? Of course one should OPTIMIZE their DB queries, but in many cases they're necessary in many cases, right?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Olle E. Johansson via sr-users sr-users@lists.kamailio.org Sent: Thursday, December 19, 2024 11:09 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alexis Fidalgo alzrck@gmail.com; Olle E. Johansson oej@edvina.net Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On 19 Dec 2024, at 17:49, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fblog.evari...https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
But in high volume, I would not _depend_ on any TCP-based external process, regardless if it’s HTTP or databases.
/O
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Yes they are, maybe unix sockets too (not tcp) but yes, there’s a point.
On Dec 19, 2024, at 12:29 PM, Ben Kaufman bkaufman@bcmone.com wrote:
Playing devil's advocate here:
Aren't DB queries generally over TCP? Of course one should OPTIMIZE their DB queries, but in many cases they're necessary in many cases, right?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com mailto:bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768 https://www.sip.us/ https://www.siptrunk.com/ https://www.flowroute.com/
From: Olle E. Johansson via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> Sent: Thursday, December 19, 2024 11:09 AM To: Kamailio (SER) - Users Mailing List <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> Cc: Alexis Fidalgo <alzrck@gmail.com mailto:alzrck@gmail.com>; Olle E. Johansson <oej@edvina.net mailto:oej@edvina.net> Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On 19 Dec 2024, at 17:49, Alex Balashov via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote:
On Dec 19, 2024, at 11:19 am, Alexis Fidalgo via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote:
Been there, done that :) async does not help in this scenario.
Killer here, as you mentioned, is wait, async moves the problem to the side only (learned by testing)
:)
YES! You've just summarised the central thesis about async that I made in this blog post:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fblog.evari... https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/
TL;DR don't do HTTP queries from Kamailio. Just don’t
Well, you can set up a cluster of background workers and use the normal http_client. That will speed up the process to read from the network as the network client processes are freed up by you suspending the transaction and continuing in a background process (which you need many of). This will make life better in some cases, but not all.
But in high volume, I would not _depend_ on any TCP-based external process, regardless if it’s HTTP or databases.
/O
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 12:29 pm, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
Aren't DB queries generally over TCP? Of course one should OPTIMIZE their DB queries, but in many cases they're necessary in many cases, right?
They aren't great either, but they run over persistent TCP connections that are proprietary to every worker process, and return much faster than HTTP.
Thanks Ben! replies from HTTP server are below 200ms. Not sure if this is enough to be a bottleneck.... Regarding async_http, knowing that Kamailio is stateless, means (it is my understanding, at least) that the HTTP request needs to be synchronous. But I will give a try to async_http.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Thu, Dec 19, 2024 at 3:49 PM Ben Kaufman bkaufman@bcmone.com wrote:
What are your http query times like? You're using http_client, which functions in a blocking manner: The http request is sent, and that thread does nothing else until a response is received and then it continues. If your request time is even moderately high try http_async_client.
*Kaufman*
*Senior Voice Engineer *
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 *|* SIPTRUNK Client Support: 800.250.6510 *|* Flowroute Client Support: 855.356.9768 [image: img] https://www.sip.us/ [image: img] https://www.siptrunk.com/ *[image: img] https://www.flowroute.com/*
*From:* Sergio Charrua via sr-users sr-users@lists.kamailio.org *Sent:* Thursday, December 19, 2024 9:08 AM *To:* Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org *Cc:* Sergio Charrua sergio.charrua@voip.pt *Subject:* [SR-Users] Kamailio not receiving packets on high CPS
*CAUTION:* This email originated from outside the organization. *Do not click links or open attachments* unless you recognize the sender and know the content is safe.
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because:
- sngrep does capture all the SIP packets and shows the flows
- though the flow shows SIP invite coming from SBC to Kamailio Server,
there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite
- picking a call with reinvites, which after some seconds, SBC cancels, if
I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCraft https://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Blog https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg:
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases
- based on reverse DNS on IPs (default on) */
# auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.com"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface
- see the documentation of 'cfg_rpc' module.
- Format: group.id = value 'desc' description
- Access: $sel(cfg_get.group.id) or @cfg_get.group.id */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) {
file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n");
file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; } $xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable
is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply
sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
In the scope of what you're looking at, 200 ms is an EXTREMELY log time if you're looking to handle 750 requests per second. Looking at this with simple math and discounting everything else that can add small amounts of latency, lets assume that ONLY 200ms of latency occurs. This means that any single process can only handle a maximum of 5 requests per second (this even discounts handling replies). If you have 32 child processes, then the number of requests/second (this assumes that requests are consistent and evenly spaced) becomes:
5 * 32 = 160
Now, this doesn't mean 160 seconds is an absolute point at which problems occur, but it should be the point at which your UDP buffer comes into play. Lets say your Kamailio is idle and you receive 32 requests at the same time (or as close as is physically possible). You'd have all processes tied up for 200ms. 100ms after receiving those 32 requests, you receive a single request. That request should be buffered, but won't get handled for 100ms. Basically the 5*32 calculation is not "the point at which Kamailio starts to fail" but the point at which it "starts to fall behind). Send 161 requests per second and eventually it will fall over. Send more than that and it will fall over faster.
Using http_async_client, you will still have whatever latency exists from the receipt of the SIP request to when the http request is sent, but given your sample code this is minimal - the biggest latency is probably the time to write to your cdr file. Let's suppose the total time then is 4 ms (a relatively arbitrary number here - it's probably less, but this will give us easy math). Once the request is sent to the http server, the request is stored in memory, and the SIP worker process is freed up to handle a new request. When an http response is received, it is handled in a new process. Assuming all you're doing is copying a value from an http reply header and sending a SIP reply header with that response, the time is very mimimal (should be sub millisecond, so lets say 1ms). Your request processing time, then goes down to 5ms per request. Now each process can handle 200 requests per second. If you have 32 children, then you'd expect your maximum total before blocking to be:
200 * 32 = 6400
Of course there are still some other things that can cause latency, etc, so don't take this as a guarantee of handling 6,400 requests/second, but it should be viewed as how using http_async_query rather than just http_async will address blocking caused by a 200ms wait on your web service.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Sergio Charrua sergio.charrua@voip.pt Sent: Thursday, December 19, 2024 10:21 AM To: Ben Kaufman bkaufman@bcmone.com Cc: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Subject: Re: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Thanks Ben! replies from HTTP server are below 200ms. Not sure if this is enough to be a bottleneck.... Regarding async_http, knowing that Kamailio is stateless, means (it is my understanding, at least) that the HTTP request needs to be synchronous. But I will give a try to async_http.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Thu, Dec 19, 2024 at 3:49 PM Ben Kaufman <bkaufman@bcmone.commailto:bkaufman@bcmone.com> wrote: What are your http query times like? You're using http_client, which functions in a blocking manner: The http request is sent, and that thread does nothing else until a response is received and then it continues. If your request time is even moderately high try http_async_client.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.commailto:bkaufman@bcmone.com
SIP.UShttp://sip.us/ Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Sergio Charrua via sr-users <sr-users@lists.kamailio.orgmailto:sr-users@lists.kamailio.org> Sent: Thursday, December 19, 2024 9:08 AM To: Kamailio (SER) - Users Mailing List <sr-users@lists.kamailio.orgmailto:sr-users@lists.kamailio.org> Cc: Sergio Charrua <sergio.charrua@voip.ptmailto:sergio.charrua@voip.pt> Subject: [SR-Users] Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because: - sngrep does capture all the SIP packets and shows the flows - though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite - picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCrafthttps://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Bloghttps://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060http://10.242.17.125:5060/ 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060http://10.242.17.146:5060/ 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg: ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases * based on reverse DNS on IPs (default on) */ # auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.comhttp://sip.mydomain.com/"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.idhttp://group.id/ = value 'desc' description * Access: $sel(cfg_get.group.idhttp://cfg_get.group.id/) or @cfg_get.group.idhttp://cfg_get.group.id/ */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; }
$xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
Sergio, we run a very similar scenario in some places with subtle differences, our http backend is in golang, it’s replicated and load balanced..
We achieve more than 1000 caps with a kind of similar config you’re posting, and also hit the ’no answering threshold’
2 things/questions.
1. How long it takes for the http backend to answer your query? (GET/POST)? 2. How sure you are the backend is able to handle the rate you’re requesting? Did you tried by itself to load stress that?
1. In our case, the backend is integrated with external apps (diameter, a web service, etc) kamailio will wait for the http response, the more it takes to get the answer, the more it waits the more resources are wasted (and kamailio is not guilty of that), children start to “occupy” and will not handle invites or any (in our cases, not even OPTIONS and sip trunks started to go down). We had to cache and modify the backend to speed it up, we started to play with a children overbook (adding even more cpu’s) to “gift” more resources to be occupied in the wait and make a false more capacity.
2. I thought the backend was able to handle it “it’s not the problem” but it was at some point, as our backend is in a K8, increase the replicas helped a lot (after a fine code tuning in the app first)
In this “scenario” we run 8 x 4 node (16vcpu) clusters and each cluster is around 2500 average caps each with a decent cpu consumption and no loss (very very very tiny loss during peak hours which are ~4000 caps per cluster.
This is my comment based in our experience in a scenario like yours, doesn’t mean is the correct or more adequate answer, just an idea where to check first.
Regards
On Dec 19, 2024, at 10:08 AM, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because:
- sngrep does capture all the SIP packets and shows the flows
- though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite
- picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCraft https://www.cyberciti.biz/faq/linux-tcp-tuning/ and Tuning Kamailio for high throughput and performance | Evariste Systems Blog https://blog.evaristesys.com/2016/02/15/tuning-kamailio-for-high-throughput-and-performance/ and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060 http://10.242.17.125:5060/ 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060 http://10.242.17.146:5060/ 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg:
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases
- based on reverse DNS on IPs (default on) */
# auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.com http://sip.mydomain.com/"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface
- see the documentation of 'cfg_rpc' module.
- Format: group.id http://group.id/ = value 'desc' description
- Access: $sel(cfg_get.group.id http://cfg_get.group.id/) or @cfg_get.group.id http://cfg_get.group.id/ */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; } $xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On Thu, Dec 19, 2024 at 7:36 AM Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
Hello!
for this ST/SH project, we are using Kamailio 5.8.4 in stateless mode, making HTTP requests to a REST API (Java Spring) that will reply with a JSON object, and then Kamailio replaces the Contact header and sends a SIP 300 Multiple Choice reply to the SBC that sent the initial INVITE.
Kamailio is running on a VM with 4vCPUs and 4GB RAM and 2 NICs. On NIC ens224 there is a Virtual IP managed by Keepalived. Kamailio is listening on port 5060 on ens224 and set with 32 children process (tried with 8, 16, 24 and also 64, but with this value it was a lot worst).
We are doing load performance tests on our PreProd environment. With the SBC we are sending 450 to 600 CAPS to Kamailio, and what we noticed is that above 450 CAPS, and after less than 1 minute, Kamailio only replies SIP 100 to some INVITEs. We also could figure out that Kamailio is not receiving all the INVITES, despite having proved that ALL invites are sent to the server. It seems to me that, for some reason, the OS is somehow not able to deliver *all* SIP packets to Kamailio, because:
- sngrep does capture all the SIP packets and shows the flows
- though the flow shows SIP invite coming from SBC to Kamailio Server, there is no SIP 100 replied back to SBC, even though this is the 1st thing kamailio does, so, for me, Kamailio did not received the SIP Invite
- picking a call with reinvites, which after some seconds, SBC cancels, if I copy the Call-ID value and grep on kamailio's logs, I just do not find any content!
I have read some "network tuning" articles, including Linux Tune Network Stack (Buffers Size) To Increase Networking Performance - nixCraft and Tuning Kamailio for high throughput and performance | Evariste Systems Blog and when running the following command I get:
$ ss -4 -n -l | grep 5060 udp UNCONN 0 0 10.242.17.125:5060 0.0.0.0:* udp UNCONN 324224 0 10.242.17.146:5060 0.0.0.0:*
According to the article, the 3rd column should be as near 0 as possible, ideally 0.
While I am waiting for some sysadmin with root permissions to be available and modify some of the network parameters on this VM, I wonder if anyone has some tips to share on how to solve this behaviour. I'm not sure, either, what parameters to change or if they should be changed! The goal is to have a minimum 750 CAPS.
Lastly, some parts of the code:
Kamailio.cfg:
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR debug=1 log_stderror=no rundir="/tmp" memdbg=5 memlog=5 log_facility=LOG_LOCAL0 # configure the prefix for all log messages log_prefix_mode = 1 log_prefix="{$mt $hdr(CSeq) $ci} " /* number of SIP routing processes */ children=32 # ------------- ALREADY TRIED WITH 8,16,24... no results..... /* uncomment the next line to disable TCP (default on) */ disable_tcp=no /* uncomment the next line to disable the auto discovery of local aliases
- based on reverse DNS on IPs (default on) */
# auto_aliases=no /* add local domain aliases */ # alias="sip.mydomain.com"
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface
- see the documentation of 'cfg_rpc' module.
- Format: group.id = value 'desc' description
- Access: $sel(cfg_get.group.id) or @cfg_get.group.id */
####### Modules Section ########
/* set paths to location of modules */ loadmodule "db_mysql.so" loadmodule "db_cluster.so" loadmodule "http_client.so" loadmodule "jsonrpcs.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "jansson.so" loadmodule "snmpstats.so" loadmodule "file_out.so" loadmodule "ctl.so" loadmodule "permissions.so" loadmodule "xhttp.so" loadmodule "xhttp_rpc.so"
####### Other Args and Env Vars #########
/* listen addresses */ include_file "listen.cfg" include_file "db_conn.cfg"
# ----------------- setting module-specific parameters -------------- # --- DB Cluster params --- # minimum requirement is to have DBURL1 defined #!ifdef DBURL1 modparam("db_cluster", "connection" , DBURL1) #!endif #!ifdef DBURL2 modparam("db_cluster", "connection" , DBURL2) #!endif #!ifdef DBURL3 modparam("db_cluster", "connection" , DBURL3) #!endif #!ifdef DBURL4 modparam("db_cluster", "connection" , DBURL4) #!endif #!ifdef DBURL5 modparam("db_cluster", "connection" , DBURL5) #!endif modparam("db_cluster", "cluster", DBCLUSTER)
# --- Permissions params --- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) #modparam("permissions", "reload_delta", 30)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
modparam("jsonrpcs", "transport", 0) # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ctl")
# ----- http_async_client params ----- modparam("http_client", "query_result", 0) modparam("http_client", "keep_connections", 0) modparam("http_client", "connection_timeout",2) modparam("http_client", "timeout_mode",2) modparam("http_client", "config_file", "/usr/local/etc/kamailio/http_client.cfg") # ---- SNMP Stats params ---- modparam("snmpstats", "sipEntityType", "proxyServer") modparam("snmpstats", "sipEntityType", "redirectServer") modparam("snmpstats", "sipEntityType", "other") modparam("snmpstats", "snmpgetPath", "/usr/bin/") modparam("snmpstats", "MsgQueueMinorThreshold", 20) modparam("snmpstats", "MsgQueueMajorThreshold", 100) modparam("snmpstats", "dlg_minor_threshold", 20) modparam("snmpstats", "dlg_major_threshold", 100) modparam("snmpstats", "snmpCommunity", "kamailio")
# ---- File_Out params ---- modparam("file_out", "base_folder", "/data/sabire002/log/kamailio/") modparam("file_out", "file", "name=stsh_requests;interval=1440;extension=.log") modparam("file_out", "file", "name=cdr;interval=1440;extension=.log") modparam("file_out", "file", "name=http;interval=1440;extension=.log") ####### Routing Logic ########
include_file "includes/reqinit.cfg" include_file "includes/handle_options.cfg" include_file "includes/handle_cancel.cfg" include_file "includes/handle_stir_shaken_stateless.cfg" include_file "includes/handle_http_rpc.cfg"
request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $avp(GROUPID) = allow_address_group($si, $sp);
if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); #sl_reply("401", "Address not allowed"); exit; };
if (is_method("ACK") ) { #&& t_check_trans() ){ exit; }
if (is_method("INVITE")) { file_out("cdr","$rm|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("100","Trying"); }
route(HANDLE_OPTIONS);
route(REQINIT);
xlog("L_INFO"," ********** Route START ***********"); # log the basic info regarding this call xlog("L_INFO","=================================================== \n"); xlog("L_INFO","New SIP message $rm with call-ID $ci received $pr request $rm $ou source $si:$sp from $fu to $tu \n"); xlog("L_INFO","=================================================== \n");
route(HANDLE_STIRSHAKEN);
route(HANDLE_CANCEL);
if (method == "INVITE"){ route(RELAY); } }
route[RELAY] { # Sends a 300 Multiple Choices back to the proxy that requested the routing lookup xlog("L_INFO","RELAY - send reply \n"); file_out("cdr","RELAY|$ft|$tt|$ci|$rs|$rr|$Ts|$avp(START_TIME)|$fU|$fd|$si|$tU|$rU|$rd|$utimef(%Y-%m-%d %H:%M:%S)"); send_reply("300", "Multiple Choices"); exit; }
As for the HANDLE_STIRSHAKEN route, where the main process is:
route[HANDLE_STIRSHAKEN] {
if (!is_method("INVITE")) { return; } $xavp(requestTime) = $utimef(%s); $var(post) = $null; // resets and makes sure the $var(post) variable is null before usage
[.... get some header values ...]
$var(res) = http_connect("api1", "/stsh", "application/json", "$var(post)", "$var(result)"); jansson_xdecode($var(result), "json"); if ( $xavp(json=>sip-response-code) == 300 ) { remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); } else { # add error message to reply sl_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } }
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users sr-users@lists.kamailio.org wrote:
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On the other hand, you might consider scaling up first, since HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature optimisation. :-)
-- Alex
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
1. A query to an Diameter DRA (which for external reasons or customer reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users sr-users@lists.kamailio.org wrote:
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On the other hand, you might consider scaling up first, since HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users < sr-users@lists.kamailio.org> wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons or customer
reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users <
sr-users@lists.kamailio.org> wrote:
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users <
sr-users@lists.kamailio.org> wrote:
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On the other hand, you might consider scaling up first, since HTTP
performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users@lists.kamailio.org
To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to
the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s </snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr-users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua sergio.charrua@voip.pt escribió:
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons or
customer reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users
sr-users@lists.kamailio.org wrote:
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users
sr-users@lists.kamailio.org wrote:
Consider scaling out instead of scaling up. Now that you know
the
apparent limit of a single node for your use case, put it
behind a
Kamailio dispatcher.
On the other hand, you might consider scaling up first, since
HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature
optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users@lists.kamailio.org
To unsubscribe send an email to
sr-users-leave@lists.kamailio.org
Important: keep the mailing list in the recipients, do not
reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Hello,
just wondering what would be the best approach to use http_async_client on a stateless redirect server, if that is even possible. Any examples to share?
Also, as a side note, documentation/wiki Kamailio Modules https://kamailio.org/docs/modules/5.8.x/#H states that HTTP_CLIENT is a "Sync and async HTTP client using CURL library" but there are no examples on how to use async HTTP with this module....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Fri, Dec 20, 2024 at 10:19 AM Stefan via sr-users < sr-users@lists.kamailio.org> wrote:
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s
</snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr-users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua sergio.charrua@voip.pt escribió:
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users < sr-users@lists.kamailio.org> wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons or customer
reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users <
sr-users@lists.kamailio.org> wrote:
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users <
sr-users@lists.kamailio.org> wrote:
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On the other hand, you might consider scaling up first, since HTTP
performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users@lists.kamailio.org
To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to
the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Never had to use it. If you work with roundtrip times in microseconds, it becomes irrelevant. Have been replacing Req./Rep. situations with events, dataflows and triggers effectively removing the associated latencies.
Implementing ST/SH, or similar, services is interesting though. I can see the value, but implemented as suggested previously. There are probably others on the list that can suggest how processing suspend/resume can be done in a good way. It's suspend/resume you want. http_whatever is probably not.
Regards, Stefan
lör 2024-12-21 klockan 11:40 +0100 skrev Sergio Charrua via sr-users:
Hello,
just wondering what would be the best approach to use http_async_client on a stateless redirect server, if that is even possible. Any examples to share?
Also, as a side note, documentation/wiki Kamailio Modules states that HTTP_CLIENT is a "Sync and async HTTP client using CURL library" but there are no examples on how to use async HTTP with this module....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Fri, Dec 20, 2024 at 10:19 AM Stefan via sr-users sr-users@lists.kamailio.org wrote:
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s
</snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr- users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua sergio.charrua@voip.pt escribió:
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons or
customer reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users
sr-users@lists.kamailio.org wrote:
> On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users
sr-users@lists.kamailio.org wrote:
> > Consider scaling out instead of scaling up. Now that you
know the
> apparent limit of a single node for your use case, put it
behind a
> Kamailio dispatcher.
On the other hand, you might consider scaling up first,
since HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature
optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions
-- sr-users@lists.kamailio.org
To unsubscribe send an email to
sr-users-leave@lists.kamailio.org
Important: keep the mailing list in the recipients, do not
reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Just a short followup.
It looks as modules evapi and asynch could be used to build access to a service using a messagebus. Will probably try it. Looks interesting enough.
//s
lör 2024-12-21 klockan 19:11 +0100 skrev Stefan via sr-users:
Never had to use it. If you work with roundtrip times in microseconds, it becomes irrelevant. Have been replacing Req./Rep. situations with events, dataflows and triggers effectively removing the associated latencies.
Implementing ST/SH, or similar, services is interesting though. I can see the value, but implemented as suggested previously. There are probably others on the list that can suggest how processing suspend/resume can be done in a good way. It's suspend/resume you want. http_whatever is probably not.
Regards, Stefan
lör 2024-12-21 klockan 11:40 +0100 skrev Sergio Charrua via sr-users:
Hello,
just wondering what would be the best approach to use http_async_client on a stateless redirect server, if that is even possible. Any examples to share?
Also, as a side note, documentation/wiki Kamailio Modules states that HTTP_CLIENT is a "Sync and async HTTP client using CURL library" but there are no examples on how to use async HTTP with this module....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Fri, Dec 20, 2024 at 10:19 AM Stefan via sr-users sr-users@lists.kamailio.org wrote:
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s
</snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr- users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua sergio.charrua@voip.pt escribió:
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users sr-users@lists.kamailio.org wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons
or customer reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
> On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote: > > >> On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users sr-users@lists.kamailio.org wrote: >> >> Consider scaling out instead of scaling up. Now that you know the >> apparent limit of a single node for your use case, put it behind a >> Kamailio dispatcher. > > On the other hand, you might consider scaling up first, since HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little. > > You might think of scaling out as a form of premature optimisation. :-) > > -- Alex > > -- > Alex Balashov > Principal Consultant > Evariste Systems LLC > Web: https://evaristesys.com > Tel: +1-706-510-6800 > > __________________________________________________________ > Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org > To unsubscribe send an email to sr-users-leave@lists.kamailio.org > Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Any docs/articles you could share? besides Kamailio docs....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Mon, Dec 23, 2024 at 12:58 PM Stefan via sr-users < sr-users@lists.kamailio.org> wrote:
Just a short followup.
It looks as modules evapi and asynch could be used to build access to a service using a messagebus. Will probably try it. Looks interesting enough.
//s
lör 2024-12-21 klockan 19:11 +0100 skrev Stefan via sr-users:
Never had to use it. If you work with roundtrip times in microseconds, it becomes irrelevant. Have been replacing Req./Rep. situations with events, dataflows and triggers effectively removing the associated latencies.
Implementing ST/SH, or similar, services is interesting though. I can see the value, but implemented as suggested previously. There are probably others on the list that can suggest how processing suspend/resume can be done in a good way. It's suspend/resume you want. http_whatever is probably not.
Regards, Stefan
lör 2024-12-21 klockan 11:40 +0100 skrev Sergio Charrua via sr-users:
Hello,
just wondering what would be the best approach to use http_async_client on a stateless redirect server, if that is even possible. Any examples to share?
Also, as a side note, documentation/wiki Kamailio Modules https://kamailio.org/docs/modules/5.8.x/#H states that HTTP_CLIENT is a "Sync and async HTTP client using CURL library" but there are no examples on how to use async HTTP with this module....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Fri, Dec 20, 2024 at 10:19 AM Stefan via sr-users < sr-users@lists.kamailio.org> wrote:
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s
</snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr-users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua sergio.charrua@voip.pt escribió:
I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users < sr-users@lists.kamailio.org> wrote:
To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2)
- A query to an Diameter DRA (which for external reasons or customer
reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms)
So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing.
That is bad, really bad.
To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis).
With this, we removed the DRA query wait, so 220ms became 70/72ms.
Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc.
That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy …
Hope it helps
On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users <
sr-users@lists.kamailio.org> wrote:
On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users <
sr-users@lists.kamailio.org> wrote:
Consider scaling out instead of scaling up. Now that you know the apparent limit of a single node for your use case, put it behind a Kamailio dispatcher.
On the other hand, you might consider scaling up first, since HTTP
performs so badly that there is lots of improvement to be squeezed out of optimising that even a little.
You might think of scaling out as a form of premature optimisation. :-)
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users@lists.kamailio.org
To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to
the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
+1 on request :)
On 23 Dec 2024, at 9:01 AM, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
Any docs/articles you could share? besides Kamailio docs....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Mon, Dec 23, 2024 at 12:58 PM Stefan via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote:
Just a short followup.
It looks as modules evapi and asynch could be used to build access to a service using a messagebus. Will probably try it. Looks interesting enough.
//s
lör 2024-12-21 klockan 19:11 +0100 skrev Stefan via sr-users:
Never had to use it. If you work with roundtrip times in microseconds, it becomes irrelevant. Have been replacing Req./Rep. situations with events, dataflows and triggers effectively removing the associated latencies.
Implementing ST/SH, or similar, services is interesting though. I can see the value, but implemented as suggested previously. There are probably others on the list that can suggest how processing suspend/resume can be done in a good way. It's suspend/resume you want. http_whatever is probably not.
Regards, Stefan
lör 2024-12-21 klockan 11:40 +0100 skrev Sergio Charrua via sr-users:
Hello,
just wondering what would be the best approach to use http_async_client on a stateless redirect server, if that is even possible. Any examples to share?
Also, as a side note, documentation/wiki Kamailio Modules https://kamailio.org/docs/modules/5.8.x/#H states that HTTP_CLIENT is a "Sync and async HTTP client using CURL library" but there are no examples on how to use async HTTP with this module....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Fri, Dec 20, 2024 at 10:19 AM Stefan via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote:
Hi, Tried to comment yesterday but it didn't go through.
<snip> I would suggest use some message bus technology, work with services accessed over that bus and data that live in RAM. Choose your favorite programming language and build. I typically work with roundtrip times of microseconds. Then you can do pretty much what you like, no problems.
//s
</snip>
Now that I see the services accessed, ST/SH, is "http across town", nothing changes, then whatever http is to be processed should be done at/as a service. Accessed using your favorite message bus tech. from Kamailio. Keeping the kamailio processing asynch and using an edge triggered message bus.
Regards, Stefan
tor 2024-12-19 klockan 20:34 -0500 skrev Alexis Fidalgo via sr-users:
The mentioned ‘aws hosted webservice’ on my email is a stir shaken + call fraud scoring + ecnam service, no possible cache there.
Actually the diameter section is not cacheable either (leads to false positives) I just tested and mentioned it with the intention to graphic the concept of ‘delete the wait’ (if possible)
Sometimes caching is not possible at all. And the price (as we pay) is to assign resources and watch it being occupied waiting. Trust me, 9000 caps made me try a lot of paths
Enviado desde dispositivo móvil
> El 19 dic 2024, a la(s) 7:12 p. m., Sergio Charrua <sergio.charrua@voip.pt mailto:sergio.charrua@voip.pt> escribió: > > > I understand the idea behind using cache facilities, however in this case, being a ST/SH attestation service, all calls need to be attested and the probability that multiple calls having src and dst numbers identical is, IMHO, very reduced. > So I don't see how a caching system could be used here, hence why HTTP is "a necessary evil".... unless i'm missing something here.... > > Atenciosamente / Kind Regards / Cordialement / Un saludo, > > Sérgio Charrua > > On Thu, Dec 19, 2024 at 11:19 PM Alexis Fidalgo via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote: >> To add some information if useful. In our case there are 2 main “actions” performed as processing when http service is called that takes a lot of time (there are more but are negligible against these 2) >> >> 1. A query to an Diameter DRA (which for external reasons or customer reasons) takes an average of 150ms (and in some other cities of the deploys can take more because of the delay in the links) >> 2. A query to a rest webservice that is in AWS, not that bad as point 1 but still bad (~70ms) >> >> So, in the best of scenarios, we have ~225ms, maybe if the DRA load balances to another HSS we get ~180ms total call processing. >> >> That is bad, really bad. >> >> To probe the idea and before any major changes in any part, I started to keep DRA responses in a redis (we use dragonfly), it’s not consistent in terms of our call processing flow but my idea was to “remove” the delay of the diameter query (I run the query, keep the result in redis, when a new request arrives for the same value I use the cached value and send a new DRA query in other thread to avoid lock the current one and update the redis). >> >> With this, we removed the DRA query wait, so 220ms became 70/72ms. >> >> Instantly all cpu usage, all retransmissions, everything disappeared, cpu, mem went down drastically, etc etc. >> >> That’s why I mentioned ’wait time is the enemy’, http is not (maybe is not your best friend but not the enemy). If it works, there’s an analogy, you can try to improve aerodynamics, engine and whatever in a F1 car, but if the driver is heavy … >> >> Hope it helps >> >> >> > On Dec 19, 2024, at 5:18 PM, Alex Balashov via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote: >> > >> > >> >> On Dec 19, 2024, at 1:06 pm, Calvin E. via sr-users <sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org> wrote: >> >> >> >> Consider scaling out instead of scaling up. Now that you know the >> >> apparent limit of a single node for your use case, put it behind a >> >> Kamailio dispatcher. >> > >> > On the other hand, you might consider scaling up first, since HTTP performs so badly that there is lots of improvement to be squeezed out of optimising that even a little. >> > >> > You might think of scaling out as a form of premature optimisation. :-) >> > >> > -- Alex >> > >> > -- >> > Alex Balashov >> > Principal Consultant >> > Evariste Systems LLC >> > Web: https://evaristesys.com https://evaristesys.com/ >> > Tel: +1-706-510-6800 >> > >> > __________________________________________________________ >> > Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org >> > To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org >> > Important: keep the mailing list in the recipients, do not reply only to the sender! >> >> __________________________________________________________ >> Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org >> To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org >> Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org mailto:sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org mailto:sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 6:27 am, Stefan via sr-users sr-users@lists.kamailio.org wrote:
It looks as modules evapi and asynch could be used to build access to a service using a messagebus.
Oh yes. This is the way.
This is the central principle on which the call processor in our product operates:
https://kamailio.org/docs/modules/5.8.x/modules/evapi.html#evapi.f.evapi_asy...
I think the documentation largely speaks for itself in terms of how to use it, but it definitely requires software engineering prowess on the service side.
-- Alex
On Dec 23, 2024, at 9:16 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 6:27 am, Stefan via sr-users sr-users@lists.kamailio.org wrote:
It looks as modules evapi and asynch could be used to build access to a service using a messagebus.
Oh yes. This is the way.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Could creating a "middleware" python script (or any other language) that Kamailio calls and sends required data, and then makes a HTTP request to the API be efficient ? I'm a bit skeptical, honestly .... in my case (and certainly many others), I can't get rid of the HTTP request to the STSH online service, that needs to be executed at some point....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Mon, Dec 23, 2024 at 3:44 PM Alex Balashov via sr-users < sr-users@lists.kamailio.org> wrote:
This is the central principle on which the call processor in our product operates:
https://kamailio.org/docs/modules/5.8.x/modules/evapi.html#evapi.f.evapi_asy...
I think the documentation largely speaks for itself in terms of how to use it, but it definitely requires software engineering prowess on the service side.
-- Alex
On Dec 23, 2024, at 9:16 am, Alex Balashov abalashov@evaristesys.com
wrote:
On Dec 23, 2024, at 6:27 am, Stefan via sr-users <
sr-users@lists.kamailio.org> wrote:
It looks as modules evapi and asynch could be used to build access to a
service using a messagebus.
Oh yes. This is the way.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 10:06 am, Sergio Charrua sergio.charrua@voip.pt wrote:
Could creating a "middleware" python script (or any other language) that Kamailio calls and sends required data, and then makes a HTTP request to the API be efficient ?
100%, and this is what you should do. Just make sure it's a separate service and not a script.
but won't that add additional delay ? I mean, connection from Kamailio to python "middleware" script will also take some additional time to be made (even on localhost) and from "middleware" to STSH API via HTTP ....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Mon, Dec 23, 2024 at 4:39 PM Alex Balashov via sr-users < sr-users@lists.kamailio.org> wrote:
On Dec 23, 2024, at 10:06 am, Sergio Charrua sergio.charrua@voip.pt
wrote:
Could creating a "middleware" python script (or any other language) that
Kamailio calls and sends required data, and then makes a HTTP request to the API be efficient ?
100%, and this is what you should do. Just make sure it's a separate service and not a script.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Delay is fine. Delay with bad concurrency or performance characteristics is bad. Free delay with few to no adverse effects is fabulous.
On Dec 23, 2024, at 10:52 am, Sergio Charrua sergio.charrua@voip.pt wrote:
but won't that add additional delay ? I mean, connection from Kamailio to python "middleware" script will also take some additional time to be made (even on localhost) and from "middleware" to STSH API via HTTP ....
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Mon, Dec 23, 2024 at 4:39 PM Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
On Dec 23, 2024, at 10:06 am, Sergio Charrua sergio.charrua@voip.pt wrote:
Could creating a "middleware" python script (or any other language) that Kamailio calls and sends required data, and then makes a HTTP request to the API be efficient ?
100%, and this is what you should do. Just make sure it's a separate service and not a script.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 10:52 am, Sergio Charrua sergio.charrua@voip.pt wrote:
I mean, connection from Kamailio to python "middleware" script will also take some additional time to be made (even on localhost) and from "middleware" to STSH API via HTTP ....
Oh, I meant to say here:
You're right, you don't want to make new connections to the "middleware" here. That's bad. You want persistent connections to the middleware that can be reused without being initiated anew each time.
EVAPI provides an excellent solution to this, and that's why I use it. In that model, there are no outbound connections at all, only inbound, not entirely dissimilar to driving a call with FreeSWITCH ESL or Asterisk ARI or whatever.
But it's not the only option. Plain UDP querying can work too. One program of action can be to forward the INVITE to a minimal SIP UA as-is, too, and I am familiar with lots of platforms where this is done. However, there are so many simpler alternatives nowadays. I think EVAPI is the simplest of them all, but raw UDP may be even simpler:
https://kamailio.org/docs/modules/5.8.x/modules/corex.html#corex.f.send_udp
https://kamailio.org/docs/modules/5.8.x/modules/corex.html#corex.evr.network...
-- Alex
I agree on the "make it a separate server" as a best practice, however I think that unless the discussion is implementing a SIP stack in the python script, this is not the way to go. Assuming that the question is about using KEMI for the script (either as the entire Kamailio scripting or calling a python function inline with scripting), the same problem remains:
You need to make WAITING for the reply to be asynchronous.
I'm not sure that you can do that in a python function and then resume the SIP processing (i.e. Do something useful with the reply). I'm not absolutely certain on this, but I think that is the general problem with using just the async module when 100% (or near 100%) of your requests will follow this pattern.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 9:25 AM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 10:06 am, Sergio Charrua sergio.charrua@voip.pt wrote:
Could creating a "middleware" python script (or any other language) that Kamailio calls and sends required data, and then makes a HTTP request to the API be efficient ?
100%, and this is what you should do. Just make sure it's a separate service and not a script.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Again, playing Devil's advocate: Doesn't that use TCP? It feels like:
* HTTP evil based solely on anecdotal evidence. I know you have a LOT of history, and I don't want downplay your experience, but I'm showing empirically how this can work, and all you fall back to is the basic "this is evil". * TCP based connections bad, even DB connections. * EVAPI: Magic cure-all, despite being inherently more complex to implement on the far end, and complexity usually results in more failures.
Since this is now being promoted in this thread, can you provide sunlight as to why this is golden vs something DB driven for example?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 8:16 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 6:27 am, Stefan via sr-users sr-users@lists.kamailio.org wrote:
It looks as modules evapi and asynch could be used to build access to a service using a messagebus.
Oh yes. This is the way.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 10:45 am, Ben Kaufman bkaufman@bcmone.com wrote:
Again, playing Devil's advocate: Doesn't that use TCP? It feels like:
• HTTP evil based solely on anecdotal evidence. I know you have a LOT of history, and I don't want downplay your experience, but I'm showing empirically how this can work, and all you fall back to is the basic "this is evil". • TCP based connections bad, even DB connections. • EVAPI: Magic cure-all, despite being inherently more complex to implement on the far end, and complexity usually results in more failures.
Since this is now being promoted in this thread, can you provide sunlight as to why this is golden vs something DB driven for example?
I have no desire to promote EVAPI unnecessarily to those who aren't already aware that it's a magic cure-all. ;-)
Joking aside:
1) Never, ever said TCP connections are bad; de novo TCP connections initiated for every query are bad;
2) Persistent connections to databases are fairly competitive with this type of option, but a more generic channel is more flexible because the thing on the other side can perform more logic, provide more complex or appropriately structured responses, etc, not just responses to SQL queries or procedure calls;
3) EVAPI is a passive model in which the outside services connect _to_ Kamailio, and Kamailio does not maintain outbound connections to those services. This is a lot more resilient, because Kamailio isn't that great at maintaining connections to things.
-- Alex
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Ben Kaufman via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 9:45 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Ben Kaufman bkaufman@bcmone.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Again, playing Devil's advocate: Doesn't that use TCP? It feels like:
* HTTP evil based solely on anecdotal evidence. I know you have a LOT of history, and I don't want downplay your experience, but I'm showing empirically how this can work, and all you fall back to is the basic "this is evil". * TCP based connections bad, even DB connections. * EVAPI: Magic cure-all, despite being inherently more complex to implement on the far end, and complexity usually results in more failures.
Since this is now being promoted in this thread, can you provide sunlight as to why this is golden vs something DB driven for example?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 8:16 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 6:27 am, Stefan via sr-users sr-users@lists.kamailio.org wrote:
It looks as modules evapi and asynch could be used to build access to a service using a messagebus.
Oh yes. This is the way.
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
1) EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
2) TCP client connects to this socket when it becomes available;
2) Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
3) TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
4) Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
5) In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
PS. A key selling point of this is that if the TCP client crashes or becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
One additional thought -- sorry for the numerous messages:
This discussion has got a little too academic. When talking about concurrency, it's important to ask what the workload actually is and how parallelisable it is.
1) All these async tricks are most useful when you have a busy Kamailio server that does lots of different kinds of things. Freeing up worker processes becomes an important objective, because not blocking them with these requests allows them to handle those requests and those other replies.
2) The other important consideration is locking: how much are shared-memory structures (transaction state, dialog state, htables, etc) being accessed by multiple worker processes?
These issues are typical of Kamailio-based multiservice SIP gateways that perform functions like call routing, registration, presence, etc. all in one system.
Purpose-built redirect servers that query an HTTP API have a trivial and one-track workload. They receive an INVITE, it's allocated to a worker, the worker goes and bangs on an HTTP server, gets a response, and sends it back to the callee. There are no other requests to juggle, save for the incidental OPTIONS ping maybe, there are no SIP replies to process and relay, and nothing else to do except to absorb ACKs (if the redirects are sent statefully). Along the way, vanishingly little is being accessed apart from transaction memory (if stateful), and concurrent accesses to that are fast because the locks are pretty granular.
Thus, this type of workload doesn't benefit from general-purpose throughput optimisations much. The proper approach, using whichever HTTP client module, is to spin up as many child processes as can be spun up without diminishing returns, and just dedicating them to that singular function while studiously avoiding lockable shared data (e.g. htable). This keeps all the cars mostly in their own lanes, and the success or failure of that per se will dictate throughput.
-- Alex
On Dec 23, 2024, at 11:25 am, Alex Balashov abalashov@evaristesys.com wrote:
PS. A key selling point of this is that if the TCP client crashes or becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
We're agreed on creating a dedicated redirect server for this process, I'm not sure I agree on the need to ramp up processes on this, when the tradeoff of holding the transaction in shared memory while waiting for an http response exists. To be sure, you're trading increased shared memory vs increased package memory, but there's frequently other considerations as well. In situations like this, I find that I'm doing a database dip, etc. in addition to the http request . Adding more workers adds more DB connections, unnecessarily increasing memory consumption.
I'd go so far as to say that the older http_client generally shouldn't be used. If you have very infrequent http requests to execute and want to use it because it's syntactically easier then it might make sense, but beyond that it only offers lesser performance.
Honestly, this thread has mostly devolved to two points:
1. Should HTTP requests ever be used: I think we're all agreed that they're not ideal. **HOW** not ideal they are and how much we can force other things to use an alternate process remain. 2. When making http requests, which module should be used. Without hesitation I would say to use http_async_query for the performance gain.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 10:51 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
One additional thought -- sorry for the numerous messages:
This discussion has got a little too academic. When talking about concurrency, it's important to ask what the workload actually is and how parallelisable it is.
1) All these async tricks are most useful when you have a busy Kamailio server that does lots of different kinds of things. Freeing up worker processes becomes an important objective, because not blocking them with these requests allows them to handle those requests and those other replies.
2) The other important consideration is locking: how much are shared-memory structures (transaction state, dialog state, htables, etc) being accessed by multiple worker processes?
These issues are typical of Kamailio-based multiservice SIP gateways that perform functions like call routing, registration, presence, etc. all in one system.
Purpose-built redirect servers that query an HTTP API have a trivial and one-track workload. They receive an INVITE, it's allocated to a worker, the worker goes and bangs on an HTTP server, gets a response, and sends it back to the callee. There are no other requests to juggle, save for the incidental OPTIONS ping maybe, there are no SIP replies to process and relay, and nothing else to do except to absorb ACKs (if the redirects are sent statefully). Along the way, vanishingly little is being accessed apart from transaction memory (if stateful), and concurrent accesses to that are fast because the locks are pretty granular.
Thus, this type of workload doesn't benefit from general-purpose throughput optimisations much. The proper approach, using whichever HTTP client module, is to spin up as many child processes as can be spun up without diminishing returns, and just dedicating them to that singular function while studiously avoiding lockable shared data (e.g. htable). This keeps all the cars mostly in their own lanes, and the success or failure of that per se will dictate throughput.
-- Alex
On Dec 23, 2024, at 11:25 am, Alex Balashov abalashov@evaristesys.com wrote:
PS. A key selling point of this is that if the TCP client crashes or becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
For sure ill consider this in the future scenarios (i need to see how it deals with the load balancing part that for example K8 offers for having n replicas of the evapi server side), but in my case im stuck with http on this scenario (cannot change that), now is stateless (blocking) and i would like to move it to http_async, i did it, but i get the 3xx retransmission and found now way yet on how to absorb the ACK (matching it with the transaction to end it)
im on the way, not there yet
On 23 Dec 2024, at 2:17 PM, Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
The http_async_client event loop is a better performer, for sure. But the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big. You just can't have a slow HTTP API.
The beauty of EVAPI is that there's no query, no new connection, and no event loop beyond normal TCP socket multiplexing.
— Sent from mobile, apologies for brevity and errors.
On Dec 23, 2024, at 12:10 PM, Ben Kaufman bkaufman@bcmone.com wrote:
We're agreed on creating a dedicated redirect server for this process, I'm not sure I agree on the need to ramp up processes on this, when the tradeoff of holding the transaction in shared memory while waiting for an http response exists. To be sure, you're trading increased shared memory vs increased package memory, but there's frequently other considerations as well. In situations like this, I find that I'm doing a database dip, etc. in addition to the http request . Adding more workers adds more DB connections, unnecessarily increasing memory consumption.
I'd go so far as to say that the older http_client generally shouldn't be used. If you have very infrequent http requests to execute and want to use it because it's syntactically easier then it might make sense, but beyond that it only offers lesser performance.
Honestly, this thread has mostly devolved to two points:
Should HTTP requests ever be used: I think we're all agreed that they're not ideal. **HOW** not ideal they are and how much we can force other things to use an alternate process remain. When making http requests, which module should be used. Without hesitation I would say to use http_async_query for the performance gain.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768 https://www.sip.us/ https://www.siptrunk.com/ https://www.flowroute.com/
From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 10:51 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
One additional thought -- sorry for the numerous messages:
This discussion has got a little too academic. When talking about concurrency, it's important to ask what the workload actually is and how parallelisable it is.
All these async tricks are most useful when you have a busy Kamailio server that does lots of different kinds of things. Freeing up worker processes becomes an important objective, because not blocking them with these requests allows them to handle those requests and those other replies.
The other important consideration is locking: how much are shared-memory structures (transaction state, dialog state, htables, etc) being accessed by multiple worker processes?
These issues are typical of Kamailio-based multiservice SIP gateways that perform functions like call routing, registration, presence, etc. all in one system.
Purpose-built redirect servers that query an HTTP API have a trivial and one-track workload. They receive an INVITE, it's allocated to a worker, the worker goes and bangs on an HTTP server, gets a response, and sends it back to the callee. There are no other requests to juggle, save for the incidental OPTIONS ping maybe, there are no SIP replies to process and relay, and nothing else to do except to absorb ACKs (if the redirects are sent statefully). Along the way, vanishingly little is being accessed apart from transaction memory (if stateful), and concurrent accesses to that are fast because the locks are pretty granular.
Thus, this type of workload doesn't benefit from general-purpose throughput optimisations much. The proper approach, using whichever HTTP client module, is to spin up as many child processes as can be spun up without diminishing returns, and just dedicating them to that singular function while studiously avoiding lockable shared data (e.g. htable). This keeps all the cars mostly in their own lanes, and the success or failure of that per se will dictate throughput.
-- Alex
On Dec 23, 2024, at 11:25 am, Alex Balashov abalashov@evaristesys.com wrote:
PS. A key selling point of this is that if the TCP client crashes or becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/ Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
I think I had the same issue with 3xx retransmissions and ACK as you are having....
Not sure it this is the correct way, but I solved this by: - setting TM parameters : modparam("tm", "failure_reply_mode", 3) modparam("tm", "fr_timer", 500)
and adding in the main route: if (is_method("ACK") ) { xlog("L_INFO","New SIP message $rm with call-ID $ci \n"); exit; }
(I don't care about ACK at this point.... once I get an ACK from SBC, the process should be released)
And I am using http_async_client in stateful transactions. I am now trying to set a failover to a second URL if the 1st request fails...
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Mon, Dec 23, 2024 at 7:02 PM Alexis Fidalgo via sr-users < sr-users@lists.kamailio.org> wrote:
For sure ill consider this in the future scenarios (i need to see how it deals with the load balancing part that for example K8 offers for having n replicas of the evapi server side), but in my case im stuck with http on this scenario (cannot change that), now is stateless (blocking) and i would like to move it to http_async, i did it, but i get the 3xx retransmission and found now way yet on how to absorb the ACK (matching it with the transaction to end it)
im on the way, not there yet
On 23 Dec 2024, at 2:17 PM, Alex Balashov via sr-users < sr-users@lists.kamailio.org> wrote:
The http_async_client event loop is a better performer, for sure. But the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big. You just can't have a slow HTTP API.
The beauty of EVAPI is that there's no query, no new connection, and no event loop beyond normal TCP socket multiplexing.
— Sent from mobile, apologies for brevity and errors.
On Dec 23, 2024, at 12:10 PM, Ben Kaufman bkaufman@bcmone.com wrote:
We're agreed on creating a dedicated redirect server for this process, I'm not sure I agree on the need to ramp up processes on this, when the tradeoff of holding the transaction in shared memory while waiting for an http response exists. To be sure, you're trading increased shared memory vs increased package memory, but there's frequently other considerations as well. In situations like this, I find that I'm doing a database dip, etc. in addition to the http request . Adding more workers adds more DB connections, unnecessarily increasing memory consumption.
I'd go so far as to say that the older http_client generally shouldn't be used. If you have very infrequent http requests to execute and want to use it because it's syntactically easier then it might make sense, but beyond that it only offers lesser performance.
Honestly, this thread has mostly devolved to two points:
- Should HTTP requests ever be used: I think we're all agreed that
they're not ideal. **HOW** not ideal they are and how much we can force other things to use an alternate process remain. 2. When making http requests, which module should be used. Without hesitation I would say to use http_async_query for the performance gain.
*Kaufman*
*Senior Voice Engineer *
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 *|* SIPTRUNK Client Support: 800.250.6510 *|* Flowroute Client Support: 855.356.9768 [image: img] https://www.sip.us/ [image: img] https://www.siptrunk.com/ *[image: img] https://www.flowroute.com/*
*From:* Alex Balashov via sr-users sr-users@lists.kamailio.org *Sent:* Monday, December 23, 2024 10:51 AM *To:* Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org *Cc:* Alex Balashov abalashov@evaristesys.com *Subject:* [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
One additional thought -- sorry for the numerous messages:
This discussion has got a little too academic. When talking about concurrency, it's important to ask what the workload actually is and how parallelisable it is.
- All these async tricks are most useful when you have a busy Kamailio
server that does lots of different kinds of things. Freeing up worker processes becomes an important objective, because not blocking them with these requests allows them to handle those requests and those other replies.
- The other important consideration is locking: how much are
shared-memory structures (transaction state, dialog state, htables, etc) being accessed by multiple worker processes?
These issues are typical of Kamailio-based multiservice SIP gateways that perform functions like call routing, registration, presence, etc. all in one system.
Purpose-built redirect servers that query an HTTP API have a trivial and one-track workload. They receive an INVITE, it's allocated to a worker, the worker goes and bangs on an HTTP server, gets a response, and sends it back to the callee. There are no other requests to juggle, save for the incidental OPTIONS ping maybe, there are no SIP replies to process and relay, and nothing else to do except to absorb ACKs (if the redirects are sent statefully). Along the way, vanishingly little is being accessed apart from transaction memory (if stateful), and concurrent accesses to that are fast because the locks are pretty granular.
Thus, this type of workload doesn't benefit from general-purpose throughput optimisations much. The proper approach, using whichever HTTP client module, is to spin up as many child processes as can be spun up without diminishing returns, and just dedicating them to that singular function while studiously avoiding lockable shared data (e.g. htable). This keeps all the cars mostly in their own lanes, and the success or failure of that per se will dictate throughput.
-- Alex
On Dec 23, 2024, at 11:25 am, Alex Balashov abalashov@evaristesys.com
wrote:
PS. A key selling point of this is that if the TCP client crashes or
becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com
wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users <
sr-users@lists.kamailio.org> wrote:
This came off a bit more harsh than I intended. I think I understand
the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding
the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
- TCP client reads this package off the wire; the built-in netstring
support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
- Kamailio receives this message in $evapi(msg), in this event_route,
and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened
by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface
with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/
Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/
Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy... https://evaristesys.com/ Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
* the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big.
TL;DR: The difference isn't only big, it's enough to make the OP's proposed scenario work.
Using the sample code I listed above, I tested this at 750 INVITEs/second using a minimal number of listener processes in docker on WSL2 in the background of my laptop while I did my other work (far from an ideal). Yes, I had to bump the shared memory up to 1 GB. And that is high, but it's far more sane than 750 listener processes. At one point in time, there was a problem with the http connection to the http service, but this didn't cause any type of crash or unmanagable event. For a variety of reasons, I'd probably look to implement two of these redirect servers in the real world and balance requests between the two.
[ben@NV0162~/projects/AAA_examples/kamailio/http_async]$ dc exec kamailio kamcmd ps 1 main process - attendant 7 udp receiver child=0 sock=127.0.0.1:5060 8 udp receiver child=1 sock=127.0.0.1:5060 9 udp receiver child=0 sock=172.23.0.2:5060 10 udp receiver child=1 sock=172.23.0.2:5060 11 slow timer 12 timer 13 secondary timer 14 Http Async Worker 15 ctl handler 16 tcp receiver (generic) child=0 17 tcp receiver (generic) child=1 18 tcp main process
[cid:fc4b45d6-ef07-4d63-ad78-39bfb8404f2e]
Less than 1% failure rate to the UA, under far from ideal conditions, with no re-attempts, etc.
Kaufman
Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 11:17 AM To: Kamailio - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
The http_async_client event loop is a better performer, for sure. But the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big. You just can't have a slow HTTP API.
The beauty of EVAPI is that there's no query, no new connection, and no event loop beyond normal TCP socket multiplexing.
— Sent from mobile, apologies for brevity and errors.
On Dec 23, 2024, at 12:10 PM, Ben Kaufman bkaufman@bcmone.com wrote:
We're agreed on creating a dedicated redirect server for this process, I'm not sure I agree on the need to ramp up processes on this, when the tradeoff of holding the transaction in shared memory while waiting for an http response exists. To be sure, you're trading increased shared memory vs increased package memory, but there's frequently other considerations as well. In situations like this, I find that I'm doing a database dip, etc. in addition to the http request . Adding more workers adds more DB connections, unnecessarily increasing memory consumption.
I'd go so far as to say that the older http_client generally shouldn't be used. If you have very infrequent http requests to execute and want to use it because it's syntactically easier then it might make sense, but beyond that it only offers lesser performance.
Honestly, this thread has mostly devolved to two points:
1. Should HTTP requests ever be used: I think we're all agreed that they're not ideal. **HOW** not ideal they are and how much we can force other things to use an alternate process remain. 2. When making http requests, which module should be used. Without hesitation I would say to use http_async_query for the performance gain.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 10:51 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
One additional thought -- sorry for the numerous messages:
This discussion has got a little too academic. When talking about concurrency, it's important to ask what the workload actually is and how parallelisable it is.
1) All these async tricks are most useful when you have a busy Kamailio server that does lots of different kinds of things. Freeing up worker processes becomes an important objective, because not blocking them with these requests allows them to handle those requests and those other replies.
2) The other important consideration is locking: how much are shared-memory structures (transaction state, dialog state, htables, etc) being accessed by multiple worker processes?
These issues are typical of Kamailio-based multiservice SIP gateways that perform functions like call routing, registration, presence, etc. all in one system.
Purpose-built redirect servers that query an HTTP API have a trivial and one-track workload. They receive an INVITE, it's allocated to a worker, the worker goes and bangs on an HTTP server, gets a response, and sends it back to the callee. There are no other requests to juggle, save for the incidental OPTIONS ping maybe, there are no SIP replies to process and relay, and nothing else to do except to absorb ACKs (if the redirects are sent statefully). Along the way, vanishingly little is being accessed apart from transaction memory (if stateful), and concurrent accesses to that are fast because the locks are pretty granular.
Thus, this type of workload doesn't benefit from general-purpose throughput optimisations much. The proper approach, using whichever HTTP client module, is to spin up as many child processes as can be spun up without diminishing returns, and just dedicating them to that singular function while studiously avoiding lockable shared data (e.g. htable). This keeps all the cars mostly in their own lanes, and the success or failure of that per se will dictate throughput.
-- Alex
On Dec 23, 2024, at 11:25 am, Alex Balashov abalashov@evaristesys.com wrote:
PS. A key selling point of this is that if the TCP client crashes or becomes unavailable, the transaction just times out after a while, instead of any Kamailio worker processes shitting themselves or blocking because they're unable to connect to something. There's nothing to connect to.
This alone sold me. Once you go EVAPI, you can't go back.
-- Alex
On Dec 23, 2024, at 11:23 am, Alex Balashov abalashov@evaristesys.com wrote:
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
- EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
TCP client connects to this socket when it becomes available;
Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
- In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 1:14 pm, Ben Kaufman bkaufman@bcmone.com wrote:
• the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big.
TL;DR: The difference isn't only big, it's enough to make the OP's proposed scenario work.
I didn't say 750 CPS wouldn't work, and didn't make that claim when you originally asked. The danger with committing to specific numbers is that they harken back to the era of hardware and software in which you last did peak load tests.
In the case of http_async_client, for me, that was probably the mid-2010s. Whatever I could say worked or didn't work then is surely different now.
My contention was that HTTP queries, even with http_async_client, are a paradigm for which Kamailio isn't especially well-suited as compared to other approaches. That is to say, the other designs recommended here would work better, if properly implemented. I don't say that http_async_client can't be made to hit the OP's specific targets, and I commend you in your efforts to show that it can.
-- Alex
Your contention that I was rebutting (emphasis mine) was:
* "whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big,"
The difference in performance is substantial. Your indication that the performance of the two modules as near equal is incorrect. Both in theory and in practice it is the better of the two options.
(You might turn back to the "if one were to create a ridiculous number of processes", but since each module gets allocated memory per process, this is not a good idea).
Kaufman
Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 1:01 PM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 1:14 pm, Ben Kaufman bkaufman@bcmone.com wrote:
• the original controversy was about whether it's better to let slow HTTP requests block things or stack up in an async context, and the contention was that it doesn't much matter either way and that the difference won't be too big.
TL;DR: The difference isn't only big, it's enough to make the OP's proposed scenario work.
I didn't say 750 CPS wouldn't work, and didn't make that claim when you originally asked. The danger with committing to specific numbers is that they harken back to the era of hardware and software in which you last did peak load tests.
In the case of http_async_client, for me, that was probably the mid-2010s. Whatever I could say worked or didn't work then is surely different now.
My contention was that HTTP queries, even with http_async_client, are a paradigm for which Kamailio isn't especially well-suited as compared to other approaches. That is to say, the other designs recommended here would work better, if properly implemented. I don't say that http_async_client can't be made to hit the OP's specific targets, and I commend you in your efforts to show that it can.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 3:14 pm, Ben Kaufman bkaufman@bcmone.com wrote:
The difference in performance is substantial.
If you confine the scope of your evaluation to Kamailio itself, then of course it's substantial; you've deputised the event mux/polling workload into kernel space. While that makes it invisible, it doesn't obviate the clock cycles.
This is like saying that Node can handle a tremendous amount of requests with a single process. I suppose it can, but only because it's able to farm out the work of monitoring sockets for data to the OS, and erase it from the ledger, if you like, of userspace costs. They still go somewhere, and that somewhere is constrained by available resources and dimensioning.
Assuming you've used this repo and assets to make your case:
https://github.com/whosgonna/kamailio_http_async
this is not a fair or reasonable comparison. In one case, you're using an external polling loop, and in the other, you're blocking your worker processes by definition. I doubt you could get 3 CPS through that config if the async shvar is set to 0.
Furthermore, the idea of an HTTP service that responds like a metronome in 1 sec, over local sockets and without any of the overhead of connection setup over a real-world network, is so contrived as to be tautological. You've neutered the synchronous approach to the maximum possible extent, while testing the asynchronous one in highly idealised conditions. In fact, tried your repo, followed your instructions on a hex-core server with 16 GB of RAM (2 GB of SHM allocated to Kamailio) and was able to get about 1600 CPS -- more than twice the OP's ask -- before seeing any retransmissions. It's so contrived as to be tautological, as if to say that being rich, young and healthy is better than being old, ill and poor. I cannot agree more.
If you empower the synchronous http_client approach with a comparable degree of parallelism, i.e. a large pool of worker processes with minimum package memory, you'll get comparable throughput. I agree that there are memory limits around that in Kamailio's concurrency model, and that was never in dispute. But you're going to pay it somewhere either way:

Are we talking about performance, or are we talking about which HTTP client module delivers more throughput within Kamailio's architectural constraints? If the latter, this was never in dispute in my mind.
-- Alex
On Dec 23, 2024, at 3:14 pm, Ben Kaufman bkaufman@bcmone.com wrote:
The difference in performance is substantial. Your indication that the performance of the two modules as near equal is incorrect. Both in theory and in practice it is the better of the two options.
If you confine the scope of your evaluation to Kamailio itself, then of course it's substantial; you've deputised the event mux/polling workload into kernel space. While that makes it invisible, it doesn't obviate the clock cycles. I'm talking about formal performance.
This is like saying that Node can handle a tremendous amount of requests with a single process. I suppose it can, but only because it's able to farm out the work of monitoring sockets for data to the OS, and erase it from the ledger, if you like, of userspace costs. They still go somewhere, and that somewhere is constrained by available resources and dimensioning.
Assuming you've used this repo and assets to make your case:
https://github.com/whosgonna/kamailio_http_async
this is not a fair or reasonable comparison. In one case, you're using an external polling loop, and in the other, you're blocking your worker processes by definition. I doubt you could get 3 CPS through that config if the async shvar is set to 0.
Furthermore, the idea of an HTTP service that responds like a metronome in 1 sec, over local sockets and without any of the overhead of connection setup over a real-world network, is so contrived as to be tautological. You've neutered the synchronous approach to the maximum possible extent, while testing the asynchronous one in highly idealised conditions. In fact, tried your repo, followed your instructions on a hex-core server with 16 GB of RAM (2 GB of SHM allocated to Kamailio) and was able to get about 1600 CPS -- more than twice the OP's ask -- before seeing any retransmissions. It's so contrived as to be tautological, as if to say that being rich, young and healthy is better than being old, ill and poor. I cannot agree more.
If you empower the synchronous http_client approach with a comparable degree of parallelism, i.e. a large pool of worker processes with minimum package memory, you'll get comparable throughput. I agree that there are memory limits around that in Kamailio's concurrency model, and that was never in dispute. But you're going to pay it somewhere either way:
Mem: 16175052K used, 217632K free, 266764K shrd, 219644K buff, 10489916K cached CPU: 22% usr 15% sys 0% nic 58% idle 0% io 0% irq 3% sirq Load average: 0.46 0.54 0.45 7/555 32 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 14 1 root R 2076m 12% 3 14% kamailio -dDDE -de -n 2 -m 2048 10 1 root R 2073m 12% 1 3% kamailio -dDDE -de -n 2 -m 2048 9 1 root S 2073m 12% 3 3% kamailio -dDDE -de -n 2 -m 2048 12 1 root S 2073m 12% 0 0% kamailio -dDDE -de -n 2 -m 2048 1 0 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 17 1 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 13 1 root S 2073m 12% 1 0% kamailio -dDDE -de -n 2 -m 2048 16 1 root S 2073m 12% 3 0% kamailio -dDDE -de -n 2 -m 2048 11 1 root S 2073m 12% 5 0% kamailio -dDDE -de -n 2 -m 2048 7 1 root S 2073m 12% 5 0% kamailio -dDDE -de -n 2 -m 2048 8 1 root S 2073m 12% 2 0% kamailio -dDDE -de -n 2 -m 2048 15 1 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 18 1 root S 2073m 12% 2 0% kamailio -dDDE -de -n 2 -m 2048 26 0 root S 1696 0% 1 0% ash 32 26 root R 1624 0% 0 0% top -d 1
async is not magic. This is why we say it moves the problem around.
-- Alex
As a curiosity, if one were to create an EVAPI client to handle these requests, wouldn't the transaction still need to be stored in shared memory with somewhat similar memory usage?
I'm not quite clear why you keep stating that it's not going to be free. I never claimed it to be. In fact, I've consistently stated that the cost is in shared memory, and I don't see any possible way in which the requests could be processed that is not in shared memory somewhere UNLESS the response time can be addressed.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us [img]https://www.siptrunk.com [img]https://www.flowroute.com
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 3:02 PM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 3:14 pm, Ben Kaufman bkaufman@bcmone.com wrote:
The difference in performance is substantial. Your indication that the performance of the two modules as near equal is incorrect. Both in theory and in practice it is the better of the two options.
If you confine the scope of your evaluation to Kamailio itself, then of course it's substantial; you've deputised the event mux/polling workload into kernel space. While that makes it invisible, it doesn't obviate the clock cycles. I'm talking about formal performance.
This is like saying that Node can handle a tremendous amount of requests with a single process. I suppose it can, but only because it's able to farm out the work of monitoring sockets for data to the OS, and erase it from the ledger, if you like, of userspace costs. They still go somewhere, and that somewhere is constrained by available resources and dimensioning.
Assuming you've used this repo and assets to make your case:
https://github.com/whosgonna/kamailio_http_async
this is not a fair or reasonable comparison. In one case, you're using an external polling loop, and in the other, you're blocking your worker processes by definition. I doubt you could get 3 CPS through that config if the async shvar is set to 0.
Furthermore, the idea of an HTTP service that responds like a metronome in 1 sec, over local sockets and without any of the overhead of connection setup over a real-world network, is so contrived as to be tautological. You've neutered the synchronous approach to the maximum possible extent, while testing the asynchronous one in highly idealised conditions. In fact, tried your repo, followed your instructions on a hex-core server with 16 GB of RAM (2 GB of SHM allocated to Kamailio) and was able to get about 1600 CPS -- more than twice the OP's ask -- before seeing any retransmissions. It's so contrived as to be tautological, as if to say that being rich, young and healthy is better than being old, ill and poor. I cannot agree more.
If you empower the synchronous http_client approach with a comparable degree of parallelism, i.e. a large pool of worker processes with minimum package memory, you'll get comparable throughput. I agree that there are memory limits around that in Kamailio's concurrency model, and that was never in dispute. But you're going to pay it somewhere either way:
Mem: 16175052K used, 217632K free, 266764K shrd, 219644K buff, 10489916K cached CPU: 22% usr 15% sys 0% nic 58% idle 0% io 0% irq 3% sirq Load average: 0.46 0.54 0.45 7/555 32 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 14 1 root R 2076m 12% 3 14% kamailio -dDDE -de -n 2 -m 2048 10 1 root R 2073m 12% 1 3% kamailio -dDDE -de -n 2 -m 2048 9 1 root S 2073m 12% 3 3% kamailio -dDDE -de -n 2 -m 2048 12 1 root S 2073m 12% 0 0% kamailio -dDDE -de -n 2 -m 2048 1 0 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 17 1 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 13 1 root S 2073m 12% 1 0% kamailio -dDDE -de -n 2 -m 2048 16 1 root S 2073m 12% 3 0% kamailio -dDDE -de -n 2 -m 2048 11 1 root S 2073m 12% 5 0% kamailio -dDDE -de -n 2 -m 2048 7 1 root S 2073m 12% 5 0% kamailio -dDDE -de -n 2 -m 2048 8 1 root S 2073m 12% 2 0% kamailio -dDDE -de -n 2 -m 2048 15 1 root S 2073m 12% 4 0% kamailio -dDDE -de -n 2 -m 2048 18 1 root S 2073m 12% 2 0% kamailio -dDDE -de -n 2 -m 2048 26 0 root S 1696 0% 1 0% ash 32 26 root R 1624 0% 0 0% top -d 1
async is not magic. This is why we say it moves the problem around.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
On Dec 23, 2024, at 5:12 pm, Ben Kaufman bkaufman@bcmone.com wrote:
As a curiosity, if one were to create an EVAPI client to handle these requests, wouldn't the transaction still need to be stored in shared memory with somewhat similar memory usage?
Yes.
I'm not quite clear why you keep stating that it's not going to be free. I never claimed it to be. In fact, I've consistently stated that the cost is in shared memory, and I don't see any possible way in which the requests could be processed that is not in shared memory somewhere UNLESS the response time can be addressed.
There is every other cost associated with processing the request, too, although I'll be the first to acknowledge that kernel-side socket polling is massively more efficient, for all sorts of reasons: reduced context switches, optimal data structures for chaining large numbers of file descriptors, etc. But actually reading the data off the socket, and processing it, still happens in the worker.
I think we're talking about two different things:
- You're talking about what's fastest given Kamailio's process constraints (and I am happy to agree with you, and I am also happy to concede that developing a methodology for a rigourous quantitative comparison of the total-system energetics of both approaches would be challenging);
- I'm talking about async not really getting around the fact that HTTP is slow and cumbersome, and so that truly throughput-maximising approaches would get Kamailio out of that business altogether.
Kamailio is a middleware, a kind of Node, and it's architected as such. It's best at facilitating interchange of SIP messages going to and from other places. There is a begrudging need to interact with other services using other protocols, as well, but it should be kept to a minimum and the footprint should be as small as possible for highest performance. HTTP is more like hammering in a nail with a microscope.
-- Alex
On Dec 23, 2024, at 5:23 pm, Alex Balashov abalashov@evaristesys.com wrote:
Kamailio is a middleware, a kind of Node, and it's architected as such. It's best at facilitating interchange of SIP messages going to and from other places. There is a begrudging need to interact with other services using other protocols, as well, but it should be kept to a minimum and the footprint should be as small as possible for highest performance. HTTP is more like hammering in a nail with a microscope.
Or to put it another way: if Kamailio were really designed for doing lots of multiprotocol I/O waiting, or compute, it'd spawn a lot of LWPs and make other architectural choices.
Kamailio is about making SIP go fast, and HTTP is slow. http_async_client is an especially clever workaround and does a) externalise a particularly vexing chunk of the problem, but not the whole problem, and b) there are limits to the payoff of externalising the problem to the kernel on the same host.
To be clear, all network interactions with any services will involve some juggling, but HTTP is especially inefficient here, for reasons previously pointed out in the thread. HTTP/2 would be a laudable improvement.
-- Alex
* I'm talking about async not really getting around the fact that HTTP is slow and cumbersome, and so that truly throughput-maximising approaches would get Kamailio out of that business altogether.
I think we can conclude on that point, as I agree in the general sense. I'm not trying to push Kamailio as a first tier HTTP relay. After all, Kamailio can also handle http requests, and therefore it could be used as a generic http proxy, but I think we can all agree on what a terrible idea that would be. It is my opinion that if planned well, it should be reasonable to create a purpose-driven service where Kamailio makes requests to http servers. But that's just my opinion.
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 4:23 PM To: sr-users@lists.kamailio.org sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 5:12 pm, Ben Kaufman bkaufman@bcmone.com wrote:
As a curiosity, if one were to create an EVAPI client to handle these requests, wouldn't the transaction still need to be stored in shared memory with somewhat similar memory usage?
Yes.
I'm not quite clear why you keep stating that it's not going to be free. I never claimed it to be. In fact, I've consistently stated that the cost is in shared memory, and I don't see any possible way in which the requests could be processed that is not in shared memory somewhere UNLESS the response time can be addressed.
There is every other cost associated with processing the request, too, although I'll be the first to acknowledge that kernel-side socket polling is massively more efficient, for all sorts of reasons: reduced context switches, optimal data structures for chaining large numbers of file descriptors, etc. But actually reading the data off the socket, and processing it, still happens in the worker.
I think we're talking about two different things:
- You're talking about what's fastest given Kamailio's process constraints (and I am happy to agree with you, and I am also happy to concede that developing a methodology for a rigourous quantitative comparison of the total-system energetics of both approaches would be challenging);
- I'm talking about async not really getting around the fact that HTTP is slow and cumbersome, and so that truly throughput-maximising approaches would get Kamailio out of that business altogether.
Kamailio is a middleware, a kind of Node, and it's architected as such. It's best at facilitating interchange of SIP messages going to and from other places. There is a begrudging need to interact with other services using other protocols, as well, but it should be kept to a minimum and the footprint should be as small as possible for highest performance. HTTP is more like hammering in a nail with a microscope.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
On Dec 23, 2024, at 5:37 pm, Ben Kaufman bkaufman@bcmone.com wrote:
It is my opinion that if planned well, it should be reasonable to create a purpose-driven service where Kamailio makes requests to http servers. But that's just my opinion.
Absolutely, we can agree on that, and I wholeheartedly endorse your opinion here.
It's not stated, but I assume you'd have t_suspend() shortly after calling `evapi_async_relay()`?
Kaufman Senior Voice Engineer
E: bkaufman@bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 | Flowroute Client Support: 855.356.9768
[img]https://www.sip.us/ [img]https://www.siptrunk.com/ [img]https://www.flowroute.com/
________________________________ From: Alex Balashov via sr-users sr-users@lists.kamailio.org Sent: Monday, December 23, 2024 10:23 AM To: Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org Cc: Alex Balashov abalashov@evaristesys.com Subject: [SR-Users] Re: Kamailio not receiving packets on high CPS
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Dec 23, 2024, at 10:56 am, Ben Kaufman via sr-users sr-users@lists.kamailio.org wrote:
This came off a bit more harsh than I intended. I think I understand the advantage of EVAPI in that it can initiate a command to Kamailio (thus Kamailio doesn't need to hold the thread, possibly it doesn't need to store the message even), but it would still be nice to have a higher level overview of how this would be achieved. Not even example code, but more a base architecture explanation / diagram of the flow.
It's probably not complicated enough to warrant a diagram.
1) EVAPI server is initialised:
loadmodule "evapi" modparam("evapi", "workers", 3) modparam("evapi", "bind_addr", "xxx:10399")
2) TCP client connects to this socket when it becomes available;
2) Kamailio receives request and serialises it (e.g. JSON), embedding the transaction ID and label in whatever serialisation structure is used, then emits it on the EVAPI bus, e.g.
evapi_async_relay("invite_request:$T(id_index):$T(id_label):$(var(data){s.encode.base64})");
3) TCP client reads this package off the wire; the built-in netstring support is ideal. It then processes it, generates a response, serialises it, and puts it back on the wire. Vitally, the $T(id_index) and $T(id_label) are embedded in the response, allowing Kamailio to resume the transaction:
4) Kamailio receives this message in $evapi(msg), in this event_route, and resumes the transaction into route[RESUME]:
event_route[evapi:message-received] { ... jansson_get("tm_trans.tm_index", "$evapi(msg)", "$var(t_index)"); jansson_get("tm_trans.tm_label", "$evapi(msg)", "$var(t_label)");
t_continue("$var(t_index)", "$var(t_label)", "RESUME");
... }
5) In route[RESUME], INVITE processing continues as normal, enlightened by anything else that was deserialised out of $evapi(msg).
EVAPI is my favourite Kamailio module, and the only way I interface with outside services, when it's up to me.
-- Alex
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristesy...https://evaristesys.com/ Tel: +1-706-510-6800
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!