【问题标题】:How to configure httpc profiles with rebar3?如何使用 rebar3 配置 httpc 配置文件?
【发布时间】:2017-03-10 12:50:16
【问题描述】:

使用 rebar3 时如何为httpc 的配置文件设置配置选项?

这是唯一一个通过erl -config inets.configexample,看起来像这样:

[{inets, 
[{services,[{httpc,[{profile, server1}]},
            {httpc, [{profile, server2}]}]}]
}].

我尝试在我的 rebar3 项目结构中采用它。

代码

项目是使用 rebar3 创建的,具有标准 OTP 布局:

rebar3 new release myapp

这是我的myapp/config/sys.config

[
  { myapp, []},
  {inets, [{services, [{httpc, [{profile, myapp}]}]}]}
].

rebar.config:

{erl_opts, [debug_info]}.
{deps, []}.

{relx, [{release, { myapp, "0.1.0" },
         [myapp,
          sasl]},

        {sys_config, "./config/sys.config"},
        {vm_args, "./config/vm.args"},

        {dev_mode, true},
        {include_erts, false},

        {extended_start_script, true}]
}.

{profiles, [{prod, [{relx, [{dev_mode, false},
                            {include_erts, true}]}]
            }]
}.

为了完整起见,这是我的myapp.app.src 文件:

{application, myapp,
 [{description, "An OTP application"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, { myapp_app, []}},
  {applications,
   [kernel,
    stdlib
   ]},
  {env,[]},
  {modules, []},

  {maintainers, []},
  {licenses, []},
  {links, []}
 ]}.

请求

这是我试图从 rebar 的外壳发出的请求:

$ ./rebar3 shell
1> ===> Booted myapp
1> ===> Booted sasl
...
1> httpc:request( "http://reddit.com", myapp).
** exception exit: {noproc,
                    {gen_server,call,
                     [httpc_myapp,
                      {request,
                       {request,undefined,<0.88.0>,0,http,
                        {"reddit.com",80},
                        "/",[],get,
                        {http_request_h,undefined,"keep-alive",undefined,
                         undefined,undefined,undefined,undefined,undefined,
                         undefined,...},
                        {[],[]},
                        {http_options,"HTTP/1.1",infinity,true,
                         {essl,[]},
                         undefined,false,infinity,...},
                        "http://reddit.com",[],none,[],1478280329839,
                        undefined,undefined,false}},
                      infinity]}}
     in function  gen_server:call/3 (gen_server.erl, line 212)
     in call from httpc:handle_request/9 (httpc.erl, line 574)

这是没有配置文件的请求,用于检查 inets 是否真正有效:

2> httpc:request( "http://reddit.com").

=PROGRESS REPORT==== 4-Nov-2016::13:25:51 ===
          supervisor: {local,inet_gethost_native_sup}
             started: [{pid,<0.107.0>},{mfa,{inet_gethost_native,init,[[]]}}]

=PROGRESS REPORT==== 4-Nov-2016::13:25:51 ===
          supervisor: {local,kernel_safe_sup}
             started: [{pid,<0.106.0>},
                       {id,inet_gethost_native_sup},
                       {mfargs,{inet_gethost_native,start_link,[]}},
                       {restart_type,temporary},
                       {shutdown,1000},
                       {child_type,worker}]
{ok,{{"HTTP/1.1",200,"OK"},...

【问题讨论】:

  • 请出示您的rebar.config

标签: erlang rebar3


【解决方案1】:

rebar3 本身使用 inets http 客户端,因此当它在 shell 中启动您的应用程序时,inets 已经启动和配置。一种解决方法是在您的应用程序启动之前停止 inets,as It's suggested by rebar3 developer(复制如下)。另一种是在控制台模式下启动您的版本:

./_build/default/rel/myapp/bin/myapp console

除此之外,您的项目还有另一个问题。您还没有告诉过您希望为您启动 inets。您应该在myapp.src 中有这一行:

{applications, [kernel, stdlib, inets]}

或者您可以在rebar.config 发布部分列出 inets,告诉 relx 这个应用应该包含在发布中并在启动时启动。

{relx, [{release, { myapp, "0.1.0" }, [inets, myapp, sasl]} ]}

在 rebar3 shell 启动时阻止 Inets 加载

这是 rebar3 邮件列表中 Fred Hebert 的 full answer 的副本:

我们确实需要 inets 来获取包,并且可能不会将其关闭 自动适用于所有用例,因为这可能会影响一般使用 在用户应用程序不使用 rebar3 代理的情况下 inets,但仍要求在后续运行中获取包。这 我建议的解决方法是为此使用挂钩脚本。钩 脚本在我们启动用户应用程序之前运行并且是常规的 escripts:

#!/usr/bin/env escript 
main(_) -> application:stop(inets). 

然后,您可以将脚本挂接到:

{shell, [{script_file, "path/to/file"}]} 

在 rebar3.config 中,或与

rebar3 shell --script_file test/check_env.escript

【讨论】:

  • 谢谢。你说的对 inets 使用 rebar3 shell 自动启动是对的!做链接中的小技巧会有所帮助。
【解决方案2】:

我在文档中找不到任何建议 rebar.config 可以包含您想要的应用程序配置。

相反,应用程序配置通常保存在应用程序的配置目录中,就像您给出的示例所说,启动erl 时必须使用-config 标志指向配置文件。

如果您为making release 使用rebar3 并通过script made with relx(默认情况下从_build/default/rel/&lt;release_name&gt;/bin/&lt;release_name&gt;)启动您的服务,则应用程序配置文件将传递给您的erl。如果你的应用目录下存在配置文件,默认在config/sys.config,将被视为应用配置,否则为空配置。您可以通过relax' release optionsys_config自定义其路径。

对于我们的软件,我们通常只有一个 config/sys.config 文件。该结构与您提供的配置示例相同。请注意,配置文件可以包含许多不同服务的设置。例如,将 inets 与我们的一个混合:

[{inets, [
     {services,[{httpc,[{profile, server1}]},
     {httpc, [{profile, server2}]}]}
 ]},
 {my_app, [
     {my_setting, "my value"}
 ]}
].

我们以erl -config config/sys.config 启动。 这样,如果我们需要设置服务配置,我们可以简单地更新我们的配置文件,该文件还包含特定于该应用程序的配置。

据我所知,这是正确的使用方法。我找不到支持任何其他方式的文档。

【讨论】:

  • 不知道是谁投了反对票。不好意思,朋友。感谢您的建议,但这不是我想要的。
  • Reith 扩展了答案。也许现在它有更多帮助? (感谢瑞思!)
  • 还是不行。当我尝试使用myapp 配置文件发出httpc:request 时,我收到noproc。我也按照您的建议尝试了独立的 httpc 条目。
  • 你需要使用inets:start().启动inets进程如果你想使用SSL,你还需要做ssl:start().然后你可以发出httpc请求。请注意,如果您将其添加到您的.app 配置文件,这可以自动完成。有关这样做的更多信息,请参阅this StackOverflow question。
  • 问题是 rebar3 shell 自动启动 inets。请参阅已接受的答案。感谢您对此进行调查!
猜你喜欢
  • 2020-05-30
  • 1970-01-01
  • 2018-04-20
  • 2014-10-14
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
相关资源
最近更新 更多