Spring Cloud Zuul,Spectator和Atlas配置

3

我在本地机器上尝试使用Spring Cloud相关技术,其中一个基于Zuul的API网关可以发现并调用Spring Data Rest服务,运行良好。

现在我想引入Spectator和Atlas,但是无法正确配置。如果我在Zuul服务中启用Atlas,则Atlas客户端的RestTemplate会失败,因为Ribbon试图包装它,而Ribbon不知道“atlas”。如果我为Atlas添加一个Ribbon客户端配置,则我的API网关调用会出错。有没有一种方法可以将atlas路由从Ribbon包装中排除?我漏掉了什么?请参见以下内容:

我定义了一个指向本地主机的主机名“atlas”,Atlas服务器正在运行。

Zuul / API网关依赖项:

spring-boot-starter-parent: 1.3.2.RELEASE
spring-boot-starter-actuator
spring-cloud-starter-config
spring-cloud-starter-eureka
spring-cloud-starter-hystrix
spring-cloud-starter-zuul
spring-cloud-starter-stream-rabbit
spring-boot-starter-hateoas
spring-boot-starter-test
spring-cloud-starter-spectator
spring-cloud-starter-atlas

Zuul / API网关应用程序属性--

hystrix.command.default.execution.isolation.strategy: SEMAPHORE
netflix.atlas.uri=http://atlas:7101/api/v1/publish
server.port: ${PORT:8080}

API网关引导属性:

spring.application.name=reservationClient
spring.cloud.config.uri=http://localhost:8888

Zuul / Eureka / Ribbon / Hystrix客户端都正常工作,但是Atlas客户端出现故障。
@SpringBootApplication
@EnableZuulProxy
@EnableHystrix
@EnableEurekaClient
@EnableAtlas
@EnableScheduling
public class APIGateway {

    @Autowired
    Registry registry;

    public static void main(String[] args) {
        SpringApplication.run(APIGateway.class, args);
    }
}

Atlas客户端被Ribbon包装,而Ribbon不了解Atlas。
2016-03-07 08:57:50.312 ERROR 184 --- [trace=,span=] [ask-scheduler-2] o.s.integration.handler.LoggingHandler   : java.lang.IllegalStateException: No instances available for atlas
    at org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory.createRequest(RibbonClientHttpRequestFactory.java:58)
    at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:77)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475)
    at org.springframework.cloud.netflix.metrics.atlas.AtlasMetricObserver.sendMetricsBatch(AtlasMetricObserver.java:148)
    at org.springframework.cloud.netflix.metrics.atlas.AtlasMetricObserver.update(AtlasMetricObserver.java:126)
    at org.springframework.cloud.netflix.metrics.atlas.AtlasExporter.export(AtlasExporter.java:35)
    at org.springframework.boot.actuate.metrics.export.MetricExporters$ExportRunner.run(MetricExporters.java:112)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

好的,让我们为Atlas定义一个Ribbon客户端。

@SpringBootApplication
@EnableZuulProxy
@EnableHystrix
@EnableEurekaClient
@EnableAtlas
@EnableScheduling
public class APIGateway {

    @Autowired
    Registry registry;

    public static void main(String[] args) {
        SpringApplication.run(APIGateway.class, args);
    }
}

@Component
public class AtlasClientConfiguration {
    @Bean
    public StaticServerList ribbonServerList() {
        return new StaticServerList<Server>(new Server("atlas", 7101));
    }
}

现在Atlas客户端正常工作。我可以看到POST请求已经发送到了Atlas服务器。
但是,现在通过Zuul访问我的Spring Data服务的GET请求失败了,错误提示如下:
"HTTP方法不被允许,支持的方法有:POST"
感谢您的帮助!
1个回答

4

我偶然找到了解决方法。

AtlasClientConfiguration不是一个组件,它只是一个提供StaticServerList的Bean。移除@Component注释。

我需要明确命名我的RibbonClient配置,例如@RibbonClient(name = "atlas", configuration = AtlasClientConfiguration.class)。

@SpringBootApplication
@EnableZuulProxy
@EnableHystrix
@EnableEurekaClient
@RibbonClient(name = "atlas", configuration = AtlasClientConfiguration.class)
@EnableAtlas
@EnableScheduling
public class APIGateway {

    @Autowired
    Registry registry;

    public static void main(String[] args) {
        SpringApplication.run(APIGateway.class, args);
    }
}


public class AtlasClientConfiguration {

    @Bean
    public StaticServerList<Server> ribbonServerList() {
        return new StaticServerList<Server>(new Server("atlas", 7101));
    }
}

干得好,这正是我想说的。不过奇怪的是Atlas正在使用启用了Ribbon的RestTemplate。 - spencergibb
2
我已经为此添加了一个问题,你不需要做你所做的事情。 https://github.com/spring-cloud/spring-cloud-netflix/issues/881 - spencergibb
@spencergibb 感谢您在此问题上的开放,也感谢您在Spring Cloud / Netflix上所做的所有工作。这是非常棒的东西。 - MarkOfHall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接