restTemplate踩过的坑-spring clound

java>spring 专栏收录该内容
63 篇文章 0 订阅

现在公司项目基本都从臃肿的项目转换成微服务的方向转换,因此也从中使用了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>

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

An active internet connection Java 8+ Docker Maven Git client Chapter 1, Introduction to Microservices, will introduce you to the microservices architecture, cloud environment, etc. You will learn the difference between a microservice based application and a monolith application while also learning how to migrate to a microservices application. Chapter 2, Spring for Microservices, will introduce you Spring Boot framework. You will learn how to effictively use it to create microservice application. We will cover such topics like creating REST API using Spring MVC annotations, providing API documentation using Swagger2, and exposing health checks and metrics using Spring Boot Actuator endpoints. Chapter 3, Spring Cloud Overview, will provide a short description of the main projects being a part of Spring Cloud. It will focus on describing the main patterns implemented by Spring Cloud and assigning them to the particular projects. Chapter 4, Service Discovery, will describe a service discovery pattern with Spring Cloud Netflix Eureka. You will learn how to run Eureka server in standalone mode and how to run multiple server instances with peer-to-peer replication. You will also learn how to enable discovery on the client side and register these clients in different zones. Chapter 5, Distributed Configuration with Spring Cloud Config, will describe how use distributed configuration with Spring Cloud Config in your applications. You will learn how to enable different backend repositories of property sources and push change notifications using Spring Cloud Bus. We will compare discovery first bootstrap and config first bootstrap approaches to illustrate integration between discovery service and configuration server. Chapter 6, Communication Between Microservices, will describe the most important elements taking a part in an inter-service communication: HTTP clients and load balancers. You will learn how to use Spring RestTemplate, Ribbon, and Feign clients with or without
©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值