首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弹簧RestTemplate & AsyncRestTemplate与Netty4永远挂起

弹簧RestTemplate & AsyncRestTemplate与Netty4永远挂起
EN

Stack Overflow用户
提问于 2016-09-22 12:46:23
回答 1查看 3.4K关注 0票数 5

非常简单的设置:

pom.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo-rest-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo-rest-client</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.5.Final</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-buffer</artifactId>
            <version>4.1.5.Final</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>9.3.1</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-hystrix</artifactId>
            <version>9.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

以及演示AsyncRestTemplate不同用法的测试用例:

SampleTests.java

代码语言:javascript
复制
package com.example;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandProperties;
import feign.RequestLine;
import feign.hystrix.HystrixFeign;
import feign.hystrix.SetterFactory;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.Netty4ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

public class SampleTests {

    private static final String URL = "https://api.github.com/users/octocat";
    private static final int DEFAULT_SLEEP_MILLIS = 20;
    private static final int DEFAULT_TIMEOUT = 10000;

    @Test(timeout = DEFAULT_TIMEOUT)
    public void syncRestNetty() throws Exception {
        RestTemplate restTemplate = new RestTemplate(new Netty4ClientHttpRequestFactory());
        ResponseEntity<String> response = restTemplate.getForEntity(URL, String.class);
        System.out.println("response = " + response);
    }

    @Test(timeout = DEFAULT_TIMEOUT)
    public void asyncRestNetty() throws Exception {
        AsyncRestTemplate restTemplate = new AsyncRestTemplate(new Netty4ClientHttpRequestFactory());
        ListenableFuture<ResponseEntity<String>> listenableFuture = restTemplate.getForEntity(URL, String.class);
        listenableFuture.addCallback(result -> System.out.println("result = " + result), Throwable::printStackTrace);
        while (!listenableFuture.isDone()) {
            Thread.sleep(DEFAULT_SLEEP_MILLIS);
        }
        System.out.println("the end");
    }

    @Test
    public void asyncRestOkHttp() throws Exception {
        AsyncRestTemplate restTemplate = new AsyncRestTemplate(new OkHttp3ClientHttpRequestFactory());
        ListenableFuture<ResponseEntity<String>> listenableFuture = restTemplate.getForEntity(URL, String.class);
        listenableFuture.addCallback(result -> System.out.println("result = " + result), Throwable::printStackTrace);
        while (!listenableFuture.isDone()) {
            Thread.sleep(DEFAULT_SLEEP_MILLIS);
        }
        System.out.println("the end");
    }

    @Test
    public void asyncRestHystrixFeign() throws Exception {
        GitHub gitHub = HystrixFeign.builder()
                .setterFactory((target, method) -> new SetterFactory.Default().create(target, method).andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter().withExecutionTimeoutInMilliseconds(10000)))
                .target(GitHub.class, "https://api.github.com");
        HystrixCommand<String> command = gitHub.octocatAsync();
        command.toObservable().subscribe(result -> System.out.println("result = " + result), Throwable::printStackTrace);
        while (!command.isExecutionComplete()) {
            Thread.sleep(DEFAULT_SLEEP_MILLIS);
        }
        System.out.println("command.getExecutionTimeInMilliseconds() = " + command.getExecutionTimeInMilliseconds());
        System.out.println("the end");
    }

    interface GitHub {
        @RequestLine("GET /users/octocat")
        HystrixCommand<String> octocatAsync();
    }
}

当尝试运行使用Netty的测试时,它们只会永远挂起。(要查看这一点,请删除JUnit超时约束)。但是,如果我对其他客户端运行完全相同的代码,一切都按预期工作。

我尝试过不同版本的Spring和Netty,但没有成功。从日志上看一切都还好。

我在这里错过了什么?

编辑:按Spring上的建议打开一个票证https://jira.spring.io/browse/SPR-14744

编辑2: Brian的回答帮助我找到了与Netty相关的问题,因为Netty没有意识到服务器发送了一个空的响应( Github和普通http的一个特殊情况),所以我将其标记为已接受。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-26 08:18:39

您能否尝试使用Netty配置请求工厂?

代码语言:javascript
复制
Netty4ClientHttpRequestFactory nettyFactory = new Netty4ClientHttpRequestFactory();
nettyFactory.setSslContext(SslContextBuilder.forClient().build());
AsyncRestTemplate restTemplate = new AsyncRestTemplate(nettyFactory);

如果没有该上下文,客户端将尝试向https端点发送明文请求;在这种情况下,您可能会得到一个HTTP 400响应。

在您的示例代码中,throwable应该是HttpClientErrorException的一个实例,您可以通过使用exception.getResponseBodyAsString()记录响应状态或它的主体来获取该信息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39639467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档