我看过Spring Tips:使用Spring Framework 5.0的功能反应端点,并阅读了一些关于spring reactor的内容,但我无法理解它.
鉴于我有netty和spring reactor有效,让端点返回Flux/ Mono实例(jacksonified)而不是直接dto对象(jacksonified)有什么好处?我最初假设在http请求/响应上下文中,反应流将更像是websockets,其中服务器通过开放通道将数据推送到接收器,但似乎并非如此.
另外netty在反应式编程中实际上比tomcat做得更好?
如果这些问题看起来很愚蠢,我很抱歉,但我不太明白这个新框架方向的目的.它为什么会出现,它是如何工作的以及它解决了哪些问题?
spring reactive-programming netty project-reactor spring-webflux
我无法理解在构建WebClient请求时我做错了什么.我想了解实际的HTTP请求是什么样的.(例如,将原始请求转储到控制台)
POST /rest/json/send HTTP/1.1
Host: emailapi.dynect.net
Cache-Control: no-cache
Postman-Token: 93e70432-2566-7627-6e08-e2bcf8d1ffcd
Content-Type: application/x-www-form-urlencoded
apikey=ABC123XYZ&from=example%40example.com&to=customer1%40domain.com&to=customer2%40domain.com&to=customer3%40domain.com&subject=New+Sale+Coming+Friday&bodytext=You+will+love+this+sale.
Run Code Online (Sandbox Code Playgroud)
我正在使用Spring5的反应工具来构建API.我有一个实用工具类,它将使用Dyn的电子邮件api发送电子邮件.我想使用新的WebClient类来完成这个(org.springframework.web.reactive.function.client.WebClient)
以下命令取自:https://help.dyn.com/email-rest-methods-api/sending-api/#postsend
curl --request POST "https://emailapi.dynect.net/rest/json/send" --data "apikey=ABC123XYZ&from=example@example.com&to=customer1@domain.com&to=customer2@domain.com&to=customer3@domain.com&subject=New Sale Coming Friday&bodytext=You will love this sale."
Run Code Online (Sandbox Code Playgroud)
当我使用真实值在curl中进行调用时,电子邮件正确发送,因此我觉得我正在生成错误的请求.
我的发送命令
public Mono<String> send( DynEmailOptions options )
{
WebClient webClient = WebClient.create();
HttpHeaders headers = new HttpHeaders();
// this line causes unsupported content type exception :(
// headers.setContentType( MediaType.APPLICATION_FORM_URLENCODED );
Mono<String> result = webClient.post()
.uri( "https://emailapi.dynect.net/rest/json/send" )
.headers( headers )
.accept( MediaType.APPLICATION_JSON )
.body( BodyInserters.fromObject( options …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的WebClient上设置超时,这是当前代码:
SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
ClientHttpConnector httpConnector = new ReactorClientHttpConnector(opt -> {
opt.sslContext(sslContext);
HttpClientOptions option = HttpClientOptions.builder().build();
opt.from(option);
});
return WebClient.builder().clientConnector(httpConnector).defaultHeader("Authorization", xxxx)
.baseUrl(this.opusConfig.getBaseURL()).build();
Run Code Online (Sandbox Code Playgroud)
我需要添加超时和汇集策略,我正在考虑这样的事情:
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(this.applicationConfig.getHttpClientMaxPoolSize());
cm.setDefaultMaxPerRoute(this.applicationConfig.getHttpClientMaxPoolSize());
cm.closeIdleConnections(this.applicationConfig.getServerIdleTimeout(), TimeUnit.MILLISECONDS);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(this.applicationConfig.getHttpClientSocketTimeout())
.setConnectTimeout(this.applicationConfig.getHttpClientConnectTimeout())
.setConnectionRequestTimeout(this.applicationConfig.getHttpClientRequestTimeout()).build();
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).build();
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何在我的webclient中设置httpClient
我在一些Spring webflux代码中遇到了Mono.defer()
我在文档中查找了该方法,但不理解其中的解释:
“创建一个Mono提供程序,该提供程序将提供目标Mono以便为每个下游的订阅者进行订阅”
请给我一个解释和一个例子。我可能会参考一堆Reactor示例代码(它们的单元测试?)的地方。
谢谢
请提出一些小的架构和设计问题。
\n问题:\nKubernetes Ingress 应该与 Spring Cloud Gateway 一起使用吗?如果不是,应该优先选择哪一个?
\n首先,通过 Spring Webflux / Spring Cloud Gateway 项目,我成功实现了基于路由的转发。这意味着,我的所有客户端只需要知道这个并且只有一个 Spring Cloud Gateway 端点,如果 URL 包含 serviceA,Spring Cloud Gateway 将转发到 serviceA,如果 URL 包含 serviceB,则 Spring Cloud Gateway 将转发到 serviceB,等等,简单明了。
\n我添加了更多 \xe2\x80\x9c 软件级别功能 \xe2\x80\x9d 例如动态配置(在运行时更改路由)、断路器、速率限制、舱壁和其他一些功能,非常酷,但实际上,我最终使用路由转发作为主要功能。
\n然后几周前,我花了一些时间研究 Kubernetes,更准确地说是 Kubernetes Ingress。\n我设法了解到 Kubernetes Ingress 是一个非常酷且强大的东西。我设法至少执行基于路由的转发。\n这意味着,客户端只需要知道这一个且唯一的 Ingress 端点,Ingress 将转发到 Kubernetes 集群内的底层服务。截至目前,它将所有内容转发到 Spring Cloud Gateway,Spring Cloud Gateway 将转发其他所有内容。我尝试过,它本来可以转发到真正的业务服务)。
\n这就是我产生怀疑的时刻。
\n我只是重复工作吗?(我的意思是就功能而言,我学习两者都很有趣)。
\n我是否应该考虑一种由 Spring Cloud Gateway(只有他)真正负责控制的架构?
\n我是否应该考虑一种入口和软件网关都具有完全重要性的架构,并在两者中配置功能?(接受重复的工作吗?)
\n我应该完全删除 Spring Cloud Gateway 吗?
\n …我们在生产中使用spring-data-r2dbc:1.3.2并dev.miku:r2dbc-mysql:0.8.2.RELEASE遇到了一个奇怪的问题。
我们不明白根本原因是什么,也不知道它是否是可恢复的,或者是否真的会产生不可预测的结果(如日志所示)。
我们定期看到错误日志如下:
我们每天都会看到它几次,这让我们感到紧张,因为它明确指出:这可能是一个导致不可预测结果的错误
我们在日志中没有得到任何附加信息。
几个问题:
我正在尝试查找WebClient使用的示例.我的目标是使用Spring 5 WebClient使用https和自签名证书查询REST服务
任何例子?
我正在使用 Spring Boot 2 和 Spring 5 和 WebFlux 反应式启动器开发一些反应式微服务。
我面临以下问题:我想处理通过调用另一个 REST 服务收到的所有 HTTP 状态,并在收到一些错误的 HTTP 状态时抛出异常。例如,当我调用端点并收到 404 HTTP 状态时,我想抛出一个异常,并且该异常将在某些 ExceptionHandler 类中处理,就像在 Spring 4 中使用@ControllerAdvice.
这样做的正确方法是什么?希望得到一些好的建议。
我正在使用带有 Kotlin 的 Spring Boot,现在尝试通过传递响应式服务的处理程序来从 GET 宁静服务中获取状态值。
我可以看到我传递的处理程序在请求中,但是每当我构建主体时,我都会收到此异常:
java.lang.IllegalArgumentException: 'producer' type is unknown to ReactiveAdapterRegistry
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.0.RELEASE.jar:5.2.0.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
@Bean
fun getReceiptConversionStatus() = router {
accept(MediaType.APPLICATION_JSON).nest {
GET("/BsGetStatus/{handler}", ::handleGetStatusRequest)
}
}
private fun handleGetStatusRequest(serverRequest: ServerRequest): Mono<ServerResponse> = ServerResponse
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(GetStatusViewmodel(fromObject(serverRequest.pathVariable("handler"))), GetStatusViewmodel::class.java)
.switchIfEmpty(ServerResponse.notFound().build())
Run Code Online (Sandbox Code Playgroud)
这就是我的视图模型:
data class GetStatusViewmodel(
@JsonProperty("handler") val documentHandler: String
)
Run Code Online (Sandbox Code Playgroud) 当响应为 5xx 时,我想在等待 10 秒后重试请求 3 次。但我没有看到可以使用的方法。在对象上
WebClient.builder()
.baseUrl("...").build().post()
.retrieve().bodyToMono(...)
Run Code Online (Sandbox Code Playgroud)
我可以看到方法:
在重试次数但没有延迟的条件下重试
.retry(3, {it is WebClientResponseException && it.statusCode.is5xxServerError} )
Run Code Online (Sandbox Code Playgroud)
重试退避和次数但没有条件
.retryBackoff
Run Code Online (Sandbox Code Playgroud)
还有一个,retryWhen但我不知道如何使用它
spring-webflux ×10
java ×6
spring ×5
spring-boot ×2
exception ×1
kotlin ×1
netty ×1
r2dbc ×1
r2dbc-mysql ×1
reactive ×1
reactor ×1
self-signed ×1
ssl ×1