この記事では、springcloud がリボンをどのように統合するかについて説明します。さまざまな springcloud コンポーネント (feign、zuul、RestTemplate) が異なる方法でリボンを統合します。この記事では、まず RestTemplate について説明します。
RestTemplateのクラス図は以下の通りです
HttpAccessor
は主にClientHttpRequest
を作成しますHttpAccessor
主要根据ClientHttpRequestFactory
创建ClientHttpRequest
InterceptingHttpAccessor
扩展了HttpAccessor
,创建拦截的InterceptingClientHttpRequest
,这里会设置拦截器ClientHttpRequestInterceptor
,这是集成ribbon的核心,当RestTemplate
发起http请求调用的时候,会先经过拦截器,然后才真正发起http请求。
拦截器ClientHttpRequestInterceptor
是如何被设置的呢?在LoadBalancerAutoConfiguration
类中,有如下代码:
@LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList();
只要加入注解@LoadBalanced
的RestTemplate
会被注入,在没有引入spring retry组件的时候,加载如下配置:
@Configuration @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") static class LoadBalancerInterceptorConfig { @Bean public LoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) { return new LoadBalancerInterceptor(loadBalancerClient, requestFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final LoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } }
这样RestTemplate
就被设置了LoadBalancerInterceptor,下面来看看整个调用过程
整个过程有点复杂,核心就是经过拦截器LoadBalancerInterceptor,通过RibbonLoadBalancerClient发起负载均衡调用。RibbonLoadBalancerClientI组合了LoadBalancer,所以具备了负载均衡的能力,也就是我们在上一篇文章解读的ribbon原理。
图中我们没有画出真正发起http请求的过程,其默认是由SimpleClientHttpRequestFactory
创建,ClientHttpRequestFactory
的类图如下:
从调用时序图上我们看到,开始我们调用的是InterceptingClientHttpRequestFactory
来获取InterceptingClientHttpRequest
,它们通过组合的方式集成了ClientHttpRequestFactory
和拦截器,InterceptingClientHttpRequest
发起调用的时候委托了其内部类InterceptingRequestExecution
去处理,核心逻辑:
@Override public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException { if (this.iterator.hasNext()) { ClientHttpRequestInterceptor nextInterceptor = this.iterator.next(); return nextInterceptor.intercept(request, body, this); }else { ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod()); for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) { List<String> values = entry.getValue(); for (String value : values) { delegate.getHeaders().add(entry.getKey(), value); } } if (body.length > 0) { StreamUtils.copy(body, delegate.getBody()); } return delegate.execute(); } }
首先会先取出拦截器集合的第一个执行,当拦截器执行完成后,会回调回来,执行else的代码,真正发起http请求,主要有两种方式实现ClientHttpRequestFactory
接口:
一种是
SimpleClientHttpRequestFactory
,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接一种方式是使用
HttpComponentsClientHttpRequestFactory
方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection,默认超时为-1,可以这样设置超时时间:
@Bean @LoadBalanced public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(1000 * 2);//连接超时时间 factory.setReadTimeout(1000 * 1);//读超时时间 return new RestTemplate(factory); }
使用HttpComponentsClientHttpRequestFactory
方式可以使用连接池(推荐) ,还可以设置重试策略(具体没有研究过)
如果想开启重试机制,我们可以引入spring的retry组件
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>版本号</version> </dependency>
这样springcloud-ribbon就会加重如下配置:
@Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryAutoConfiguration { @Bean public RetryTemplate retryTemplate() { RetryTemplate template = new RetryTemplate(); template.setThrowLastExceptionOnExhausted(true); return template; } @Bean @ConditionalOnMissingBean public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory() { return new LoadBalancedRetryPolicyFactory.NeverRetryFactory(); } } @Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryInterceptorAutoConfiguration { @Bean @ConditionalOnMissingBean public RetryLoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties, LoadBalancedRetryPolicyFactory lbRetryPolicyFactory, LoadBalancerRequestFactory requestFactory) { return new RetryLoadBalancerInterceptor(loadBalancerClient, properties, lbRetryPolicyFactory, requestFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final RetryLoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } }
@Bean @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") @ConditionalOnMissingBean public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) { return new RibbonLoadBalancedRetryPolicyFactory(clientFactory); }
拦截器替换成RetryLoadBalancerInterceptor
了,这里集成了retry组件retryTemplate。重试策略由RetryHandler
接口来配置,默认实现类DefaultLoadBalancerRetryHandler
,如下为默认的配置参数
#最大的重试次数 ribbon.MaxAutoRetries=0 #最大重试server的个数 ribbon.MaxAutoRetriesNextServer=1 #是否开启任何异常都重试(默认在get请求下会重试,其他情况不会重试,除非设置为true) ribbon.OkToRetryOnAllOperations=false #指定重试的http状态码 ribbon.retryableStatusCodes=500,501
以上是对全局生效,如果加上xxx.ribbon.MaxAutoRetries=1
InterceptingHttpAccessor
HttpAccessor
を拡張して、インターセプトされた InterceptingClientHttpRequest
を作成します。ここで、インターセプター ClientHttpRequestInterceptor
が設定されます。これは、統合リボン When RestTemplate
は http リクエストの呼び出しを開始します。最初にインターセプターを通過し、次に実際に http リクエストを開始します。
ClientHttpRequestInterceptor
はどのように設定されますか? LoadBalancerAutoConfiguration
クラスには、次のコードがあります: rrreee 注釈 @LoadBalanced
が追加されている限り、RestTemplate
が挿入されます。 Spring Retry コンポーネントを導入せずに、次の設定をロードします: rrreee
RestTemplate
が LoadBalancerInterceptor に設定されます🎜🎜
SimpleClientHttpRequestFactory
によって作成されます。ClientHttpRequestFactory
のクラス図は次のとおりです。 
InterceptingClientHttpRequestFactory
を呼び出して、 を統合した <code>InterceptingClientHttpRequest
を取得したことがわかります。 ClientHttpRequestFactory は とインターセプターの組み合わせにより、 InterceptingClientHttpRequest
が呼び出しを開始すると、その内部クラス InterceptingRequestExecution
に処理を委託します。 🎜rrreee🎜 は最初に実行します。インターセプター コレクションの出力 最初の実行では、インターセプターが完了するとコールバックし、else コードが実行され、実際に http リクエストが開始されます。 ClientHttpRequestFactory
インターフェイスを実装するには、主に 2 つの方法があります。 🎜🎜 1 つは SimpleClientHttpRequestFactory です。J2SE によって提供されるメソッド (java.net パッケージによって提供されるメソッド) を使用して、基礎となる Http リクエスト接続を作成します🎜🎜🎜 1 つの方法は、 HttpComponentsClientHttpRequestFactory
メソッドでは、最下層は HttpClient を使用してリモート Http サービスにアクセスし、接続プール、証明書、その他の情報を構成できます。 🎜🎜 RestTemplate はデフォルトで SimpleClientHttpRequestFactory を使用し、デフォルトのタイムアウトは -1 です。 🎜rrreee🎜 HttpComponentsClientHttpRequestFactory
を使用します。 > メソッド. 接続プール (推奨)、再試行戦略を設定することもできます (具体的には検討していません) 🎜🎜再試行メカニズムを有効にしたい場合は、Spring の再試行コンポーネントを導入できます🎜rrreee🎜 このように、springcloud-ribbon は追加します。次の構成:🎜rrreeerrreee🎜 インターセプターは RetryLoadBalancerInterceptor
に置き換えられ、再試行コンポーネント retryTemplate が統合されています。再試行戦略は、RetryHandler
インターフェースによって構成されます。デフォルトの実装クラスは、DefaultLoadBalancerRetryHandler
です。上記は、 の場合にグローバルに有効です。 >xxx が追加されました .ribbon.MaxAutoRetries=1
これは、特定のリボン クライアントでのみ有効になります。 MaxAutoRetries と MaxAutoRetriesNextServer を併用すると、各サーバーの最大再試行回数が MaxAutoRetries=1 および MaxAutoRetriesNextServer=1 に設定されている場合、トリガーされる最大再試行回数は 4 回になります。 🎜🎜関連記事: 🎜🎜🎜🎜Java の例 - 配列からコレクションへ🎜🎜以上がspringcloudコンポーネントのRestTemplateで統合されたリボンの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要整理了Stream流的概念和使用的相关问题,包括了Stream流的概念、Stream流的获取、Stream流的常用方法等等内容,下面一起来看一下,希望对大家有帮助。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

WebStorm Mac版
便利なJavaScript開発ツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ホットトピック



