某种情况下造成服务器发送消息无比延迟的原因

大家好!小弟最近在学习erlang,熟悉代码做了一个消息转发的server,但是在测试性能的时候遇到一个问题,请教各位,是哪里的问题,谢谢! 

我开发的消息转发server的功能: 
Aclient Bclient都连入Server,都并加入一个组C,Aclient向C组发一条消息,Server负责将消息发给C组内除了A外的其他Client,也就是B。开发没用OTP这些高级东西。SOCKET使用二进制,{active true},{packet 2}. 

消息Server的设计: 
有一个独立的进程负责监听client连入,当有新的client连入会为client申请独立的进程(client_recv process)负责接受这个client发来的消息,有一个独立的进程(group_manager process)维护分组和组的client成员列表,每个组(group process)有一个独立进程负责向组内的client转发消息。 

当Aclient连入server,就会为A启动(client_recv process)负责接受A发来的消息并通过进程通信告诉给group_manager来建立一个组group。Bclient连入操作和A一样,都会加入同一个组。 
当A发消息给SERVER要求把消息给组的其他成员时,client_recv通过进程通讯将消息给group进程,group进程便利组的成员列表将消息转发。 

在测试性能时遇到的问题: 
测试的时候A向SERVER发送100W的消息,用了8秒就发完了,并自动退出了,消息内容都一样,在内网做的测试。 
而SERVER通过tcpdump监听,确实也是在8秒把所有消息都收完了,不在有来自A的消息进入,但是SERVER向B转发消息用了很长时间,超过10分钟,最后我结束进程了。 

在程序内做了打印来判断程序的运行流程,发现SERVER一直执行从client_recv接受A的消息并给group来转发。 

请问是我设计的有问题造成消息转发很慢吗?还是由于进程间通讯造成的?有什么办法可以调优? 

(以下只节选该作者出问题的代码,注意循环后面的那个ok原子)

