DefaultHttpClient调用在具有公共ip的同一tomcat中抛出拒绝的连接



centos 7,tomcat 8.5。

CCD_ 1和CCD_。

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);

然而,如果HttpPost(url)url<public ip>:80,则httpClient.execute(httpPost)将抛出connection refused

而如果a.war1的urllocalhost:80127.0.0.1:80,则httpClient.execute(httpPost)是成功的。

为什么?如何解决这个问题?

注意:如果我在计算机中使用类似http://<public ip>/a的公共ip从浏览器访问a.war,则所有操作都是成功的

我的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. Apachehttpd、nginx或其他反向代理可能处理各种虚拟主机名,也可能处理不同于公共IP的localhost
  4. 端口转发-如果您只将localhost:80转发到localhost:8080(tomcat的默认端口),那么您可能在publicip:80上没有任何转发该流量的东西

评论后编辑:

  1. 传入流量似乎不错,但传出流量确实存在这些问题。从@stringy05的评论中添加:检查有问题的IP是否可以从您的服务器路由:您正在从该服务器连接到任何IP,所以请使用其他方法创建传出连接,例如curl

#1&3:如果连接到外部http服务器,它将根据使用的主机名以不同的方式处理请求。很可能是IP"主机名"被高级防火墙阻止了,或者只是由Web服务器本身以不同于URL的方式处理。在大多数情况下,您可以通过从任何其他系统(例如您自己的浏览器)连接到有问题的Web服务器来进行检查。

如果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等,如以下文章中所述:

  • https://www.garron.me/en/linux/add-secondary-ip-linux.html
  • https://www.thegeekdiary.com/centos-rhel-6-how-to-addremove-additional-ip-addresses-to-a-network-interface/

例如,对于您需要的公共IP地址1.2.3.4(只有在下次重新启动之前才有效,最坏的情况可能会干扰您使用例如SSH连接到服务器的能力!):

sudo ip addr add 1.2.3.4/32 dev lo

有这些命令的输出可能会很有用,以更好地理解您的设置,随时在您的问题中分享,并始终匿名的公共IP地址):

以下任一项(ss=套接字统计,旧netstat的新替代品):

  1. ss-nltp
  2. netstat-nltp

其中之一:

  1. ifconfig
  2. ip地址显示

最后但并非最不重要的一个:

  1. 路线
  2. ip路由

我不认为我们需要知道您的防火墙配置,但如果您使用它,在使用时关注它可能会很有趣:

iptables-L-n-v--行号

尝试将您的公共域名放入服务器的本地/etc/hosts文件中,如下所示:127.0.0.1 localhost YOURPUBLIC.DOMAIN.NAME

这样,您的Java代码就不需要尝试使用外部IP地址,而是直接连接到Tomcat。

祝你好运!

我认为curl超时解释了这一点——你在某个地方有一个防火墙规则,可以阻止服务器访问公共IP地址。

如果没有理由不能使用localhost或本地主机名访问服务,那么就这样做,但如果需要通过公共IP调用服务,那么需要弄清楚为什么请求会从服务器超时。

一些常见的嫌疑人:

  • 服务器可能实际上没有互联网接入-你能rest.war0吗
  • 可能需要一个转发代理-系统管理员会知道这类事情
  • 你的服务器周围的一些基础设施上可能会有IP白名单——想想AWS安全组、负载均衡器IP白名单之类的东西。要解决此问题,您需要知道服务器curl https://canihazip.com/s的公共IP,并将其添加到白名单中

最新更新