[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached

 

错误的意思是:已达到可容忍的服务器重连接错误的最大数目。
有两个解决思路:一个将这个值设置的更大;然后是排查自己连接服务哪儿出了问题。
先说在哪儿设置这个值:在拉取nacos服务的注解配置中,添加一个属性maxRetry,这个值源码中默认给的是3,可以将其设置的更大一些。

 1 @Configuration
 2 @EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848", namespace = "xxxxxxxxxxxxxxxxxx", maxRetry = "10"))
 3 @NacosPropertySources({
 4     
 5     @NacosPropertySource(dataId = "url.properties", groupId = "test_group", autoRefreshed = true),
 6 
 7 
 8     @NacosPropertySource(dataId = "db.properties", groupId = "test_group", autoRefreshed = true),
 9 
10     @NacosPropertySource(dataId = "xxl-job.properties", groupId = "test_group", autoRefreshed = true)
11 })
12 public class NacosConfiguration {
13 
14 }

 

nacos-clinent架包中,找到ServerHttpAgent类。
包的全路经:com.alibaba.nacos.client.config.http.ServerHttpAgent
可以看到设置错误的最大连接数目默认值为3,private int maxRetry = 3;

在方法httpGet中,如果出现异常或者没有提前返回,则判断serverListMgr.getIterator().hasNext(),如果为true则使用serverListMgr.getIterator().next()更新currentServerAddr,为false则递减maxRetry,maxRetry=0时则抛出异常[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached

 

  1 /*
  2  * Copyright 1999-2018 Alibaba Group Holding Ltd.
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 package com.alibaba.nacos.client.config.http;
 17 
 18 import com.alibaba.nacos.api.PropertyKeyConst;
 19 import com.alibaba.nacos.api.common.Constants;
 20 import com.alibaba.nacos.api.exception.NacosException;
 21 import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
 22 import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
 23 import com.alibaba.nacos.client.config.impl.ServerListManager;
 24 import com.alibaba.nacos.client.config.impl.SpasAdapter;
 25 import com.alibaba.nacos.client.config.utils.IOUtils;
 26 import com.alibaba.nacos.client.identify.STSConfig;
 27 import com.alibaba.nacos.client.utils.TemplateUtils;
 28 import com.alibaba.nacos.client.utils.JSONUtils;
 29 import com.alibaba.nacos.client.utils.LogUtils;
 30 import com.alibaba.nacos.client.utils.ParamUtil;
 31 import com.alibaba.nacos.client.utils.StringUtils;
 32 import com.fasterxml.jackson.annotation.JsonProperty;
 33 import com.fasterxml.jackson.core.type.TypeReference;
 34 import org.apache.commons.lang3.math.NumberUtils;
 35 import org.slf4j.Logger;
 36 import java.io.IOException;
 37 import java.net.ConnectException;
 38 import java.net.HttpURLConnection;
 39 import java.net.SocketTimeoutException;
 40 import java.net.URL;
 41 import java.util.ArrayList;
 42 import java.util.Date;
 43 import java.util.List;
 44 import java.util.Properties;
 45 import java.util.concurrent.Callable;
 46 
 47 /**
 48  * Server Agent
 49  *
 50  * @author water.lyl
 51  */
 52 public class ServerHttpAgent implements HttpAgent {
 53 
 54     private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class);
 55 
 56     /**
 57      * @param path          相对于web应用根,以/开头
 58      * @param headers
 59      * @param paramValues
 60      * @param encoding
 61      * @param readTimeoutMs
 62      * @return
 63      * @throws IOException
 64      */
 65     @Override
 66     public HttpResult httpGet(String path, List headers, List paramValues, String encoding,
 67                               long readTimeoutMs) throws IOException {
 68         final long endTime = System.currentTimeMillis() + readTimeoutMs;
 69         final boolean isSSL = false;
 70 
 71         String currentServerAddr = serverListMgr.getCurrentServerAddr();
 72         int maxRetry = this.maxRetry;
 73 
 74         do {
 75             try {
 76                 List newHeaders = getSpasHeaders(paramValues);
 77                 if (headers != null) {
 78                     newHeaders.addAll(headers);
 79                 }
 80                 HttpResult result = HttpSimpleClient.httpGet(
 81                     getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
 82                     readTimeoutMs, isSSL);
 83                 if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
 84                     || result.code == HttpURLConnection.HTTP_BAD_GATEWAY
 85                     || result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
 86                     LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
 87                         serverListMgr.getCurrentServerAddr(), result.code);
 88                 } else {
 89                     // Update the currently available server addr
 90                     serverListMgr.updateCurrentServerAddr(currentServerAddr);
 91                     return result;
 92                 }
 93             } catch (ConnectException ce) {
 94                 LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ce.getMessage());
 95             } catch (SocketTimeoutException stoe) {
 96                 LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), stoe.getMessage());
 97             } catch (IOException ioe) {
 98                 LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
 99                 throw ioe;
100             }
101 
102             if (serverListMgr.getIterator().hasNext()) {
103                 currentServerAddr = serverListMgr.getIterator().next();
104             } else {
105                 maxRetry --;
106                 if (maxRetry < 0) {
107                     throw new ConnectException("[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached");
108                 }
109                 serverListMgr.refreshCurrentServerAddr();
110             }
111 
112         } while (System.currentTimeMillis() <= endTime);
113 
114         LOGGER.error("no available server");
115         throw new ConnectException("no available server");
116     }
117 
118     @Override
119     public HttpResult httpPost(String path, List headers, List paramValues, String encoding,
120                                long readTimeoutMs) throws IOException {
121         final long endTime = System.currentTimeMillis() + readTimeoutMs;
122         boolean isSSL = false;
123 
124         String currentServerAddr = serverListMgr.getCurrentServerAddr();
125         int maxRetry = this.maxRetry;
126 
127         do {
128 
129             try {
130                 List newHeaders = getSpasHeaders(paramValues);
131                 if (headers != null) {
132                     newHeaders.addAll(headers);
133                 }
134 
135                 HttpResult result = HttpSimpleClient.httpPost(
136                     getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
137                     readTimeoutMs, isSSL);
138                 if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
139                     || result.code == HttpURLConnection.HTTP_BAD_GATEWAY
140                     || result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
141                     LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
142                         currentServerAddr, result.code);
143                 } else {
144                     // Update the currently available server addr
145                     serverListMgr.updateCurrentServerAddr(currentServerAddr);
146                     return result;
147                 }
148             } catch (ConnectException ce) {
149                 LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, ce.getMessage());
150             } catch (SocketTimeoutException stoe) {
151                 LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, stoe.getMessage());
152             } catch (IOException ioe) {
153                 LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe);
154                 throw ioe;
155             }
156 
157             if (serverListMgr.getIterator().hasNext()) {
158                 currentServerAddr = serverListMgr.getIterator().next();
159             } else {
160                 maxRetry --;
161                 if (maxRetry < 0) {
162                     throw new ConnectException("[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached");
163                 }
164                 serverListMgr.refreshCurrentServerAddr();
165             }
166 
167         } while (System.currentTimeMillis() <= endTime);
168 
169         LOGGER.error("no available server, currentServerAddr : {}", currentServerAddr);
170         throw new ConnectException("no available server, currentServerAddr : " + currentServerAddr);
171     }
172 
173     @Override
174     public HttpResult httpDelete(String path, List headers, List paramValues, String encoding,
175                                  long readTimeoutMs) throws IOException {
176         final long endTime = System.currentTimeMillis() + readTimeoutMs;
177         boolean isSSL = false;
178 
179         String currentServerAddr = serverListMgr.getCurrentServerAddr();
180         int maxRetry = this.maxRetry;
181 
182         do {
183             try {
184                 List newHeaders = getSpasHeaders(paramValues);
185                 if (headers != null) {
186                     newHeaders.addAll(headers);
187                 }
188                 HttpResult result = HttpSimpleClient.httpDelete(
189                     getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
190                     readTimeoutMs, isSSL);
191                 if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
192                     || result.code == HttpURLConnection.HTTP_BAD_GATEWAY
193                     || result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
194                     LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
195                         serverListMgr.getCurrentServerAddr(), result.code);
196                 } else {
197                     // Update the currently available server addr
198                     serverListMgr.updateCurrentServerAddr(currentServerAddr);
199                     return result;
200                 }
201             } catch (ConnectException ce) {
202                 LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ce.getMessage());
203             } catch (SocketTimeoutException stoe) {
204                 LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), stoe.getMessage());
205             } catch (IOException ioe) {
206                 LOGGER.error("[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
207                 throw ioe;
208             }
209 
210             if (serverListMgr.getIterator().hasNext()) {
211                 currentServerAddr = serverListMgr.getIterator().next();
212             } else {
213                 maxRetry --;
214                 if (maxRetry < 0) {
215                     throw new ConnectException("[NACOS HTTP-DELETE] The maximum number of tolerable server reconnection errors has been reached");
216                 }
217                 serverListMgr.refreshCurrentServerAddr();
218             }
219 
220         } while (System.currentTimeMillis() <= endTime);
221 
222         LOGGER.error("no available server");
223         throw new ConnectException("no available server");
224     }
225 
226     private String getUrl(String serverAddr, String relativePath) {
227         return serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
228     }
229 
230     public static String getAppname() {
231         return ParamUtil.getAppName();
232     }
233 
234     public ServerHttpAgent(ServerListManager mgr) {
235         serverListMgr = mgr;
236     }
237 
238     public ServerHttpAgent(ServerListManager mgr, Properties properties) {
239         serverListMgr = mgr;
240         init(properties);
241     }
242 
243     public ServerHttpAgent(Properties properties) throws NacosException {
244         serverListMgr = new ServerListManager(properties);
245         init(properties);
246     }
247 
248     private void init(Properties properties) {
249         initEncode(properties);
250         initAkSk(properties);
251         initMaxRetry(properties);
252     }
253 
254     private void initEncode(Properties properties) {
255         encode = TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENCODE), new Callable() {
256             @Override
257             public String call() throws Exception {
258                 return Constants.ENCODE;
259             }
260         });
261     }
262 
263     private void initAkSk(Properties properties) {
264         String ramRoleName = properties.getProperty(PropertyKeyConst.RAM_ROLE_NAME);
265         if (!StringUtils.isBlank(ramRoleName)) {
266             STSConfig.getInstance().setRamRoleName(ramRoleName);
267         }
268 
269         String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
270         if (StringUtils.isBlank(ak)) {
271             accessKey = SpasAdapter.getAk();
272         } else {
273             accessKey = ak;
274         }
275 
276         String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
277         if (StringUtils.isBlank(sk)) {
278             secretKey = SpasAdapter.getSk();
279         } else {
280             secretKey = sk;
281         }
282     }
283 
284     private void initMaxRetry(Properties properties) {
285         maxRetry = NumberUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.MAX_RETRY)), Constants.MAX_RETRY);
286     }
287 
288     @Override
289     public synchronized void start() throws NacosException {
290         serverListMgr.start();
291     }
292 
293     private List getSpasHeaders(List paramValues) throws IOException {
294         List newHeaders = new ArrayList();
295         // STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
296         if (STSConfig.getInstance().isSTSOn()) {
297             STSCredential sTSCredential = getSTSCredential();
298             accessKey = sTSCredential.accessKeyId;
299             secretKey = sTSCredential.accessKeySecret;
300             newHeaders.add("Spas-SecurityToken");
301             newHeaders.add(sTSCredential.securityToken);
302         }
303 
304         if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
305             newHeaders.add("Spas-AccessKey");
306             newHeaders.add(accessKey);
307             List signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
308             if (signHeaders != null) {
309                 newHeaders.addAll(signHeaders);
310             }
311         }
312         return newHeaders;
313     }
314 
315     private STSCredential getSTSCredential() throws IOException {
316         boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials();
317         if (cacheSecurityCredentials && sTSCredential != null) {
318             long currentTime = System.currentTimeMillis();
319             long expirationTime = sTSCredential.expiration.getTime();
320             int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
321             if (expirationTime - currentTime > timeToRefreshInMillisecond) {
322                 return sTSCredential;
323             }
324         }
325         String stsResponse = getSTSResponse();
326         STSCredential stsCredentialTmp = JSONUtils.deserializeObject(stsResponse,
327             new TypeReference() {
328             });
329         sTSCredential = stsCredentialTmp;
330         LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
331             sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
332         return sTSCredential;
333     }
334 
335     private static String getSTSResponse() throws IOException {
336         String securityCredentials = STSConfig.getInstance().getSecurityCredentials();
337         if (securityCredentials != null) {
338             return securityCredentials;
339         }
340         String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
341         HttpURLConnection conn = null;
342         int respCode;
343         String response;
344         try {
345             conn = (HttpURLConnection) new URL(securityCredentialsUrl).openConnection();
346             conn.setRequestMethod("GET");
347             conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
348             conn.setReadTimeout(1000);
349             conn.connect();
350             respCode = conn.getResponseCode();
351             if (HttpURLConnection.HTTP_OK == respCode) {
352                 response = IOUtils.toString(conn.getInputStream(), Constants.ENCODE);
353             } else {
354                 response = IOUtils.toString(conn.getErrorStream(), Constants.ENCODE);
355             }
356         } catch (IOException e) {
357             LOGGER.error("can not get security credentials", e);
358             throw e;
359         } finally {
360             if (null != conn) {
361                 conn.disconnect();
362             }
363         }
364         if (HttpURLConnection.HTTP_OK == respCode) {
365             return response;
366         }
367         LOGGER.error("can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
368             securityCredentialsUrl, respCode, response);
369         throw new IOException(
370             "can not get security credentials, responseCode: " + respCode + ", response: " + response);
371     }
372 
373     @Override
374     public String getName() {
375         return serverListMgr.getName();
376     }
377 
378     @Override
379     public String getNamespace() {
380         return serverListMgr.getNamespace();
381     }
382 
383     @Override
384     public String getTenant() {
385         return serverListMgr.getTenant();
386     }
387 
388     @Override
389     public String getEncode() {
390         return encode;
391     }
392 
393     @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
394     private static class STSCredential {
395         @JsonProperty(value = "AccessKeyId")
396         private String accessKeyId;
397         @JsonProperty(value = "AccessKeySecret")
398         private String accessKeySecret;
399         @JsonProperty(value = "Expiration")
400         private Date expiration;
401         @JsonProperty(value = "SecurityToken")
402         private String securityToken;
403         @JsonProperty(value = "LastUpdated")
404         private Date lastUpdated;
405         @JsonProperty(value = "Code")
406         private String code;
407 
408         public String getAccessKeyId() {
409             return accessKeyId;
410         }
411 
412         public Date getExpiration() {
413             return expiration;
414         }
415 
416         public Date getLastUpdated() {
417             return lastUpdated;
418         }
419 
420         public String getCode() {
421             return code;
422         }
423 
424         @Override
425         public String toString() {
426             return "STSCredential{" +
427                 "accessKeyId='" + accessKeyId + '\'' +
428                 ", accessKeySecret='" + accessKeySecret + '\'' +
429                 ", expiration=" + expiration +
430                 ", securityToken='" + securityToken + '\'' +
431                 ", lastUpdated=" + lastUpdated +
432                 ", code='" + code + '\'' +
433                 '}';
434         }
435     }
436 
437     private String accessKey;
438     private String secretKey;
439     private String encode;
440     private int maxRetry = 3;
441     private volatile STSCredential sTSCredential;
442     final ServerListManager serverListMgr;
443 
444 }

你可能感兴趣的:([NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached)