簡體   English   中英

DefaultHttpClient 調用在具有公共 ip 的同一個 tomcat 中拋出連接被拒絕

[英]DefaultHttpClient call throws connection refused in the same tomcat with public ip

centos 7,tomcat 8.5。

a.warrest.war在同一個 tomcat 中

a.war使用以下代碼調用rest.war

import org.apache.http.impl.client.DefaultHttpClient;

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");  

StringEntity se = new StringEntity(json.toString());

se.setContentType("text/json");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

httpPost.setEntity(se);

HttpResponse response = httpClient.execute(httpPost);

但是,如果urlHttpPost(url)<public ip>:80 ,然后httpClient.execute(httpPost)將拋出connection refused

而如果urlHttpPost(url)localhost:80127.0.0.1:80 ,然后httpClient.execute(httpPost)是成功。

為什么? 以及如何解決這個問題?

注意:如果我從瀏覽器訪問a.war ,公網ip如http://<public ip>/a在我的電腦上,所有操作都是成功的。

我的 tomcat 連接器是:

<Connector  
            port="80"
                protocol="HTTP/1.1"  
                connectionTimeout="60000" 
                keepAliveTimeout="15000"
                maxKeepAliveRequests="-1"
                maxThreads="1000"  
                minSpareThreads="200"  
                maxSpareThreads="300"
                minProcessors="100" 
                maxProcessors="900" 
                acceptCount="1000" 
                enableLookups="false"
                executor="tomcatThreadPool"
                maxPostSize="-1"
                compression="on"
                compressionMinSize="1024"               
                redirectPort="8443" />

我的服務器沒有域,只有一個公共 IP,它的/etc/hosts是:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

更新了一些在服務器中運行的命令:

ss -nltp

State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                   users:(("rpcbind",pid=643,fd=8))
LISTEN     0      128          *:80                       *:*                   users:(("java",pid=31986,fd=53))
LISTEN     0      128          *:22                       *:*                   users:(("sshd",pid=961,fd=3))
LISTEN     0      1      127.0.0.1:8005                     *:*                   users:(("java",pid=31986,fd=68))
LISTEN     0      128         :::111                     :::*                   users:(("rpcbind",pid=643,fd=11))
LISTEN     0      128         :::22                      :::*                   users:(("sshd",pid=961,fd=4))
LISTEN     0      80          :::3306                    :::*                   users:(("mysqld",pid=1160,fd=19))
netstat -nltp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      643/rpcbind         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      31986/java          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      961/sshd            
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      31986/java          
tcp6       0      0 :::111                  :::*                    LISTEN      643/rpcbind         
tcp6       0      0 :::22                   :::*                    LISTEN      961/sshd            
tcp6       0      0 :::3306                 :::*                    LISTEN      1160/mysqld 
ifconfig

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1396428  bytes 179342662 (171.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1396428  bytes 179342662 (171.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

p2p1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.25  netmask 255.255.255.0  broadcast 192.168.1.255
        ether f8:bc:12:a3:4f:b7  txqueuelen 1000  (Ethernet)
        RX packets 5352432  bytes 3009606926 (2.8 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2839034  bytes 559838396 (533.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: p2p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether f8:bc:12:a3:4f:b7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.25/24 brd 192.168.1.255 scope global noprefixroute dynamic p2p1
       valid_lft 54621sec preferred_lft 54621sec
route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    100    0        0 p2p1
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 p2p1
ip route

default via 192.168.1.1 dev p2p1 proto dhcp metric 100 
192.168.1.0/24 dev p2p1 proto kernel scope link src 192.168.1.25 metric 100
iptables -L -n -v --line-numbers

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

您可能已經配置了以下其中一項:

  1. 防火牆公共 IP 的端口,所以沒有任何東西通過。
  2. Tomcat 可能會綁定一個特定的 IP,例如 localhost(請參閱 tomcat 的 server.xml 中的連接器元素)
  3. Apache httpd、nginx 或其他反向代理可能會處理各種虛擬主機名,而且它們可能會處理與公共 IP 不同的 localhost
  4. 端口轉發 - 如果您只將 localhost:80 轉發到 localhost:8080(tomcat 的默認端口),則在 publicip:80 上可能沒有任何轉發該流量的內容。

在您的評論后編輯:

  1. 傳入流量似乎沒問題,但傳出流量確實存在這些問題。 從@stringy05 的評論中添加:檢查有問題的 IP 是否可以從您的服務器路由:您正在連接到來自該服務器的任何 IP,因此請使用另一種方式創建傳出連接,例如curl

#1 & #3 的解釋:如果您連接到外部 http 服務器,它將根據使用的主機名以不同方式處理請求。 很可能是 IP“主機名”被高級防火牆阻止,或者只是網絡服務器本身對 URL 的處理方式不同。 在大多數情況下,您可以通過從任何其他系統(例如您自己的瀏覽器)連接到相關網絡服務器來檢查這一點。

嘗試將您的公共域名放入服務器的本地 /etc/hosts 文件中,如下所示: 127.0.0.1 localhost YOURPUBLIC.DOMAIN.NAME

這樣您的 Java 代碼就不需要嘗試使用外部 IP 地址,而是直接連接到 Tomcat。

祝你好運!

如果 Tomcat 正在偵聽(綁定)到您的公共 IP 地址,它應該可以工作,但是您的公共 IP 地址可能屬於某個其他設備,例如 SOHO 路由器,那么您的問題與此類似:

https://superuser.com/questions/208710/public-ip-address-answered-by-router-not-internal-web-server-with-port-forwardi

但是如果沒有 DNS 名稱,您不能簡單地向 /etc/hosts 添加一行,但您可以將公共 IP 地址添加到您的網絡接口卡 (NIC) 之一,如 lo(環回)、eth0 等,如以下之一所述這些文章:

例如,您需要使用公共 IP 地址 1.2.3.4(這只會在下次重新啟動之前有效,最壞的情況可能會干擾您使用例如 SSH 連接到服務器的能力!):

sudo ip addr add 1.2.3.4/32 dev lo

讓這些命令的輸出更好地理解您的設置可能很有用,請隨時在您的問題中分享它,並使用始終匿名的公共 IP 地址):

其中之一(ss = socket stat,舊的netstat的新替代品):

  1. ss -nltp
  2. netstat -nltp

其中之一:

  1. 如果配置
  2. ip地址顯示

最后但並非最不重要的其中一項:

  1. 路線
  2. 路由

我不希望我們需要知道您的防火牆配置,但是如果您使用它,那么在您使用它時留意它可能會很有趣:

iptables -L -n -v --line-numbers

我認為 curl 超時解釋了它 - 您在某處有一個防火牆規則阻止服務器訪問公共 IP 地址。

如果沒有理由無法使用 localhost 或本地主機名訪問該服務,那么請執行此操作,但如果您需要通過公共 IP 調用該服務,則需要弄清楚請求從服務器超時的原因。

一些常見的嫌疑人:

  • 服務器實際上可能無法訪問互聯網 - 您可以curl https://www.google.com嗎?
  • 可能需要轉發代理 - 系統管理員會知道這種事情
  • 您的服務器周圍的某些基礎設施上可能存在 IP 白名單 - 想想 AWS 安全組、負載均衡器 IP 白名單之類的事情。 要解決此問題,您需要知道服務器curl https://canihazip.com/s的公共 IP 並將其添加到白名單

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM