转载自 https://www.cnblogs.com/jimw/p/9037542.html

现在公司项目基本都从臃肿的项目转换成微服务的方向转换,因此也从中使用了spring clound的一些组件,在此过程中就遇到了restTemplate的坑。

起初,是直接注入RestTemplate,后来则不断的遇到错误日志无法请求,出现异常。

异常信息:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for IP

意思是说url必须是服务的名称,猜测应该是涉及到eureka,直接用ip跟url调用是直接报错的。

因此不适用默认的,直接重新自定义,则引用了原有的注入修改一下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/**

 *

 * 功能描述:

 *

 * @作者 jimw 创建时间:2018-04

 *

 */

@Configuration

public class RestTemplateConfig {

    public RestTemplate restTemplate() {

        return new RestTemplate(getClientHttpRequestFactory());

    }

    /**

     * 配置HttpClient超时时间

     *

     * @return

     */

    private ClientHttpRequestFactory getClientHttpRequestFactory() {

        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_SOCKET_TIMEOUT)

                .setConnectTimeout(HTTP_CONNECT_TIMEOUT).build();

        CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();

        return new HttpComponentsClientHttpRequestFactory(client);

    }

    /** http请求socket连接超时时间,毫秒为单位 */

    public static final int HTTP_SOCKET_TIMEOUT = 15000;

    /** http请求连接超时时间,毫秒为单位 */

    public static final int HTTP_CONNECT_TIMEOUT = 15000;

}

  

当配置了这个之后,服务正常了。观察了一段时间,发现在并发的高峰期,开多几个服务器负载,也会存在服务出现请求非常慢,导致接口出现阻塞的情况出现,经过分析

1、出现阻塞的原因是因为高峰并发的时候,出现请求的链接数很大

因此找了源码,发现是因为restTemplate的默认配置值小于请求的链接数,而且路由并发也是默认为5的,因为微服务之间的逻辑处理中也有一定的时间。出现大规模阻塞的坑就这么踩到了。

对代码改造一下,配置最大链接数,路由并发数,这个restTemplate的坑就这么解决了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

package com.jingbei.guess.config.web;

import java.security.KeyManagementException;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;

import javax.net.ssl.SSLContext;

import org.apache.http.client.HttpClient;

import org.apache.http.config.Registry;

import org.apache.http.config.RegistryBuilder;

import org.apache.http.conn.socket.ConnectionSocketFactory;

import org.apache.http.conn.socket.PlainConnectionSocketFactory;

import org.apache.http.conn.ssl.NoopHostnameVerifier;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;

import org.apache.http.conn.ssl.SSLContextBuilder;

import org.apache.http.conn.ssl.TrustStrategy;

import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;

import org.apache.http.impl.client.HttpClientBuilder;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

import org.springframework.web.client.DefaultResponseErrorHandler;

import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;

/**

 *

 * 功能描述:

 *

 * @作者 jimw 创建时间: 2018-04

 *

 */

@Slf4j

@Configuration

public class RestTemplateConfig {

    @Bean

    public RestTemplate restTemplate() {

        RestTemplate restTemplate = new RestTemplate();

        restTemplate.setRequestFactory(clientHttpRequestFactory());

        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());

        return restTemplate;

    }

    @Bean

    public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {

        try {

            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(nullnew TrustStrategy() {

                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

                    return true;

                }

            }).build();

            httpClientBuilder.setSSLContext(sslContext);

            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,

                    hostnameVerifier);

            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()

                    .register("http", PlainConnectionSocketFactory.getSocketFactory())

                    .register("https", sslConnectionSocketFactory).build();// 注册http和https请求

            // 开始设置连接池

            PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(

                    socketFactoryRegistry);

            poolingHttpClientConnectionManager.setMaxTotal(2700); // 最大连接数2700

            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100); // 同路由并发数100

            httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);

            httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3true)); // 重试次数

            HttpClient httpClient = httpClientBuilder.build();

            HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(

                    httpClient); // httpClient连接配置

            clientHttpRequestFactory.setConnectTimeout(20000); // 连接超时

            clientHttpRequestFactory.setReadTimeout(30000); // 数据读取超时时间

            clientHttpRequestFactory.setConnectionRequestTimeout(20000); // 连接不够用的等待时间

            return clientHttpRequestFactory;

        catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {

            log.error("初始化HTTP连接池出错", e);

        }

        return null;

    }

}

  在对应的插件中配置即可

依赖包:

<dependency>

<groupId>org.apache.httpcomponents</groupId>

<artifactId>httpclient</artifactId>

<version>4.5.3</version>

</dependency>

<dependency>

