Featured image of post opensips ratelimit模块

opensips ratelimit模块

背景

ratelimit模块用来限制sip请求, 并不是按照源ip来限制,可以根据不同的分组设置,和pike不同.

该模块可以和Redis或者memcache结合, 可以实现集群opensips的统一限制。 另外也可以使用clusterer分布式模块,使用pipe_replication_cluster参数,把pipes复制到其他的实例上。

如果要使用CacheDB发送,就在pipes后加/r, 如果要用clusterer,就在pipes后加/b

支持的算法有:

  • (Tail Drop Algorithm)TAILDROP: 请求达到限制后,后面的请求丢弃
  • (Random Early Detection Algorithm)RED: 随机早期检测算法,测量平均负载并动态调整丢包率
  • (Slot Based Taildropping)SBT: 持有一个或多个slot组成的窗口.
  • NETWORK: 依赖网口上等待消耗的字节数
  • FEEDBACK: 使用PID控制模型, 根据负载因子动态调整下降率.

官方文档地址:ratelimit

本次测试的opensips版本:

version: opensips 3.5.5 (x86_64/linux)

配置参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 定时时间间隔,单位秒,默认:10
modparam("ratelimit", "timer_interval", 5)
# 每个时间间隔的限制数,默认:0(每秒), 1:(每timer_interval)
modparam("ratelimit", "limit_per_interval", 1)
# 多长时间pipe保存在内存中,默认: 3600
modparam("ratelimit", "expire_time", 1800)
# 哈希表大小,默认: 1024
modparam("ratelimit", "hash_size", 512)
# 设置算法, 默认: TAILDROP
modparam("ratelimit", "default_algorithm", "RED")
# 缓存数据库的URL,默认: ""
modparam("ratelimit", "cachedb_url", "redis://root:root@127.0.0.1/")
# 缓存数据库的key前缀,默认: "rl_pipe_"
modparam("ratelimit", "db_prefix", "ratelimit_")

# 设置集群下的发送buffer大小,默认: 32767 bytes
modparam("ratelimit", "repl_buffer_threshold", 500)
# 集群模式下, 发送数据的时间间隔,默认: 200ms
modparam("ratelimit", "repl_timer_interval", 100)
# 集群模式下, 发送数据的过期时间,默认: 10s
modparam("ratelimit", "repl_timer_expire", 10)
# 设置集群id
modparam("ratelimit", "pipe_replication_cluster", 1)
# SBT窗口大小,默认: 10
modparam("ratelimit", "window_size", 5)
# SBT的slot间隔,单位ms。
modparam("ratelimit", "slot_period", 100)

重要函数

rl_check(name, limit[, algorithm])

当前请求和pipe name的算法比较限制数, 如果pipe没有,会根据限制数和算法创建新的,如果算法也没有,使用默认的。

rl_dec_count(name)

减少pipe name当前的计数

rl_reset_count(name)

重置pipe name的当前计数

实战

配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
loadmodule "ratelimit.so"
modparam("ratelimit", "timer_interval", 5)
modparam("ratelimit", "limit_per_interval", 1)
modparam("ratelimit", "expire_time", 1800)
modparam("ratelimit", "default_algorithm", "TAILDROP")

route {
    ...

    if (is_method("INVITE")&&!rl_check("gw_$si", 3)) {
        sl_send_reply(503, "Server Unavailable");
        xlog("L_DBG","-----receive limit-----\n");
        exit; 
    }
    ...
}

为了测试出效果, pipe名字为: gw_$si, 以源ip来测试。

测试

设置的是3个请求/5s, 当并发请求10个/5s,看到的信令图:

sip

可以看到,当达到第6个请求之后,第7个请求就被拒绝了, 之后当计数减少之后,后续还是能再次请求成功。

测试过程中使用opensips-cli -x mi rl_list查看:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
    "Pipes": [
        {
            "id": "gw_172.16.4.113",
            "algorithm": "TAILDROP",
            "limit": 3,
            "counter": 7
        }
    ],
    "drop_rate": 82
}

请求拒绝的信令:

503

总结

  1. opensipsratelimit功能比kamailioratelimit强大, opensips可以使用clusterer模块或者cacheDB实现集群的ratelimit, kamailio不可以。
本博客已稳定运行
发表了45篇文章 · 总计78.36k字
本站总访问量 次 · 您是本站第 位访问者
粤ICP备2025368587号-1| 使用 Hugo 构建
主题 StackJimmy 设计