【发布时间】:2019-10-18 08:05:35
【问题描述】:
我遇到了 Apache HttpComponents HttpClient 的架构问题。
我们有一个系统,我们有几个不同的远程端点要联系,每个端点都有一些不同的配置,如 ssl、基本身份验证等。
我正在使用 Spring Boot 和 Cloud Sleuth,从中我得到了一个 HttpClientBuilder,它可以为我提供跟踪和其他功能。我想重复使用 那个 HttpClientBuilder,但除此之外添加我自己的特定配置,用于每个唯一的端点。
但问题是 HttpCientBuilder 不是不可变的 withXYZ() 方法,构建器上也没有 copy 或 clone 方法,所以我不能复制原件并仅更改我的特定在不改变基础HttpClientBuilder 的情况下进行更改,并与使用相同构建器实例的其他人发生冲突。无论是线程之间的竞争条件还是不同端点之间的冲突配置。
在 Spring Boot 项目中我看到他们似乎想做类似事情的地方是在 Spring Cloud Commons 的 HttpClientConfiguration 中,它创建了一个自己的 ApacheHttpClientFactory,它采用原始的自动连线 HttpClientBuilder,然后设置 @ 987654332@、disableCookieManagement() 和 useSystemProperties()——但它似乎对 HttpClientBuilder 的原始实例执行了此操作,这对我来说似乎完全错误。它将改变所有已构建的HttpClient 的工作方式,而不仅仅是他们稍后将在HttpClientRibbonConfiguration 或Spring Cloud Netflix Ribbon 的功能区代码中使用的那个。隐藏的潜在错误?对我来说似乎是这样,因为它高度依赖于调用顺序。
有没有人知道如何解决这样的问题?
我可以做的简单替代方法是不要尝试在 Sleuth 给定的HttpClientBuilder 的基础上构建,而是在每次需要时从头开始构建一个全新的,并检查 @987654340 @ bean 可用并在这种情况下使用TracingHttpCientBuilder 而不是HttpClientBuilder,但这似乎违反直觉。
【问题讨论】:
-
为什么要为不同的端点使用不同的 HttpClient 实例?这似乎没有多大意义。
-
@ok2c 不是吗?但它们有不同的 ssl 上下文、BASIC 身份验证等。是否不建议在 HttpClientBuilder 上设置这些设置,而不是尝试为每个请求直接在 HttpClient 上进行操作?
-
这就是
HttpContext的用途。 -
@ok2c 你能解释一下
HttpContext是如何解决问题的吗?HttpContext当然可以为每个请求使用和配置,你总是可以做一些自定义拦截器来处理给定的配置。它可以完成这项工作,但是当您需要多个端点的共享配置时,它并不友好。图片显示您的应用程序与其他 20 个系统通信,并且每个系统使用不同的身份验证协议,您可以期望它们有不同的超时设置。这就是为什么最好有不可变的 HTTP 客户端构建器来为每个系统进行配置。
标签: spring-boot apache-httpclient-4.x apache-httpcomponents