- 浏览: 982255 次
- 性别:
- 来自: 广州
最新评论
-
qingchuwudi:
有用,非常感谢!
erlang进程的优先级 -
zfjdiamond:
你好 这条命令 在那里输入??
你们有yum 我有LuaRocks -
simsunny22:
这个是在linux下运行的吧,在window下怎么运行escr ...
escript的高级特性 -
mozhenghua:
http://www.erlang.org/doc/apps/ ...
mnesia 分布协调的几个细节 -
fxltsbl:
A new record of 108000 HTTP req ...
Haproxy 1.4-dev2: barrier of 100k HTTP req/s crossed
见附件的图
但是你仔细看下他的测试方式
What do we measure and how?
We use a 16 node cluster running at SICS. We plot throughput vs. parallel load.
- Machine 1 has a server (Apache or Yaws).
- Machine 2 requests 20 KByte pages from machine 1. It does this in tight a loop requesting a new page as soon as it has received a page from the server. From this we derive a throughput figure, which is plotted in the horizontal scale on the graph. A typical value (800) means the throughput is 800 KBytes/sec.
- Machines 3 to 16 generate load.
Each machine starts a large number of parallel sessions.
Each session makes a very slow request to fetch a one byte file from machine 1. This is done by sending very slow HTTP GET requests (we break up the GET requests and send them character at a time, with about ten seconds between each character)
这个比较是非常不公平的
apache的链接处理机制是 开线程或者进程来处理请求 按它的测试方法 你非常慢速的8w请求 导致apache开大量的线程来处理。而能开多少线程取决于操作系统的能力 这还是其次 大量的线程处理活跃的链接导致大量的thread content switch。 apache 挂了不奇怪。 而erlang的线程相大于c语言的一个数据结构 erl_process你开多少取决于你的内存 大量的但是慢速的链接刚好适合poll事件dispatch, 以epoll的能力(俺测试过epoll30w)能够轻松处理。 这个测试与其说测试web服务器的性能 不如说 测试服务器的进程生成能力。
俺的测试是这样的:../yaws --conf yaws.conf --erlarg "+K true +P 1024000" #epoll 最多1024000个进程 内核都已经调优过
yaws.conf 的内容:
auth_log = false
max_num_cached_files = 8000
max_num_cached_bytes = 6000000
<server test_yaws=""></server>
大家都用 ab -c 1000 -n 1000000 http://192.168.0.98:8000/bomb.gif 来测
果然发现yaws的性能也是非常一般 大概也就是3K左右.
各位看下 strace 的结果就知道了:
accept(10, {sa_family=AF_INET, sin_port=htons(5644), sin_addr=inet_addr("192.168.0.97")}, [16]) = 11fcntl64(11, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(11, F_SETFL, O_RDWR|O_NONBLOCK) = 0
getsockopt(10, SOL_TCP, TCP_NODELAY, [0], [4]) = 0
getsockopt(10, SOL_SOCKET, SO_KEEPALIVE, [0], [4]) = 0
getsockopt(10, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(10, SOL_IP, IP_TOS, [0], [4]) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_IP, IP_TOS, [0], 4) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
setsockopt(11, SOL_IP, IP_TOS, [0], 4) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_TCP, TCP_NODELAY, [0], 4) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
recv(11, "GET /bomb.gif HTTP/1.0\r\nUser-Age"..., 8192, 0) = 100
getpeername(11, {sa_family=AF_INET, sin_port=htons(5644), sin_addr=inet_addr("192.168.0.97")}, [16]) = 0
clock_gettime(CLOCK_MONOTONIC, {110242, 326908594}) = 0
stat64("/var/www/html/bomb.gif", {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
access("/var/www/html/bomb.gif", R_OK) = 0
access("/var/www/html/bomb.gif", W_OK) = 0
clock_gettime(CLOCK_MONOTONIC, {110242, 327135982}) = 0
time(NULL) = 1185894828
clock_gettime(CLOCK_MONOTONIC, {110242, 327222643}) = 0
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=405, ...}) = 0
writev(11, [{NULL, 0}, {"HTTP/1.1 200 OK\r\nConnection: clo"..., 231}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...
, 4096}], 3) = 4327
close(11
这里面充斥着大量的无用的昂贵的系统调用 (至少有20个*10us = 200us 的系统调用是无效的)
对文件的access 2 次 连文件的cache都没有 每次 打开文件 读文件 然后写到socket去 。
这个case是小文件(4k)的情况。 看下大文件(40k)的情况
open("/var/www/html/bomb.gif", O_RDONLY|O_LARGEFILE) = 19
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 7240
read(19, "", 10240) = 0
close(19) = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856508319}) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 11, {0, {u32=11, u64=581990243524149259}}) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 12, {0, {u32=12, u64=581990243524149260}}) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 16, {EPOLLOUT, {u32=16, u64=581990243524149264}}) = 0
epoll_wait(3, {}, 256, 0) = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856677411}) = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856729274}) = 0
大量的epoll_ctl 调用 clock_gettime的调用 足够让系统的速度变的非常慢。
比对下lighttpd的性能。 lighttpd用到了cache,用到了aio,还是完全用c语言小心编写, 他处理小文件大概是并发1w. 而yaws这个的处理方式打个3折我看差不多。
所以请各位大佬介绍erlang的性能时候不要 再用这个apache vs yaws的例子了 误导太多人了.
评论
问题应该出在prim_inet里面.
...
不过你应该不用改动代码,直接使用async_accept/2即可跳过这段.
的确,直接用prim_inet:async_accept/2就没有这些调用了,一次accept变成这样了:
clock_gettime(CLOCK_MONOTONIC, {1293204, 894416432}) = 0 gettimeofday({1185954733, 787267}, NULL) = 0 accept(8, {sa_family=AF_INET, sin_port=htons(37370), sin_addr=inet_addr("127.0.0.1")}, [16]) = 9 fcntl64(9, F_GETFL) = 0x2 (flags O_RDWR) fcntl64(9, F_SETFL, O_RDWR|O_NONBLOCK) = 0 write(0, "Socket #Port<0.122> connected\r\n", 31) = 31 clock_gettime(CLOCK_MONOTONIC, {1293204, 894949432}) = 0 accept(8, 0xbffff1c0, [28]) = -1 EAGAIN (Resource temporarily unavailable) recv(9, 0xb7d03180, 1024, 0) = -1 EAGAIN (Resource temporarily unavailable) clock_gettime(CLOCK_MONOTONIC, {1293204, 895342432}) = 0 epoll_ctl(3, EPOLL_CTL_DEL, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=9, u64=8589934601}}) = 0 epoll_wait(3, {{EPOLLIN, {u32=9, u64=8589934601}}}, 256, 3575743) = 1 clock_gettime(CLOCK_MONOTONIC, {1293232, 316418432}) = 0 gettimeofday({1185954761, 209266}, NULL) = 0 recv(9, "11\r\n", 1024, 0) = 4 clock_gettime(CLOCK_MONOTONIC, {1293232, 316673432}) = 0 epoll_wait(3,
后面一半是prim_inet:recv调用。
不单单是 setsockopt 或者 getsockopt有问题 这个倒好 因为是一次性的开销 毕竟一个连接才做一次你看下clock_gettime epoll_ctl也是无厘头的调用,这也问题不是很大,最大的问题是 read write反复调用这个才是大头 不过这个也可以用delay_send option来避免。所有这个erlang是有很多细节可以微调的,只有把这些问题都处理掉了,性能才会提升。
clock_gettime可能是receive或其它超时参数的负作用吧,虽然没设超时,但它并没有判断后减少这个调用。
上面这个epoll_ctl只是多了个del/add,也还说得过去,毕竟你的接收进程循环就是这么写的,如果你不想再accept,它还是放在epoll里面就多此一举了,增加了不必要的事件,如果不处理这些事件,但又让它停留在epoll里面,epoll_wait总是马上返回,这会让CPU占用非常高的。ACE的多线程reactor在处理一个socket的事件时,也会把这个socket从select/epoll中拿掉,防止多个线程操作同一个socket。这里情况稍有不同,实际上相当于是proactor的实现,需要读时发一个读请求,不需要时就把事件注册给取消掉了。
问题应该出在prim_inet里面.
accept0(L, Time) when port(L), integer(Time) ->
case async_accept(L, Time) of
{ok, Ref} ->
receive
{inet_async, L, Ref, {ok,S}} ->
accept_opts(L, S);
{inet_async, L, Ref, Error} ->
Error
end;
Error -> Error
end.
%% setup options from listen socket on the connected socket
accept_opts(L, S) ->
case getopts(L, [active, nodelay, keepalive, delay_send, priority, tos]) of
{ok, Opts} ->
case setopts(S, Opts) of
ok -> {ok, S};
Error -> close(S), Error
end;
Error ->
close(S), Error
end.
不过你应该不用改动代码,直接使用async_accept/2即可跳过这段.
这个至多是说yaws实现的问题,和Erlang本身无关.
我测试的结果,应该就是erlang底层实现问题,连接建立时都会有这种调用,对于长连接来说这个影响倒并不是很大:
$ strace -p xxxxx -T ..... clock_gettime(CLOCK_MONOTONIC, {1287762, 170939432}) = 0 <0.000008> gettimeofday({1185949291, 63789}, NULL) = 0 <0.000007> accept(8, {sa_family=AF_INET, sin_port=htons(64671), sin_addr=inet_addr("127.0.0.1")}, [16]) = 11 <0.000013> fcntl64(11, F_GETFL) = 0x2 (flags O_RDWR) <0.000008> fcntl64(11, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000008> getsockopt(8, SOL_TCP, TCP_NODELAY, [1], [4]) = 0 <0.000009> getsockopt(8, SOL_SOCKET, SO_KEEPALIVE, [0], [4]) = 0 <0.000009> getsockopt(8, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0 <0.000007> getsockopt(8, SOL_IP, IP_TOS, [0], [4]) = 0 <0.000009> getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0 <0.000008> getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0 <0.000008> setsockopt(11, SOL_IP, IP_TOS, [0], 4) = 0 <0.000008> setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0 <0.000011> getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0 <0.000007> getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0 <0.000008> setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0 <0.000007> getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0 <0.000008> getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0 <0.000008> setsockopt(11, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0 <0.000008> setsockopt(11, SOL_IP, IP_TOS, [0], 4) = 0 <0.000007> setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0 <0.000008> getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0 <0.000007> getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0 <0.000008> setsockopt(11, SOL_TCP, TCP_NODELAY, [1], 4) = 0 <0.000008> setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0 <0.000008> clock_gettime(CLOCK_MONOTONIC, {1287762, 172860432}) = 0 <0.000008> accept(8, 0xbffff1c0, [28]) = -1 EAGAIN (Resource temporarily unavailable) <0.000010> recv(11, 0xb7cfb970, 4, 0) = -1 EAGAIN (Resource temporarily unavailable) <0.000009> clock_gettime(CLOCK_MONOTONIC, {1287762, 173046432}) = 0 <0.000008> clock_gettime(CLOCK_MONOTONIC, {1287762, 173098432}) = 0 <0.000008> epoll_ctl(3, EPOLL_CTL_DEL, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0 <0.000010> epoll_ctl(3, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0 <0.000009> epoll_ctl(3, EPOLL_CTL_ADD, 11, {EPOLLIN, {u32=11, u64=8589934603}}) = 0 <0.000012> epoll_wait(3, {}, 256, 3000) = 0 <2.999371>
我的测试程序是一个进程accept,收到一个就建立一个新进程去recv,上面这个过程就是telnet上去什么也不做抓下来的。
我认为这里是两个问题:
A,以 c 的视角来看 erlang 的网络底层代码,在性能上有进一步提高的空间。profile 结果表明了这一点。
这个帖子实际上有几个问题.
bottle neck定位的问题.mryufeng 用profile 工具dump出来的information,的确有很大的价值.可惜他对bottle neck的定位并不准确.我手上没有什么profile工具,仅凭逻辑上的推断和ultraedit的search基本上可以确定,strace 出来的结果肯定不是Erlang以及OPT本身的问题.
erlang 所有的socket api的封装都是在kernel下的inet module里面,getopts,setopts和recv,send这些函数是分开实现的.erlang底层的代码就没有必要把recv和send里面再加入getopts的代码.有能力设计runtime库的作者都不会犯这种低级错误.
在inet上面opt又封装了一层gentcp.gentcp的recv,send唯一一个多余的操作是去inet_db去lookup Socket.对于正常的anscyn的网络程序管理一个socket queue这点恐怕也是逃不掉的.
那么唯一的那些耗时操作是yaws代码:
%% ret: continue | done
'GET'(CliSock, Req, Head) ->
SC=get(sc),
ok = yaws:setopts(CliSock, [{packet, raw}, binary], is_ssl(SC#sconf.ssl)),
flush(CliSock, Head#headers.content_length),
ARG = make_arg(CliSock, Head, Req, undefined),
handle_request(CliSock, ARG, 0).
这个至多是说yaws实现的问题,和Erlang本身无关.
关于Cache,Yaws的文档Chapter3里面明确写明了是支持Cache的
static content in RAM.The caching behavior is controlled by a number of global configuration directives.
Since the RAM caching occupies memory,it maybe interesting to tweak the default values for the caching
directives or even to turn it off completely.
The following configuration directives control the caching behavior
* max_num_cached_files=Integer YAWS will cache small files such as commonly accessed GIF images
in RAM.This directives ets a maximum number on the number of cached files.The default value is
400.
* max_num_cached_bytes=Integer This directive controls the total amount of RAM which can maxi-
mally be used for cached RAM files.The default value is 1000000,1 mega byte.
* max_size_cached_file=Integer
This directive sets a maximum size on the files that are RAM cached by YAWS . The default value i
8000,8 batters.
It maybe considered to be confusing,but the numbers specified in the above mentioned cache directives
are local to each server.Thus if we have specified max_num_cached_bytes=1000000 and have defined
3 servers,we mayactually use 3*1000000bytes.
我认为这里是两个问题:
A,以 c 的视角来看 erlang 的网络底层代码,在性能上有进一步提高的空间。profile 结果表明了这一点。
B,erlang 在并发/分布的高度复杂问题上提供了目前仅见的统一而且优雅的一揽子解决方案。这似乎是大家的共识。
我想这两个问题之间,并不存在非此即彼的逻辑。
更进一步, mryufeng 有难得的 c 网络编程视角与丰富的实践经验,我建议你继续深入 hack erlang 的源码,从性能角度优化 erlang 这部分 c 代码(比如,将 yaws 的 ab 测试的数据从 c3k 提升到 c100k 的性能水平?)。优化的成果,可以做成 patch 提交到 erlang-patch maillist。
倘若能够如此,将会是为整个 erlang 社区做出的巨大贡献。
用C++最终也能实现出来,只不过最后可能重新实现了一个erlang核心,而且调用界面反而不如erlang美观。。我看C++的各种完成并行计算或分布式的库甚至是编译器扩展,从语法上来看都比较丑陋,代码风格上也截然不同。
C++好像没有一个框架同时支持并发/并行/分布,把几个框架凑到一块的难度也不小。
什么时候向编程语言里加入新概念取决于“创造性扩展原则”:当程序出于技术原因变得过度复杂,但增加的复杂度和要解决的问题无关时,就可以引入新的概念了。引入的新概念应该简化程序。
用C++最终也能实现出来,只不过最后可能重新实现了一个erlang核心,而且调用界面反而不如erlang美观。。我看C++的各种完成并行计算或分布式的库甚至是编译器扩展,从语法上来看都比较丑陋,代码风格上也截然不同。
C++好像没有一个框架同时支持并发/并行/分布,把几个框架凑到一块的难度也不小。
对于Http这种应用一收一发,大不了搞搞Cache,逻辑简单,C++会有优势.但是一旦逻辑复杂起来,比如很多电信应用里面,一个客户端连上来需要数个服务器同时协调提供服务.ACE那种,异步方式处理网络IO的C++框架,处理这种复杂逻辑就非常困难,不但难以调试和扩展,而且本身就会造成性能下降.在可伸缩性上,C/C++ 的实现更无法自然地扩展到集群上去.
说到底,操作系统所谓的Process和Thread 也只不过是一个Context结构,用指针保存每个Stack Frame,然后按时间片切换Context.有任何区别吗?
用最简单的stack_t ,sigaltstack和longjmp 就能做一个最简单的micro thread.
性能方面,俄罗斯的nginx服务器我自己测试下来是现在最快的,静态文件性能有apache2的两倍。有趣的是nginx也支持热配置更新和本身代码热更新,做法和erlang差不多:给master进程发信号说要升级拉,还在工作的worker继续,但别接新任务了等做完再更新,现在发呆着的worker马上更新然后等着去接新任务。
BTW, 楼主要小心别沾染标题党的“必看”恶习呵呵
即使是并发,erlang也不能和C相比,毕竟是C实现的。你自己实现这样一个当然是可以,不过如何把文件、数据库、网络调用都纳入到一个统一的框架中?erlang相当于完成了一个异步调用框架,所有符合它的规范的都可以融为一体,最终形成一个一致的界面。比如一个数据库调用模块,用C NODE方式,为了性能不受网络影响太大,需要使用一个线程池来完成调用。以后该数据库的接口升级了,支持异步调用了,就可以单个线程完成,对于这个C程序来说,修改相对比较小,因为它不面向具体业务。对于erlang来说,调用方式也没有改变,这正是最理想的方式嘛,想了N久没能力搞出来的东西。完全用erlang做项目我目前感觉不是特别必要,看中的是它的分布式和热代码替换。
对了,你上面strace抓的也太恐怖了,这么多重复的调用?很多调用看参数根本都是可以省略的,比如:
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0 getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
有种想扁人的感觉。。
erlang的优势就是高并发而非高性能,性能方面谁敢跟C比,erlang也是C写的内核。
发表评论
-
OTP R14A今天发布了
2010-06-17 14:36 2677以下是这次发布的亮点,没有太大的性能改进, 主要是修理了很多B ... -
R14A实现了EEP31,添加了binary模块
2010-05-21 15:15 3030Erlang的binary数据结构非常强大,而且偏向底层,在作 ... -
如何查看节点的可用句柄数目和已用句柄数
2010-04-08 03:31 4814很多同学在使用erlang的过程中, 碰到了很奇怪的问题, 后 ... -
获取Erlang系统信息的代码片段
2010-04-06 21:49 3475从lib/megaco/src/tcp/megaco_tcp_ ... -
iolist跟list有什么区别?
2010-04-06 20:30 6529看到erlang-china.org上有个 ... -
erlang:send_after和erlang:start_timer的使用解释
2010-04-06 18:31 8386前段时间arksea 同学提出这个问题, 因为文档里面写的很不 ... -
Latest news from the Erlang/OTP team at Ericsson 2010
2010-04-05 19:23 2013参考Talk http://www.erlang-factor ... -
对try 异常 运行的疑问,为什么出现两种结果
2010-04-05 19:22 2842郎咸武<langxianzhe@163.com> ... -
Erlang ERTS Async基础设施
2010-03-19 00:03 2517其实Erts的Async做的很不错的, 相当的完备, 性能又高 ... -
CloudI 0.0.9 Released, A Cloud as an Interface
2010-03-09 22:32 2476基于Erlang的云平台 看了下代码 质量还是不错的 完成了不 ... -
Memory matters - even in Erlang (再次说明了了解内存如何工作的必要性)
2010-03-09 20:26 3439原文地址:http://www.lshift.net/blog ... -
Some simple examples of using Erlang’s XPath implementation
2010-03-08 23:30 2050原文地址 http://www.lshift.net/blog ... -
lcnt 环境搭建
2010-02-26 16:19 2614抄书:otp_doc_html_R13B04/lib/tool ... -
Erlang强大的代码重构工具 tidier
2010-02-25 16:22 2486Jan 29, 2010 We are very happy ... -
[Feb 24 2010] Erlang/OTP R13B04 has been released
2010-02-25 00:31 1387Erlang/OTP R13B04 has been rele ... -
R13B04 Installation
2010-01-28 10:28 1390R13B04后erlang的源码编译为了考虑移植性,就改变了编 ... -
Running tests
2010-01-19 14:51 1486R13B03以后 OTP的模块加入了大量的测试模块,这些模块都 ... -
R13B04在细化Binary heap
2010-01-14 15:11 1508从github otp的更新日志可以清楚的看到otp R13B ... -
R13B03 binary vheap有助减少binary内存压力
2009-11-29 16:07 1668R13B03 binary vheap有助减少binary内存 ... -
erl_nif 扩展erlang的另外一种方法
2009-11-26 01:02 3218我们知道扩展erl有2种方法, driver和port. 这2 ...
相关推荐
Erlang是一种面向并发和分布式系统的语言,以其高可靠性而著称,而Yaws是由Claes Wikström用Erlang编写的高性能Web服务器,能够处理大量并发连接。 首先,Yaws提供了几种处理动态内容和构建REST服务的方式: 1. *...
这是Yaws,是用Erlang编写的动态内容的Web服务器。 准备构建 获取并安装一个Erlang系统( )。 要编译Yaws,需要Erlang / OTP 18.0或更高版本。 如果您已经从github克隆了源代码,并且想使用自动工具进行构建,请...
5. **日志记录和性能监控**:Yaws具有详细的日志记录功能,可以帮助开发者分析和优化服务器性能。同时,它还提供了一套性能监控工具,便于管理员实时掌握服务器状态。 6. **自动压缩**:Yaws可以自动对发送给客户端...
yaws(Yet Another Web Scraper)是一种易于使用但功能强大的Node.js Web抓取工具,它支持多种常用的抓取技术,通过使用带有正则表达式的模式,通过导航DOM(JQuery样式)来定义对象。 它是一个进行中的工作,包括...
yaws-json2 yaws-json2 是来自网络服务器的编码器/解码器。安装在 rebar.config 中: { yaws_json2 , " .* " , { git , " git://github.com/myua/yaws-json2 " , { tag , " master " }}}用法使用yaws_json2:decode_...
随着技术的进步,诸如Nginx、Lighttpd等优秀的基于事件驱动的Web服务器框架,以及Tornado、Django这样的Python非阻塞Web框架,甚至使用Erlang语言编写的Yaws和Cowboy轻量级Web框架,都已经能够很好地解决C10K问题。...
首先,Apache和Internet Information Server (IIS)是市场份额最大的两款Web服务器。Apache是开源的,具有高度可定制性和丰富的模块支持,适用于各种操作系统。IIS则是微软提供的闭源服务器,主要应用于Windows环境,...
在Yaws上启动Web服务、服务静态文件(Serving Static Files)、编译、加载和运行代码以及集群化Yaws(Clustering Yaws)是构建Erlang Web应用的关键步骤。 4. 在构建Web应用时,需要考虑系统架构(System ...
- **编译、加载和运行代码**: 在Web应用中,编译、加载和运行代码是常规操作,Yaws提供了相应的机制来支持这一流程。 - **集群Yaws**: 为了提高Web应用的可用性和负载均衡,Yaws支持集群部署,使多个Yaws实例能够...
Yaws是一个用Erlang编写的高性能Web服务器,它特别适用于处理静态文件的分发、编译和运行Erlang代码、以及在Erlang集群中的应用。使用Yaws,开发者可以轻松地启动一个Web服务,从静态文件服务到动态内容处理,再到...
7. **性能和限制**:虽然`Jinterface`提供了一个方便的桥梁,但跨语言调用的性能相比同语言内部调用会有下降。此外,由于`Erlang`和`Java`的并发模型不同,需要考虑线程安全和资源管理等问题。 8. **优化和实践**:...
标题中的“Erlang-or-java.rar_erlang”表明这是一个关于Erlang和Java之间通信的示例项目。Erlang是一种面向并发、分布式、容错的编程语言,常用于构建高可用性和高并发性的系统,而Java则是一种广泛应用的通用编程...
Erlang有多种库如 cowboy 和 yaws 支持WebSocket,方便实现双向通信。 ### 8. 性能优化与监控 Erlang VM(BEAM)提供了诸如实时垃圾回收和运行时性能监控等工具。开发者可以通过这些工具优化代码性能,确保游戏...
然而,不同的服务器在性能、功能和灵活性方面各有特点,选择哪一款取决于具体项目需求。 总的来说,elli是一个针对HTTP API设计的Erlang Web服务器,它利用Erlang的语言特性提供了高并发、高可用的解决方案。如果你...
5. 应用框架:如Mnesia数据库系统、公共接口服务器(COS)和Web服务器(Yaws或Inets)等,方便开发特定用途的应用。 使用OTP Win64 24.0,开发者可以构建高性能、高并发的系统,同时享受Erlang语言提供的强大并发...
- **C语言**:许多轻量级Web服务器都是用C语言编写的,因为C语言能够提供更好的性能和较低的资源消耗。 - **Erlang**:Erlang是一种适合编写并发程序的语言,因此使用Erlang编写的Web服务器在处理高并发请求时表现...
在IT行业中,Erlang是一种面向并发的编程语言,它被广泛用于构建高可靠性、分布式系统,尤其是在电信和实时计算领域。WebSocket协议则是一种在Web上实现双向通信的协议,它允许服务器和客户端进行持久连接,从而实现...
10. **Web开发**: Erlang可以通过 cowboy、YAWS 等框架进行Web开发,构建高性能的HTTP服务器和API。 总的来说,Erlang OTP 21.0的Windows 64位版本是一个强大的工具,适合构建分布式、高并发和容错的系统,尤其在...