`
cwqcwk1
  • 浏览: 86905 次
文章分类
社区版块
存档分类
最新评论

erlang R17新socket选项{active,N}

 
阅读更多

erlang R17带来了新的socket选项{active,N} ,与{active,once}一起为应用层提供流量控制。为什么要多了这个选项,{active,once}不是可以有效抑制大量socket消息吗?

我们知道,{active,once}在每次接收到包都要重新设置active选项,才能继续接收erlang的消息通知。实际上,每次设定{active,once}都意味着调用一次epoll_ctl, 如果请求过于频繁,就会有大量的epoll_ctl调用。erlang目前只有一个线程会收割epoll_wait事件,epoll_wait要轮询已经就绪的ctl队列,如果大量的ctl事件将会阻塞了epoll_wait的操作,造成网络处理能力的下降。

那么,我们能不能设定接收N个的socket消息后再执行一次epoll_ctl,这样可以有效减少epoll_ctl的调用,{active,N}就是这样出现的。

下面来看一下{active,N}的说明

Add the {active,N} socket option for TCP, UDP, and SCTP,where N is an integer in the range -32768..32767, to allow acaller to specify the number of data messages to be deliveredto the controlling process. Once the socket's deliveredmessage count either reaches 0 or is explicitly set to 0 withinet:setopts/2 or by including {active,0} as an option whenthe socket is created, the socket transitions to passive({active, false}) mode and the socket's controlling processreceives a message to inform it of the transition. TCPsockets receive {tcp_passive,Socket}, UDP sockets receive{udp_passive,Socket} and SCTP sockets receive{sctp_passive,Socket}.

The socket's delivered message counter defaults to 0, but itcan be set using {active,N} via any gen_tcp, gen_udp, orgen_sctp function that takes socket options as arguments, orvia inet:setopts/2. New N values are added to the socket'scurrent counter value, and negative numbers can be used toreduce the counter value. Specifying a number that wouldcause the socket's counter value to go above 32767 causes aneinval error. If a negative number is specified such that thecounter value would become negative, the socket's countervalue is set to 0 and the socket transitions to passive mode.If the counter value is already 0 and inet:setopts(Socket,[{active,0}]) is specified, the counter value remains at 0but the appropriate passive mode transition message isgenerated for the socket.

设定了{active,N}选项后,进程在接收了N个包后,会收到{tcp_passive, Socket}消息,意味着这个Socket进入被动模式,需要重新设置active选项。

接下来,在实际的例子中测试这个参数:

-module(server).

-export([start/0]).
-export([continue/1]).
-define( PORT, 8888).

start() ->
  {ok, LSock} = gen_tcp:listen(?PORT, [binary, {packet, 0},{active, false}]),
  io:format("socket listen: ~p on ~p ~n",[LSock, ?PORT]),
  accept(LSock).

accept(LSock) ->
  {ok, ASock} = gen_tcp:accept(LSock), 
  Pid = spawn(fun() -> do_loop(ASock) end),
  gen_tcp:controlling_process(ASock, Pid),
  inet:setopts(ASock, [{active, 3}]),
  accept(LSock).

do_loop(ASock) ->
  receive
    {tcp, Socket, Data} ->
       io:format("socket ~p recv: ~p ~n",[Socket, Data]);
    {tcp_closed, Socket} ->
       io:format("socket ~p close ~n",[Socket]);
    {tcp_passive,Socket} ->
       io:format("socket ~p is passive, please call continue/1 ~p ~n",[Socket, self()]);
    release_passive ->
       inet:setopts(ASock, [{active, 3}]);
    Err ->
       io:format("socket may error: ~p ~n",[Err])
  end,
  do_loop(ASock).

continue(Pid) ->
  Pid ! release_passive,
  ok.
编译启动这个模块后,我们创建一个客户端来请求这个服务端:

1> f(S), {ok,S} = gen_tcp:connect({127,0,0,1},8888,[{packet,0}]).
{ok,#Port<0.526>}
2> gen_tcp:send(S,<<"hello">>).
ok
3> gen_tcp:send(S,<<"hello">>).
ok
4> gen_tcp:send(S,<<"hello">>).
ok
5> gen_tcp:send(S,<<"hello">>).
ok
服务端控制台打印了这样的信息:

D:\tmp>erl -s server
socket listen: #Port<0.422> on 8888
Eshell V6.0  (abort with ^G)
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> is passive, please call continue/1 <0.33.0>
1> server:continue(pid(0,33,0)).
socket #Port<0.479> recv: <<"hello">>
ok
2>
在上面的例子中,我们设定了{active,3}的选项,在接收到客户端3次数据后,socket进入了passive状态,在重新设置{active,N}后继续接收tcp消息。

那么,如何在实际项目中运用{active,N}选项?

inet:setopts(Socket, [{active, 300}]),
erlang:send_after(30 * 1000, self(), release_passive);
大概思路是,在30秒内最多接收300个包,超过就不接收,等待这30秒完成后继续接收,如此反复。

利用这点还可以加多一个计数器,如果超过10次进入passive状态,说明这个Socket存在问题,有攻击的行为。


参考:

http://blog.csdn.net/mycwq/article/details/24814843
http://www.erlang.org/download/otp_src_17.0.readme
http://blog.yufeng.info/archives/2970

分享到:
评论

相关推荐

    erlang r17官方api及stdlib手册

    R17是Erlang的一个版本,它包含了对先前版本的改进和新特性。本手册是Erlang R17的官方API及stdlib文档,为开发者提供了详尽的函数介绍和使用指南。 在Erlang的stdlib(标准库)中,你可以找到各种用于处理日常编程...

    Erlang中的socket编程简单例子

    在Erlang中,使用socket进行网络编程是非常重要的基础技能,它可以让我们创建能够处理网络通信的服务器和客户端应用。本文将深入探讨Erlang中的TCP和UDP socket编程,以及如何实现简单的echo服务器和客户端。 首先...

    erlang22最新下载包

    Erlang22是Erlang的第22个主要版本,它包含了对语言特性的改进、性能优化以及一些新的库和工具。 在“erlang22最新下载包”中,提供的文件是`otp_src_22.1`,这表明这是一个源代码包,包含Erlang/OTP(开放电信平台...

    erlang 20.3 最新版本下载

    同时,Erlang的社区活跃且友好,提供了丰富的文档和资源,帮助开发者解决问题和学习新技术。 总而言之,Erlang 20.3是一个关键的版本,尤其对于依赖Erlang环境的项目,如RabbitMQ,它的下载和安装至关重要。通过...

    erlang最新安装包_64位_21.3.rar

    7. **更新维护**:保持Erlang和RabbitMQ的版本更新是很重要的,因为新版本通常包含性能改进和安全修复。 总之,Erlang 21.3版的64位Windows安装包对于RabbitMQ的学习者和开发者来说是至关重要的。它提供了运行和...

    erlang25.0 windows版本

    5. **并发与分布式特性**:Erlang以其强大的并发处理能力著称,新版本可能在进程管理、消息传递等方面有进一步的改进。 6. **编译器升级**:Erlang的BEAM虚拟机和编译器可能会有优化,使得编译速度更快,生成的代码...

    erlang api 最新资源

    当需要增加新的水果类型时,只需简单地增加一个新的模式匹配规则即可,非常便于扩展。 描述中提到的模式匹配和正则表达式是完全不同的概念。在Erlang中,模式匹配是一种控制流结构,而在正则表达式中,表达式用于...

    ERLANG最新版安装包Win64位

    erlang 20.1 安装包Win64、otp_win64_20.1.exe(官网大小:92M) erlang 20.1 安装包Win32、otp_win32_20.1.exe(官网大小:91.12M) 由于上传文件大小限制,目前只放了64位的,各位可以去度娘网盘下载吧 64位下载--...

    erlang编程 Introducing Erlang

    **Erlang编程:Introducing Erlang** Erlang是一种函数式编程语言,由爱立信在1986年开发,主要用于构建高可用性、容错性和并发性的分布式系统。"Introducing Erlang"是Simon St. Laurent撰写的一本入门级教程,...

    erlang_版本24.3.4.4

    3. **编译Erlang**:进入解压后的目录,运行`./configure`命令来配置编译选项。这一步会检测你的系统环境并生成适合的Makefile。 4. **构建和测试**:执行`make`命令开始编译Erlang。这个过程可能需要一些时间,...

    handler socket erlang client

    handlersocket是基于mysql的nosql解决方案,与普通的nosql方案比较,具有更大的灵活性,可以使用mysql的索引。性能相比于mysql的批量操作方式,具有5倍左右的提升(我测试的,可能是内存设置的不多)。...

    Erlang Windows 64位 安装包

    跟随安装向导的提示进行操作,选择合适的安装路径,注意勾选添加Erlang到系统PATH选项,以便于命令行环境下直接调用erl命令。 3. 验证安装:安装完成后,可以在命令行输入"erl"来启动Erlang shell,如果出现Erlang...

    最新最全rabbitmq与erlang版本匹配-2020-04-23.docx

    **RabbitMQ与Erlang版本匹配指南** RabbitMQ是一种广泛使用的开源消息代理和队列服务器,它基于Erlang编程语言构建。Erlang以其并发能力、容错性和分布式特性而闻名,是实现RabbitMQ的理想选择。正确地匹配RabbitMQ...

    erlang9.rar

    安装过程中,你可能会被询问是否要添加Erlang环境变量到PATH,这个选项建议选中,以便在命令行中可以直接使用erl命令。此外,安装路径的选择也很关键,最好选择一个不会频繁变动的位置,以避免日后升级或重装带来的...

    Erlang 20.3linux安装包

    对于Linux系统来说,安装Erlang有多种方法,但推荐使用最新版本,因为新版本通常包含更多的功能增强和安全修复。"Erlang 20.3linux安装包"可能是一个为Linux系统设计的Erlang特定版本的安装包,它包含了所有必要的...

    Erlang/OTP 26.2.1

    Erlang/OTP 26.2.1,Erlang,OTP,26.2.1

    erlang资源

    这个“erlang资源”包含两本PDF书籍——《Erlang并发编程》和《Erlang入门手册》,它们是深入理解和学习Erlang语言的关键资料。 《Erlang并发编程》这本书可能涵盖了以下知识点: 1. **并发模型**:Erlang的并发...

    ErlangB和ErlangC计算工具(exe可执行文件+excel两个)

    Erlang B和Erlang C是电信领域中两种重要的流量模型,用于预测和分析通信系统中的呼叫处理能力和拥塞情况。这两个模型由丹麦工程师Agner Krarup Erlang在20世纪初提出,至今仍广泛应用于现代通信网络的设计与优化。 ...

    rabbitmq,erlang安装包

    21.3是这个版本的编号,意味着这是Erlang OTP的一个特定版本,通常每个新版本会带来性能提升、新功能或者对旧功能的改进。 在安装Erlang之后,就可以安装RabbitMQ了。文件"rabbitmq-server-3.7.14.exe"是RabbitMQ...

    Erlang_B_model.rar_Erlang B _Erlang B model_Wireless Handbook_e

    无线通信手册中的Erlang B查表通常会列出不同C/N比下的B值,使得工程师可以根据已知的话务量和系统容量快速估算出损失率。 在无线通信网络规划中,**Erlang B模型**可以帮助确定所需的最小信道数,以保证在预期的话...

Global site tag (gtag.js) - Google Analytics