首页 > 解决方案 > DefaultHttpClient 调用在具有公共 ip 的同一个 tomcat 中引发连接被拒绝

问题描述

centos 7,tomcat 8.5。

a.war并且rest.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);

但是,如果urlofHttpPost(url)<public ip>:80httpClient.execute(httpPost)则将抛出connection refused

而 if urlofHttpPost(url)localhost:80or 127.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         

标签: javalinuxresttomcat

解决方案


您可能已经配置了以下之一:

  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 的方式处理。在大多数情况下,您可以通过从任何其他系统(例如您自己的浏览器)连接到有问题的网络服务器来检查这一点。


推荐阅读