3

这是一个非常简单的模块,它会不断检查请求者的 IP。我使用反向连接代理,这意味着它会在每个 http 请求上获得新的 IP。

defmodule Test do
  def go() do
    Enum.each(1..1, fn x ->
    Task.Supervisor.async_nolink(Scraper.TaskSupervisor, fn ->
      r = HTTPoison.get("https://api.ipify.org?format=json", [],
        [timeout: 10_000, recv_timeout: 10_000, proxy: "ip:port", ssl: [{:versions, [:'tlsv1.2']}]])

      case r do

        {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
          IO.inspect body |> Jason.decode
          :timer.sleep(1000)
          go()
      end
    end)
    end)

  end
end
Test.go()
:timer.sleep(2000000)

问题?只要进程处于活动状态,HTTPoison(hackney) 就不会释放连接,因此 IP 始终相同。我将如何手动关闭内部的连接:

{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
          IO.inspect body |> Jason.decode
4

2 回答 2

2

HTTPoison自述文件:

通常hackney会 按需打开和关闭连接,但它也会创建一个默认连接池,这些连接池可重复用于对同一主机的请求。如果连接和主机支持 keepalive,则连接将保持打开状态,直到显式关闭。

HTTPoison不会close为底层套接字导出 ,并且自 2017 年以来存在一个未解决的问题。

同时,您可能会调用hackney_pool:stop_pool(:default). 无论如何,这显然不是最佳解决方案,而且开销很大。所以我的建议是要么提供一个拉取请求以HTTPoison启用关闭连接功能(通过委托给;hackney_response.close/1,要么干脆摆脱冗余HTTPoison并只使用hackney.

于 2019-03-18T06:17:50.057 回答
2

最简单的解决方案原来是设置pool: false,整个请求看起来像:

HTTPoison.get(url, [], [
  timeout: 5_000,
  recv_timeout: 5_000,
  proxy: proxy,
  hackney: [pool: false],
  ssl: [{:versions, [:'tlsv1.2']}]
])
于 2019-03-18T19:34:20.610 回答