@IDE: Eclipse
@Language: Java
@Elasticsearch
问题描述:
今天在写一个接口去连接ES的时候出现了怎么都连接不上的情况,系统扔出HttpHostConnectException,并且给出的信息是:connect time out. 经过打断点,发现问题出在这一行代码上:
CloseableHttpResponse response = httpClient.execute(post);
我尝试了以下办法:
(1)延长timeout的时间--failed
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(50000).setConnectionRequestTimeout(10000)
.setSocketTimeout(50000).build();
post.setConfig(requestConfig);
.setConnectTimeout(50000).setConnectionRequestTimeout(10000)
.setSocketTimeout(50000).build();
post.setConfig(requestConfig);
(2)关闭本地的防火墙 -- failed
在认真检查了代码的逻辑顺序和应该设置的属性后仍然没有发现问题。然后无意间尝试了一下连接别的服务器,发现成功了。
于是觉得可能是要连接的服务器防火墙规则的问题
用Xshell登陆平台查看防火墙:iptables -nvL
并添加以下防火墙规则,允许accept 外部对9200端口的访问 :iptables -I INPUT -p tcp --dport 9200 -j ACCEPT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1472 88108 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:9200
这次就能连接成功了。所以根本原因是远程服务器防火墙规则没通过,于是被拒绝了
106K 8495K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
有关CloseableHttpClient 的代码如下:
String ip = Environment.GetProperty("env.SERVER_IP");//获取ip地址
String id = ID+i; String indexUri = String.format(curl_insert_es_cmd_templ,ip,index_name,type_name,id);//change @timestamp
String newTime = newTimeStamp(getNextDay(date));
String jsonContent = record.replace("\"@timestamp\":\"tochange\"","\"@timestamp\":\""+ newTime+"T00:03:57.184+0800\"");//要插入的数据CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(indexUri);//要插入带参数的数据,所以用HttpPost
RequestConfig requestConfig = RequestConfig.custom()//set timeout
.setConnectTimeout(5000)
.setConnectionRequestTimeout(1000)
.setSocketTimeout(5000).build();
post.setConfig(requestConfig);
StringEntity stringEntity=null;
stringEntity = new StringEntity(jsonContent,"UTF-8");
post.setEntity(stringEntity);
CloseableHttpResponse response = httpClient.execute(post);
PS: 之前连接ES的时候用的是ssh,那个是直接登陆了服务器,然后在localhost上执行命令,所以就不会被拒绝
但是利用CloseableHttpClient是外部连接端口,所以不行
English Version
@IDE: Eclipse
@Language: Java
@Elasticsearch
Describe problems:
These days I am working on implementing an interface to connect ES while inserting data at the same time. But the connection always fails because of HttpHostConnectException. The information showing in the console is : connect time out.
After degugging, I found there is some problem in the following code:
CloseableHttpResponse response = httpClient.execute(post);
In this case, I have tried different ways to solve it:
(1) extend the time out period -- but failed anyway
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(50000).setConnectionRequestTimeout(10000)
.setSocketTimeout(50000).build();
post.setConfig(requestConfig);
.setConnectTimeout(50000).setConnectionRequestTimeout(10000)
.setSocketTimeout(50000).build();
post.setConfig(requestConfig);
(2) turn off local firewall -- but failed again
Then I try to connect another server(different ip address), it works!
And I guess that the problem can be caused by the server's firewall rules.
I then login the platform with Xshell and use command: iptables -nvL
There is no rule to accept port 9200!!!! -- Get the point!!!!
The server will refuse connection to 9200 in this case:
106K 8495K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
So, just alter the rule!
Adding a rule like this: iptables -I INPUT -p tcp --dport 9200 -j ACCEPT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1472 88108 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:9200
Succeed!
Here is my code to connect the ES with CloseableHttpClient:
String ip = Environment.GetProperty("env.SERVER_IP");
String id = ID+i; String indexUri = String.format(curl_insert_es_cmd_templ,ip,index_name,type_name,id);
//change @timestamp
String newTime = newTimeStamp(getNextDay(date));
String jsonContent = record.replace("\"@timestamp\":\"tochange\"","\"@timestamp\":\""+ newTime+"T00:03:57.184+0800\"");
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(indexUri);
RequestConfig requestConfig = RequestConfig.custom()//set timeout
.setConnectTimeout(5000)
.setConnectionRequestTimeout(1000)
.setSocketTimeout(5000).build();
post.setConfig(requestConfig);
StringEntity stringEntity=null;
stringEntity = new StringEntity(jsonContent,"UTF-8");
post.setEntity(stringEntity);
CloseableHttpResponse response = httpClient.execute(post);
PS: I used to connect ES using ssh, but that is a different case. ssh is to login server and then execute commands in localhost which commands will not be refused. However, using CloseableHttpClient is to connect port 9200 from outside.