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.war
1的url
是localhost:80
或127.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
您可能已经配置了其中一个:
- 防火墙公共IP的端口,这样就不会有任何东西通过
- Tomcat可以绑定特定的IP,例如localhost(请参阅Tomcat的server.xml中的连接器元素)
- Apachehttpd、nginx或其他反向代理可能处理各种虚拟主机名,也可能处理不同于公共IP的localhost
- 端口转发-如果您只将localhost:80转发到localhost:8080(tomcat的默认端口),那么您可能在publicip:80上没有任何转发该流量的东西
评论后编辑:
- 传入流量似乎不错,但传出流量确实存在这些问题。从@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的新替代品):
- ss-nltp
- netstat-nltp
其中之一:
- ifconfig
- ip地址显示
最后但并非最不重要的一个:
- 路线
- ip路由
我不认为我们需要知道您的防火墙配置,但如果您使用它,在使用时关注它可能会很有趣:
iptables-L-n-v--行号
尝试将您的公共域名放入服务器的本地/etc/hosts文件中,如下所示:127.0.0.1 localhost YOURPUBLIC.DOMAIN.NAME
这样,您的Java代码就不需要尝试使用外部IP地址,而是直接连接到Tomcat。
祝你好运!
我认为curl超时解释了这一点——你在某个地方有一个防火墙规则,可以阻止服务器访问公共IP地址。
如果没有理由不能使用localhost或本地主机名访问服务,那么就这样做,但如果需要通过公共IP调用服务,那么需要弄清楚为什么请求会从服务器超时。
一些常见的嫌疑人:
- 服务器可能实际上没有互联网接入-你能
rest.war
0吗 - 可能需要一个转发代理-系统管理员会知道这类事情
- 你的服务器周围的一些基础设施上可能会有IP白名单——想想AWS安全组、负载均衡器IP白名单之类的东西。要解决此问题,您需要知道服务器
curl https://canihazip.com/s
的公共IP,并将其添加到白名单中