`
wqtn22
  • 浏览: 101073 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

异步gen_server进行port访问时性能严重下降的原因和应对方法(五)套接字发送的应对

 
阅读更多

复制前文的应对方法概览:

 

1从大道理上来讲,需要开发者预估一个进程的处理能力,不要向进程投递过多的消息以致于处理不完,如果处理不完,则需要重新设计,将消息分布到多个进程中处理;

2将异步接收消息的进程与调用port(receive_match)的模式的进程分开;

3拆分向port投递命令的过程,由进程来接收port回传的结果,而不是由模块接收;

4不使用port编写的模块,利用nif重新实现一套;

5其它。

 

这里介绍套接字发送的场景。

对于1,这确实是一个使用广泛的大道理,能解决一切,却好像又什么都没有解决,开发者需要不断摸索才能做到,我还在摸索中,所以就再次略过;

对于2,前文已经介绍过思路和优缺点,此处也就不再赘述;

对于3,rabbitmq已经给出了实现范例,我在开发过程中也借用了过来:

rabbit_writer.erl

 

handle_message({send_command, MethodRecord}, State) ->

    ok = internal_send_command_async(MethodRecord, State),

    State;

 

internal_send_command_async(MethodRecord,

                            #wstate{sock      = Sock,

                                    channel   = Channel,

                                    protocol  = Protocol}) ->

    ok = port_cmd(Sock, assemble_frame(Channel, MethodRecord, Protocol)).

internal_send_command_async(MethodRecord, Content,

                            #wstate{sock      = Sock,

                                    channel   = Channel,

                                    frame_max = FrameMax,

                                    protocol  = Protocol}) ->

    ok = send_frames(fun port_cmd/2, Sock, assemble_frames(Channel, MethodRecord, Content, FrameMax, Protocol)).

 

port_cmd(Sock, Data) ->

    true = try rabbit_net:port_command(Sock, Data)

           catch error:Error -> exit({writer, send_failed, Error})

           end,

    ok.

 

rabbit_net.erl

port_command(Sock, Data) when ?IS_SSL(Sock) ->

    case ssl:send(Sock#ssl_socket.ssl, Data) of

        ok              -> self() ! {inet_reply, Sock, ok},

                           true;

        {error, Reason} -> erlang:error(Reason)

    end;

port_command(Sock, Data) when is_port(Sock) ->

    erlang:port_command(Sock, Data).

上述是第一阶段的port_command。

rabbit_writer.erl

 

handle_message({inet_reply, _, ok}, State) ->

    State;

handle_message({inet_reply, _, Status}, _State) ->

    exit({writer, send_failed, Status});

上述是第二阶段的receive过程,其中{inet_reply, Socket, Status}为gen_tcp:send发送命令后,receive到的消息。

套接字发送不存在文件写遇到的2个问题,首先,套接字发送过程的任何错误不会影响进程状态,因为发送者只有在收到应用层的确认时,才会认为消息到达,没有确认则可以认为未到达;其次,套接字接收消息可以通过在连接时使用{active,once/true}选项,令对端的数据直接投递到接收进程内部,而不需要显式调用gen_tcp:recv,也就不存在消息紊乱的问题;

对于4,我目前还没有找到实现,但是由于网络连接随时可以断开,进程也必须收到连接断开的异步通知,因此必须要使用消息机制异步通知进程,因此完全通过nif实现套接字访问是不可接受的,幸运的是,3已经足够解决问题了;

对于5,在通过gen_tcp:connect连接时,可以设置一个选项为delay_send,该选项类似于文件打开的delayed_write选项,在gen_tcp:send进入port_driver时,首先将要写的数据缓存到套接字port的发送缓存中,此时可以令 gen_tcp:send迅速返回,从而加快处理速度,减少进程消息队列堆积量,但该方法终有瓶颈,不能无限制应对消息增加,且为了更好的异步发送性能,需要配合另外一个选项nodelay,但这样会牺牲一部分同步发送性能;

套接字发送的解决方法较少,但是却很实用,向rabbitmq的编写者们致敬!

实际项目开发时,异步服务器的编写会时常碰到,读者们也会遇到这些问题,期待大家更好的解决方法!

分享到:
评论

相关推荐

    异步套接字服务器与客户端

    异步套接字是网络编程中的一个重要概念,它在服务器端和客户端的通信中起着关键作用。在本文中,我们将深入探讨异步套接字的工作原理、优势以及如何在服务器端和客户端实现异步通信。 首先,让我们理解什么是异步套...

    异步套接字网络通信

    套接字是进程间通信(IPC)的一种方式,特别是在网络环境中,它提供了一种标准接口,使得应用程序能够通过IP网络发送和接收数据。套接字分为同步和异步两种类型。同步套接字在执行读写操作时会阻塞,直到操作完成;...

    适合初学者的异步套接字简单实例

    本实例聚焦于异步套接字,这是一种允许程序在等待数据到达时执行其他任务的技术,非常适合处理高并发和实时性的网络应用。下面将详细解释异步套接字的概念、工作原理,并通过"适合初学者的异步套接字简单实例"来阐述...

    异步套接字通信

    而异步套接字则采用事件驱动或回调机制,允许应用程序在等待数据准备就绪时执行其他任务,提高了系统的并发性和响应性。 异步套接字通信的核心原理是基于操作系统提供的异步I/O模型,如Windows上的IOCP(I/O完成...

    异步套接字服务器加客户端

    当有客户端连接时,`AcceptAsync`方法会被触发,返回一个新的套接字用于与客户端进行通信。 3. **连接处理**:服务器通常会为每个连接的客户端创建一个新的线程或任务,以确保并发处理多个客户端连接。异步操作允许...

    异步套接字代码详细解析

    异步套接字编程是网络通信中的重要技术,它允许程序在等待数据传输时执行其他任务,提高了系统资源的利用率和程序的响应速度。本文将深入解析异步套接字的工作原理、API使用以及实现一个简单的异步套接字服务器。 ...

    基于tcp的异步套接字客户端服务端通信

    异步套接字是TCP编程中的一个重要概念,尤其在构建高性能、高并发的服务器时更为关键。下面将详细阐述基于TCP的异步套接字客户端与服务端通信的知识点。 1. **TCP的基础概念** - **连接建立**:TCP通信前需要建立...

    server-and-client.rar_server client_套接字

    在IT行业中,网络通信是至关重要的一个领域,而"server-and-client.rar_server client_套接字"这个压缩包文件显然涉及到的是基于套接字(Socket)的客户端-服务器(Client-Server)通信模型。下面我们将深入探讨这个...

    深入了解异步套接字

    异步套接字是计算机网络编程中的一个重要概念,特别是在Windows平台上,它被广泛应用于高并发、实时性要求较高的网络服务中。MFC(Microsoft Foundation Classes)库为开发者提供了一个便捷的方式来处理异步套接字,...

    线程同步与异步套接字编程

    在计算机编程领域,尤其是网络编程中,线程同步与异步套接字编程是至关重要的概念,它们直接影响到程序的性能、稳定性和可扩展性。本文将深入探讨这两个主题,并结合实际应用进行详细阐述。 首先,我们需要理解线程...

    VC++异步套接字类(AsyncSocket),进行“异步非阻塞”客户/服务器(Client/Server)网络程序设计的方法与原理。

    在IT领域,网络编程是构建分布式系统的关键技术之一,而异步套接字(AsyncSocket)是Microsoft Visual C++提供的一种高效、灵活的工具,用于实现异步非阻塞的客户端和服务器通信。异步非阻塞模式允许程序在等待数据...

    基于C#异步套接字的聊天程序包

    2. **客户端**:通过异步套接字连接到服务器,发送和接收消息。客户端也需要处理网络事件,例如连接状态的变化、消息的发送与接收等。 3. **数据传输协议**:为了保证数据的正确传输,聊天程序通常会定义一套协议,...

    (C#)基于SocketAsyncEventArgs的异步套接字通讯框架

    基于SocketAsyncEventArgs的异步套接字通讯框架 基于SocketAsyncEventArgs的异步套接字通讯框架 基于SocketAsyncEventArgs的异步套接字通讯框架 基于SocketAsyncEventArgs的异步套接字通讯框架

    c#异步/同步多线程套接字

    在C#编程中,异步和同步多线程套接字是网络通信的重要技术,尤其在构建高性能、高并发的应用程序时。本文将详细讲解这些概念,并基于给定的项目文件进行解析。 首先,让我们理解“同步”和“异步”在套接字编程中的...

    基于异步套接字的网络聊天室C++源码

    【基于异步套接字的网络聊天室C++源码】是一个典型的计算机网络编程项目,主要涉及了异步套接字编程技术,用于构建一个可以让多个用户进行实时交流的网络聊天平台。在这个项目中,我们将深入探讨异步套接字的概念、...

    采用异步套接字实现网络聊天的例子(很适合初学者看!!!)

    在计算机网络编程中,套接字(Socket)是网络通信的基本接口,它允许应用程序通过网络发送和接收数据。异步套接字则是套接字的一种高级形式,它提供了非阻塞的I/O操作,使得程序在等待数据传输时可以执行其他任务,...

    Python基于UDP协议的套接字通信,网络编程必看

    套接字是网络通信的基本单元,它可以用来发送和接收数据。下面分别介绍服务端和客户端的实现。 1. 服务端: - 首先,导入socket模块并创建一个UDP套接字对象,使用socket.SOCK_DGRAM指定UDP协议。 - 绑定本地IP...

    易语言同步异步套接字模块

    易语言同步异步套接字模块源码,同步异步套接字模块,Call,取字节集指针,异步客户_初始,异步客户_销毁,异步客户_连接,异步客户_断开,异步客户_发送数据,异步客户_取回数据,异步客户_回调函数,同步客户_初始,同步客户_...

Global site tag (gtag.js) - Google Analytics