<groupId>org.apache.httpcomponents</groupId>

<artifactId>httpcore</artifactId>

<version>4.4.9</version>

</dependency>

restTemplate踩过的坑-spring clound--cloud内部服务调用重试次数相关推荐

  1. 通过Feign实现Spring Cloud微服务调用

    我们在上一篇文章通过restTemplate实现Spring cloud微服务的调用中介绍了spring cloud微服务的一种调用方式,本文我们介绍另一种调用spring cloud微服务的方式-- ...

  2. spring cloud 微服务调用--ribbon和feign调用

    这里介绍ribbon和feign调用两种通信服务调用方式,同时介绍如何引入第三方服务调用.案例包括了ribbon负载均衡和hystrix熔断--服务降级的处理,以及feign声明式服务调用.例子包括s ...

  3. Spring boot 内部服务调用 (FeignClient)

    Eureka 注册的服务之间互相调用 1.请求方 启动类添加注解,扫描Eureka 中的全部服务 @SpringBootApplication @EnableEurekaClient @EnableF ...

  4. (十四)Alian 的 Spring Cloud 订单服务调用自动生成的API

    目录 一.背景 二.maven依赖 三.主要编码 3.1.控制层 3.2.服务层 3.3.dto 3.4.主类 四.配置 4.1.bootstrap.properties 4.2.build.prop ...

  5. Spring Cloud 微服务架构全链路实践

    阅读目录: 1. 网关请求流程 2. Eureka 服务治理 3. Config 配置中心 4. Hystrix 监控 5. 服务调用链路 6. ELK 日志链路 7. 统一格式返回 Java 微服务 ...

  6. Spring Cloud微服务笔记(四)客户端负载均衡:Spring Cloud Ribbon

    客户端负载均衡:Spring Cloud Ribbon 一.负载均衡概念 负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容.因为负载均衡对系统的高可用性. 网络压力的缓解和处理能力的扩容的 ...

  7. Spring Cloud 微服务技术栈

    Spring Cloud 简介 主要内容 微服务简介 SpringCloud 简介 SpringCloud 框架结构 SpringCloud 和 Dubbo 的对比 SpringCloud 版本号说明 ...

  8. 放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结

    Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多. 在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的.从 ...

  9. com 组件调用不起来_Spring Cloud Alibaba训练营 —— 分布式服务调用

    注意:用手机查看排版可能不太友好, 1. 简介 在<Spring Cloud Alibaba 服务注册与发现>篇中曾提到,Spring Cloud Alibaba Nacos Discov ...

最新文章

  1. iOS开发之设计模式篇
  2. FishC01 讲:我和 Python 第一次亲密接触
  3. python renames_Python os.renames() 方法
  4. php lamp环境搭建,lamp环境搭建 --lnmp环境搭建_无需整理
  5. CentOS7 搭建Ambari-Server,安装Hadoop集群(一)
  6. js 字符串编码与解码
  7. nohup的程序能不能再转到前台查看啊?_小程序开发之路入门
  8. 使用Intent Filter来响应隐式Intent
  9. python替换文本文件单词_Python:如何替换文本文件中一行的最后一个单词?
  10. 怎样用java抽签小程序,可以作弊的抽签小程序,急求java抽签小程序
  11. 用python给表格加边框_python如何设置表格边框
  12. 分享:微信淘宝客自动查券找券返利机器人实现的原理和思路
  13. 小白入门之HTML--第五章 块状元素,行内元素,盒子模型
  14. 分析案例:贷款逾期分析
  15. 如何查看mysql的gtid_mode_配置MHA开启主从同步的时候会提示从库gtid_mode为ON的状态...
  16. PEEKABOO——alpha冲刺置顶集合随笔
  17. 魔兽争霸游戏开始前数据包分析
  18. Swift游戏实战-跑酷熊猫 07 平台的移动
  19. xstream 对象 -》xml
  20. java爬虫系列(二)——爬取动态网页

热门文章

  1. python3爬虫(8)爬虫框架scrapy安装和使用
  2. C++虚继承(一) --- vtordisp字段
  3. Windows服务编写综述
  4. static_cast, dynamic_cast, const_cast学习和探讨
  5. Scrapy中的get_project_settings 读取设置文件
  6. 分布式事务科普(初识篇)
  7. 50 种不同编程语言的“Hello World”,你知多少?
  8. Linux(CentOS)中常用软件安装,使用及异常——XManager, 中文支持,JDK
  9. 收官蓉城,展望2019多媒体技术新方向(内附资料下载)
  10. 腾讯数平精准推荐 | 横扫ICDAR 2019,斩获七项冠军