springboot的Httpclient的503和Connection reset异常处理

tech2022-12-03  127

springboot是一个scala编写的rest接口交互,scala的连接是akka 1.503 service unbelievable 解:akka-http-core设置request-timeout = 20 s,太短了。httpclient虽然设置6分钟,时间到了。那边服务不可用 2.Connection reset:连接重试,httpclient本来设置超时是6分钟,每次到一分钟左右就出现这个问题

原因:在 akka-http-core里面,linger-timeout = 1 min,一分钟就超时 解1.linger-timeout设置大一点,最好大于超时时间request-timeout,idle-timeout设置大一点,这里非常重要, 解2.改用http 1.0版本,它是一个短链接,关闭连接,同时也改nginx的配置,超时长一点。idle-timeout设置大一点,这里非常重要,

代码示例

nginx.conf upstream test.local { server 192.168.1.221:26181; }

server { listen 3000; charset utf-8; gzip on; gzip_types application/javascript text/html text/css; client_max_body_size 250m; #access_log /var/log/nginx/log/host.access.log main; location / { root /home/centos/jiangwancheng/visual/dist; try_files $uri /index.html; } location /redpeak { #rewrite ^/hs-api/(.*)$ /$1 break; proxy_pass http://test.local; proxy_connect_timeout 1800s; proxy_send_timeout 1800s; proxy_read_timeout 1800s; } #error_page 404 /static/html/404/404.html; } import com.fasterxml.jackson.core.type.TypeReference; import com.hongshan.visual.common.constant.BdpConstant; import com.hongshan.visual.common.constant.Tips; import com.hongshan.visual.common.exception.VisualException; import com.hongshan.visual.common.model.dto.OperateResultDTO; import com.hongshan.visual.common.model.dto.TenantDTO; import org.apache.commons.lang3.StringUtils; import org.apache.http.*; import org.apache.http.client.HttpClient; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.hongshan.visual.common.constant.BdpConstant.TENANT_ID; /** * http相关的工具类 */ @Component public class HttpUtil { private static final Logger log = LoggerFactory.getLogger(HttpUtil.class); public static String platformUrl; @Value("${platform.url}") public void setPlatformUrl(String url) { platformUrl = url; } /** * 封装url * * @param domain 域名 * @param request 请求 * @param params 参数 * * @return 封装完毕的url */ private static String makeUrl(String domain, String request, Map<String, String> params) { StringBuilder sb = new StringBuilder().append(domain).append(request); if (!params.isEmpty()) { sb.append("?"); for (Map.Entry entry : params.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } sb.delete(sb.length() - 1, sb.length()); } return sb.toString(); } /** * get请求 * * @param domain 域名 * @param request 请求 * @param params 参数 */ public static Map<String, String> doGet(String domain, String request, Map<String, String> params) throws Exception { Map<String, String> res = new HashMap<String, String>(); HttpURLConnection connection = null; BufferedReader br = null; try { String urlStr = makeUrl(domain, request, params); URL url = new URL(urlStr); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); // 设置该连接是可以输出的 connection.setRequestMethod("GET"); // 设置请求方式 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); connection.connect(); int code = connection.getResponseCode(); res.put("code", code + ""); if (code == 200) { br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8")); StringBuilder result = new StringBuilder(); String line; while ((line = br.readLine()) != null) { // 读取数据 result.append(line).append(System.getProperty("line.separator")); } res.put("message", result.toString()); }else { res.put("message", connection.getResponseMessage()); } } catch (Exception e) { throw new Exception(e); } finally { if (connection != null) { connection.disconnect(); } if (br != null) { br.close(); } } return res; } public static String getRestTemplateResult(String uri,String paramName,String jsonStr){ RestTemplate restTemplate = SpringUtil.getRestTemplate(); String url = platformUrl + uri + "?" + paramName + "=" + jsonStr; try { return restTemplate.getForObject(url, String.class); }catch (Exception e){ log.error(Tips.DBP_EXCEPTION + "method:getRestTemplateResult, errMsg:{}",e); throw new VisualException(Tips.DBP_EXCEPTION); } } public static String getRestPlatform(String uri,String parmasStr){ RestTemplate restTemplate = SpringUtil.getRestTemplate(); String url = platformUrl + uri + "?" + parmasStr; if(StringUtils.isEmpty(parmasStr)){ url = platformUrl + uri; } try { return restTemplate.getForObject(url, String.class); }catch (Exception e){ log.error(Tips.DBP_EXCEPTION + " method:getResultByDay,errMsg:{}",e); throw new VisualException(Tips.DBP_EXCEPTION); } } /** * 向目的URL发送post请求 * @param uri 目的uri * @param jsonString 发送的json参数 * @return ResultVO */ public static String postRest(String uri, String jsonString) throws IOException { Map<String, String> httpResMap; try{ httpResMap = doPost(platformUrl, uri, jsonString); }catch (Exception e){ log.error(Tips.DBP_EXCEPTION + " method:postRest,errMsg:{}",e); throw new VisualException(Tips.DBP_EXCEPTION); } if (! httpResMap.get(BdpConstant.CODE_STRING).equals(BdpConstant.SUCCESS_CODE)){ log.error(Tips.DBP_EXCEPTION ); throw new VisualException(httpResMap.get(BdpConstant.CODE_STRING) + ":" +httpResMap.get("message")); } return httpResMap.get("message"); } public static Map<String, String> doPost(String domain, String request, String jsonStr) throws Exception { Map<String, String> res = new HashMap<String, String>(); HttpURLConnection connection = null; BufferedReader br = null; OutputStream os = null; try { String urlStr = domain + request; URL url = new URL(urlStr); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); // 设置该连接是可以输出的 connection.setUseCaches(false); connection.setRequestMethod("POST"); // 设置请求方式 connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); connection.setRequestProperty("Cache-Control", "no-cache"); connection.setRequestProperty("Accept-Encoding", "gzip, deflate,compress"); connection.connect(); connection.setConnectTimeout(6*60*BdpConstant.BASE_TIME_OUT); connection.setReadTimeout(6*60*BdpConstant.BASE_TIME_OUT); os = connection.getOutputStream(); os.write(jsonStr.getBytes("UTF-8")); os.flush(); int code = connection.getResponseCode(); res.put("code", code + ""); if (code == 200) { br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8")); StringBuilder result = new StringBuilder(); String line; while ((line = br.readLine()) != null) { // 读取数据 result.append(line).append(System.getProperty("line.separator")); } res.put("message", result.toString()); return res; }else { res.put("message", connection.getResponseMessage()); } } catch (Exception e) { throw new Exception(e); } finally { if (connection != null) { connection.disconnect(); } if (br != null) { br.close(); } if (os != null) { os.close(); } } return res; } /** * 向目的URL发送post请求 * @param uri 目的uri * @param jsonStr 发送的json参数 * @param readTimeOut 超时 * @return OperateResultDTO 操作返回 */ public static OperateResultDTO debugPost(String uri, String jsonStr, int readTimeOut){ OperateResultDTO dto ; HttpURLConnection connection = null; BufferedReader br = null; OutputStream os = null; try { URL url = new URL(uri); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); connection.setRequestProperty("Cache-Control", "no-cache"); connection.setRequestProperty("Accept-Encoding", "gzip, deflate,compress"); connection.connect(); connection.setConnectTimeout(2000); connection.setReadTimeout(readTimeOut); os = connection.getOutputStream(); os.write(jsonStr.getBytes(StandardCharsets.UTF_8)); os.flush(); int code = connection.getResponseCode(); if (code == 200) { br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); StringBuilder result = new StringBuilder(); String line; while ((line = br.readLine()) != null) { result.append(line).append(System.getProperty("line.separator")); } dto = JsonResult.MAPPER.readValue(result.toString(), new TypeReference<OperateResultDTO>() {}); return dto; }else { dto = new OperateResultDTO(null,1,connection.getResponseMessage()); } } catch (IOException e) { log.error(e.getMessage()); dto = new OperateResultDTO(null,1,e.getMessage()); } finally { if (connection != null) { connection.disconnect(); } close(br); close(os); } return dto; } public static void close(AutoCloseable stream){ if (stream != null) { try { stream.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * @Description: 获取租户信息 * @Param: * @Author: luoliyin * @Date: 2020/4/22 **/ public static List<TenantDTO> getTenant(){ try { String json1 = getRestPlatform(TENANT_ID, null); return JsonResult.MAPPER.readValue(json1, new TypeReference<List<TenantDTO>>() {}); } catch (Exception e) { log.error("获取租户,连接平台异常!"); throw new VisualException("平台正在重启中,请稍后再试!"); } } private static HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { return false; }}; /** * post请求(用于请求json格式的参数) * @param url * @param params * @return */ public static String doPost(String url, String params) throws Exception { HttpClientBuilder custom = HttpClients.custom(); CloseableHttpClient httpclient = custom.setRetryHandler(myRetryHandler).build(); HttpPost httpPost = new HttpPost(platformUrl + url); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-Type", "application/json"); String charSet = "UTF-8"; StringEntity entity = new StringEntity(params, charSet); httpPost.setEntity(entity); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(30*60*BdpConstant.BASE_TIME_OUT) .setSocketTimeout(30*60*BdpConstant.BASE_TIME_OUT) .setConnectionRequestTimeout(30*60*BdpConstant.BASE_TIME_OUT) .build(); httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); httpPost.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); httpPost.setConfig(requestConfig); CloseableHttpResponse response = null; try { response = httpclient.execute(httpPost); StatusLine status = response.getStatusLine(); int state = status.getStatusCode(); if (state == HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); String jsonString = EntityUtils.toString(responseEntity); return jsonString; } else{ log.error("请求返回:"+state+"(" + url + ")" ); throw new VisualException("请求平台异常:"+state); } } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } }
最新回复(0)