72.group(Client)->%%负责组的消息群发的进程   
73.    ?DEBUG("group \r\n",[]),   
74.    receive   
75.        {join,Socket,ClientName,CPid} ->   
76.            ?DEBUG("group ClientName ~s\r\n",[ClientName]),   
77.            ?DEBUG("group Client set ~w\r\n",[Client]),   
78.            case lists:keysearch(ClientName,#client.name,Client) of   
79.                false->   
80.                    ?DEBUG("group new client\r\n",[]),   
81.                    ClientNew = #client{name=ClientName,pid=CPid,socket=Socket},   
82.                    ClientTmp = [ClientNew|Client],   
83.                    group(ClientTmp);   
84.                {value,SingleClient}->   
85.                    ?DEBUG("group client is set ~s\r\n",[SingleClient#client.name]),   
86.                    group(Client)   
87.            end;   
88.        {send,ClientName,Msg}->   
89.            ?DEBUG("group recv client send ~s\r\n",[Msg]),   
90.            lists:foreach(fun(T)->send(ClientName,T,Msg) end,Client),   
91.            group(Client)   
92.    end,   
93.    ok.   


 

以下是高手的招数

1.你的send不是很高效,gen_tcp:send是会阻塞的,如果客户很慢,缓冲区已满就会阻塞,把TCP_OPTIONS加上{delay_send, true}测试一下有没有提高。

 

2.既然瓶颈在CPU上,还是使用fprof分析一下吧,测试可以减少到100-1000次

最容易出现的问题是receive匹配顺序,或者是没有匹配到,建议加一个任意匹配检查一下是否有没有匹配的消息

 

3.建议把receive里面加上_Any匹配一下,打印输出或者是exit都可以,没有匹配的消息对性能影响特别大,特别是你这里大量消息的情况。

 

4.感谢qiezi的帮忙!
代码的group下去掉一个无用ok,在server和client增加了tcp属性的设置{nodelay, false}, {delay_send, true},100W的数据在本地单机跑大概用40秒,迅驰1.7 1.5G内存的笔记本上。比以前快多了,谢谢qiezi一直在帮助,学到以前没了解的东西。

在我测试用的服务器上依然出现SERVER端CPU占用99%导致发消息慢的情况。感觉可能是服务器设置或erlang安装造成的问题,因为即使把代码放到同一机器走127.0.0.1的时候一样会出现cpu占满的情况的。

我在安装erlang的时候记得提示 没有java odbc libgd好像没别的库少了,各位还有别的办法吗?谢谢!

 

5.1. 你最初的代码没有设置client socket的options,不知后来有没有改过。
2. 安装erlang时有没有enable-kernel-poll? 运行server时有没有加 +K true选项? kernel poll对提高性能作用很大。

 

6.使用+K true了
我发现是我安装的时候没有disable smp,我的服务器是单核的。
执行shell的时候 -smp disable后 cpu运转还是99%但是运行速度已经升上来了,100w的数据 A服务器发SERVER SERVER转发B服务器 A服务器发送完用5秒,B服务器收完用11秒,消息内容长度1bytes,78bytes发8秒,收21秒。

可是CPU占用依然高,总是瞬间99%,这个问题各位有办法解决吗?
cpu占用到99%这应该算不正常吧?

7.CPU占用率高是肯定的。楼主能否说下目前的tcp选项?erlang邮件列表中建议你使用{active,once} 代替{active,true},您有试过吗?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux下架设代理服务器 bye2000 一、代理服务器概述 1.1什么是代理服务器 在TCP/IP网络中,传统的通信过程是这样的:客户端向服务器请求数据,服务器响应该 请求,将数据传送给客户端。在引入了代理服务器以后,这一过程变成了这样:客户端 向服务器发起请求,该请求被送到代理服务器;代理服务器分析该请求,先查看自己缓 存中是否有请求数据,如果有就直接传送给客户端,如果没有就代替客户端向该服务器 发出请求。服务器响应以后,代理服务器将响应的数据传送给客户端,同时在自己的缓 存中保留一份该数据的拷贝。这样,再有客户端请求一样的数据时,代理服务器就可以 直接将数据传送给客户端,而不需要再向该服务器发起请求。 1.2 代理服务器的功能 一般说来,代理服务器具有以下的功能: 1.通过缓存增加访问速度 随着Internet的迅猛发展,网络带宽变得越来越珍贵。所以为了提高访问速度,好多IS P都提供代理服务器,通过代理服务器的缓存功能来加快网络的访问速度。一般说来,大 多数的代理服务器都支持 缓存,但是,有的代理服务器也支持FTP缓存。在选择代理服务器时,对于大多数的组织 ,只需要 缓存功能就足够了。 通常,缓存有主动缓存被动缓存之分。所谓被动缓存,指的是代理服务器只在客户端请 求数据时才将服务器返回的数据进行缓存,如果数据过期了,又有客户端请求一样数据 时,代理服务器又必须重新发起新的数据请求,在将响应数据传送给客户端时又进行新 的缓存。所谓主动缓存,就是代理服务器不断地检查缓存中的数据,一旦有数据过期, 则代理服务器主动发起新的数据请求来更新数据。这样,当有客户端请求该数据时就会 大大缩短响应时间。还需要说明的是,对于数据中的认证信息,大多数的代理服务器都 不会进行缓存的。 2.提供用私有IP访问Internet的方法 IP地址是不可再生的宝贵资源,假如你只有有限的IP地址,但是需要提供整个组织的In ternet访问能力,那么,你可以通过使用代理服务器来实现这一点。 3.提高网络的安全性 这一点是很明显的,如果部用户访问Internet都是通过代理服务器,那么,代理服务器 就成为进入Internet的唯一通道;反过来说,代理服务器也是Internet访问部网的唯一 通道,如果你没有做反向代理,则对于Internet上的主机来说,你的整个部网只有代理 服务器是可见的,从而大大增强了网络的安全性。 1.3 代理服务器的分类与特点 通常的代理服务器分类方法,是从实现的机理分为线路层代理、应用层代理、智能线路 层代理等等。在这里,我想从另外一个角度出发,把代理服务器分为传统代理服务器和 透明代理服务器。 我认为有必要好好搞清楚两者的区别,只有真正明白了在地机理,才能在遇到问题时, 有章可循,才不会一头雾水,不知从何解决问题。因此,下面我们就通过具体的实例来 说明。本章的写作思路来源于Paul Russell所写的IPCHAINS- HOWTO。下面所举的例子也来源于该文章,我觉得我读该文的最大收获在于对部网访问外 部网以与外部网访问部网的实现手段有了一个清晰的认识。当然,这里所谓的部网是指 使用私有IP的部网络。 我们的例子都基于以下假设: 你的域名为sample.,你的部网(192.168.1.*)用户通过proxy.sample.(外部接口 eth0:1 .2.3.4;部接口 eth1:192.168.1.1)的代理服务器访问Internet,换句话说,该代理服务 器是唯一一台直接与Internet和部网相连的机器。并假该设代理服务器上运行着某种代 理服务器软件(如squid)。假设部网中某一客户机为client.sample.(192.168.1.100)。 +-------------------+ "部网(192.168.1.*)" eth1+--------+eth0 DDN " +------------" proxy "<===============>;Internet "client198.168.1.100" +--------+ +-------------------+ eth0: 1.2.3.4 eth1: 198.168.1.1 1.3.1传统代理 在以上基础上我们做以下工作: 1.代理服务软件被绑定到代理服务器的8080端口。 2.客户端浏览器被配置使用代理服务器的8080端口。 3.客户端不需要配置DNS。 4.代理服务器上需要配置代理服务器。 5.客户端不需要配置缺省路由。 当我们在客户端浏览器中打开一个web请求,比如".linuxaid..cn",这时将陆续发生以 下事件: 1.客户端使用某一端口(比如1025)连接代理服务器8080端口,请求web页面".linuxaid ..cn" 2.代理
### 回答1: 浏览器在以下情况下可能不会发送图片请求: 1. 图片已经被缓存,浏览器会直接从缓存中加载图片而不发送请求。 2. 图片的链接错误或者图片不存在,浏览器会放弃发送请求。 3. 网络连接异常或者服务器出现错误,导致浏览器无法发送请求。 4. 浏览器的安全设置拦截了图片请求,例如浏览器禁止加载非安全来源的图片等。 5. 用户手动取消了图片请求,例如在图片还未加载完成时主动刷新页面或者关闭了页面等。 ### 回答2: 浏览器在以下情况下可能不会发送图片请求: 1. 图片请求已经被浏览器缓存:浏览器会对经常访问的图片进行缓存,如果之前已经请求过并且没有过期,浏览器会直接从缓存中获取图片,而不会再发送请求。 2. 图片链接错误或无效:如果在页面中引用的图片链接错误或者无效,浏览器将无法加载该图片,因此也不会发送请求。 3. 图片加载被用户取消:在图片加载过程中,如果用户手动取消了图片加载或者禁用了图片加载功能,浏览器将不会发送该图片的请求。 4. 图片请求被服务器拒绝:有时服务器可能会限制对特定图片资源的访问,例如通过IP地址屏蔽或者需要进行身份验证等,这时浏览器发送的图片请求可能会被服务器拒绝。 5. 图片请求被浏览器阻止:浏览器在某些情况下会对图片请求进行安全性检查,如果发现请求的图片存在恶意行为或者违反浏览器的安全规定,浏览器会阻止发送该请求。 总之,浏览器不会发送图片请求情况主要涉及缓存、链接错误、用户取消加载、服务器限制和浏览器安全性检查等方面。 ### 回答3: 在以下情况下,浏览器可能不会发送图片请求: 1. 用户设置了浏览器的图像加载选项为“不显示图片”或“仅显示文本”,此时浏览器不会主动发送图片请求,而只会加载网页的文本内容。 2. 当网页代码中没有包含图片标签或没有正确的图片URL时,浏览器无法获取图片的地址,因此也就无法发送图片请求。 3. 网络连接异常或服务器故障时,浏览器无法正常与服务器通信,因此无法发送图片请求。 4. 图片请求被网页设计者手动禁止。有时,网页设计者可能会使用特定的技术手段(如JavaScript代码)来阻止浏览器发送图片请求,以达到某种特定的设计目的。 5. 浏览器在缓存中找到了该图片的副本,并且判断缓存的图片版本是最新的,那么它可以直接从缓存中读取图片,而不需要发送图片请求。 需要注意的是,根据浏览器的不同,具体的情况会有所不同。以上只是一些常见的情况,实际情况可能因浏览器版本、用户设置、网页设计等因素而有所差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值