前一段时间我在二郎(从C++/PHP/Java世界中来)非常感兴趣-我已经看到了它在业界已经successfuly使用,通过Ericsson,Facebook,Goldman Sachs,等,所以,我认为这将是一个伟大的平台使用低延迟配置文件构建高要求的应用程序,使用比Java(对我而言)更清晰,更好的语言.
但是在"哇哇效应"消失后,我发现有许多高性能的Java库似乎解决了Erlang理论上最适合的许多问题(实时,低延迟应用,并发,容错等). ).而且,似乎有些东西尽管是Erlang配置文件,但在BEAM上却无法实现(如LMAX Disruptor并发框架).
所以问题出现了:Erlang仍然是建立这样的最佳平台demanding applications吗?如果我们坚持使用一个非常成熟的(J)VM并尝试使用更少的可用资源(OTP团队的大小与JVM团队,支持者等)来实现类似的东西,那会不会更好?是否有可能performance and adoption通过BEAM 实现这种目标?
只是为了说清楚:我不想在这里发起火焰战争.我只是好奇,因为我真的很喜欢Erlang,我认为这是一个很棒的平台,我想投入时间和精力来建立真实的项目.但我想知道其他人可能会说些什么 - 如果我错了 - 也许有人可以纠正我.
我正在尝试使用Apache Beam 0.6.0在GCP上启动数据流作业。我正在使用shade插件编译一个uber jar,因为我无法使用“ mvn:execjava”启动该作业。我包括此依赖项:
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-runners-google-cloud-dataflow-java</artifactId>
<version>0.6.0-SNAPSHOT</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我收到以下异常:
Exception in thread "main" java.lang.IllegalArgumentException: Unknown 'runner' specified 'DataflowRunner', supported pipeline runners [DirectRunner]
at org.apache.beam.sdk.options.PipelineOptionsFactory.parseObjects(PipelineOptionsFactory.java:1609)
at org.apache.beam.sdk.options.PipelineOptionsFactory.access$400(PipelineOptionsFactory.java:104)
at org.apache.beam.sdk.options.PipelineOptionsFactory$Builder.as(PipelineOptionsFactory.java:289)
at com.disney.dtss.desa.tools.SpannerSinkTest.main(SpannerSinkTest.java:116)
Caused by: java.lang.ClassNotFoundException: DataflowRunner
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.apache.beam.sdk.options.PipelineOptionsFactory.parseObjects(PipelineOptionsFactory.java:1595)
Run Code Online (Sandbox Code Playgroud)
我还有其他东西吗?
我们有一个 erlang/elixir 应用程序(在 18/erts 7.3.1 上)可以处理大型 json 负载。??
这是一个典型的工作流程:
侦听器从 rabbitmq 获取令牌并发送到 gen_server。
gen_server 将令牌放入具有未来时间(当前 + n 秒)的 ETS 表中。gen_server 中的计划作业将从 ETS 中获取过期的令牌,并使用这些令牌启动几个短期进程。
这些短暂的进程从elasticsearch(使用hackney)下载30-50k json有效负载并处理它,然后将结果上传回??elasticsearch,然后进程立即终止。我们跟踪这些过程并确认它们已经死亡。我们每秒处理 5-10 个这样的请求。
问题:我们看到一个不断增长的二进制空间,并在 48 小时内增长到几个 GB(通过观察者和调试打印看到)。手动 GC 也没有影响。
我们已经添加了“recon”并运行了 recon:bin_leak,但是这只会释放很少的 KB,对不断增长的二进制空间没有影响。
堆栈:Erlang 18/erts 7.3.1、elixir 1.3.4、hackney 1.4.4、poison 2.2.0、timex 3.1.13 等,这些应用程序也没有占用内存。
过去有没有人遇到过类似的问题?将不胜感激任何解决方案。
2017 年 9 月 15 日更新:
我们更新了我们的应用程序到 Erlang 19/ERTS 8.3 和 hackney 和毒药库到最新,仍然没有任何进展。这是 GenServer 中的一些日志,它使用 spawn/receive 或 send_after 定期向自己发送消息。在每个 handle_info 处,它查找 ets 表,如果找到任何“合格”条目,则生成新进程。如果没有,它只返回一个 {:noreply, state}。我们在函数入口处打印 VM 二进制空间信息(以 KB 为单位),日志列在下面。这是一天中的“安静”时间。可以看到二进制空间逐渐增大。再次 :recon.bin_leak(N) 或 :erlang.garbage_collect() 对这种增长没有影响。
11:40:19.896 [警告] …
是否可以在跟踪中返回堆栈跟踪?我正在使用:dbg.tp/3和:dbg.tracer/2来获取调用模块的跟踪。我尝试了caller函数(参见文档: https: //erlang.org/doc/apps/erts/match_spec.html),但它给了我堆栈中的下一个调用(即{:erl_eval, :do_apply, 6}),我需要的是第一个函数是在我的项目中定义的。
对于上下文,处理函数传递给tracer/2:
handler_fun = fn {:trace, _pid, :call, {_m, _f, _a}, dump}, _ignored ->
IO.puts(dump)
end
Run Code Online (Sandbox Code Playgroud)
和 tp 调用(现在我只使用进程转储,它以二进制形式提供堆栈,但我想以可以在代码中解释而不是解析它的形式获取它):
:dbg.tp(module, :_, [{:_, [], [{:message, {:process_dump}}]}])
Run Code Online (Sandbox Code Playgroud)
我愿意使用与跟踪/dbg 不同的工具。
可以像这样采用引用的Elixir表达式(AST树):
quote do: 1 + 1
=> {:+, [context: Elixir, import: Kernel], [1, 1]}
Run Code Online (Sandbox Code Playgroud)
并将其转换为Erlang AST?
我查看了代码模块以及一些寻找功能的内核模块,但是我找不到任何东西.我甚至不确定这是否可能......我不知道如何在Ellang AST中表示像Elixir宏这样的东西.
提前致谢!
当Erlang VM梁运行一些用C编写的代码时,没有安排用Erlang编写的其他进程.例如:
static ERL_NIF_TERM
nifsleep(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
sleep(10);
return enif_make_atom(env, "ok");
}
Run Code Online (Sandbox Code Playgroud)
当你在Erlang中调用这个C函数时,其他进程没有正常进行schedulling.我想知道为什么?这是一个功能还是受实现限制(也就是说,这是一个错误)?
上面代码的地址是:https://github.com/davisp/sleepy
我在Perl/Python/node中的背景和一些Ruby.我之前没有使用过BEAM VM语言.
在Perl/Python/Node/Ruby中,如果我想处理"较低级别"的任务 - 强烈的计算,需要访问线程,或者更常见的是,包装C库 - 我会用C语言写一些东西.Elixir/Erlang显然有Erlang进程形式的极大并行性和非常低的延迟,消除了大部分需求.
所以如果我有一个C库,最好是制作一个Elixir/Erlang包装器还是重新实现这个功能?
一个非常具体的例子:Elixir/Erlang的TLS使用OpenSSL,还是用BEAM语言实现?
我发现Elixir程序可以通过NIF(本机实现的功能)或OS级别的端口运行C代码.阅读过那些和类似的链接,我不是百分之百地知道何时使用一种或另一种方法(或完全不同的其他方法?),并认为对我自己和其他新手进行直接比较会很好.谁能提供?
我遇到了Erlang OTP + Cowboy应用程序的问题,该应用程序不允许我同时打开足够的文件.
如何更改BEAM中允许的打开文件句柄数?
潜在地,我需要同时打开大约500个小文本文件,但似乎文件限制为224.我从这个小测试程序获得了224的值:
-module(test_fds).
-export([count/0]).
count() -> count(1, []).
count(N, Fds) ->
case file:open(integer_to_list(N), [write]) of
{ok, F} ->
count(N+1, [F| Fds]);
{error, Err} ->
[ file:close(F) || F <- Fds ],
delete(N-1),
{Err, N}
end.
delete(0) -> ok;
delete(N) ->
case file:delete(integer_to_list(N)) of
ok -> ok;
{error, _} -> meh
end,
delete(N-1).
Run Code Online (Sandbox Code Playgroud)
这给了
$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [kernel-poll:false]
Eshell V9.2 (abort with ^G)
1> c(test_fds).
{ok,test_fds}
2> test_fds:count().
{emfile,224}
3> …Run Code Online (Sandbox Code Playgroud)