无法使用 Spring 云连接到 Hystrix 仪表板的命令指标流

Unable to connect to Command Metric Stream for Hystrix Dashboard with Spring Cloud

我有 Spring Cloud 的微服务项目,来自父级的代码段:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
</parent>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.SR3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

Eureka 服务器下的所有服务运行:

所有服务运行都很好。我可以打电话给 Postman 进行适当的呼叫,一切正常。

我有单独的服务来处理 Hystrix 仪表板,摘自 pom:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>

主要配置class:

@SpringBootApplication
@EnableHystrixDashboard
public class DashboardApp {
    public static void main(String[] args) {
        SpringApplication.run(DashboardApp.class, args);
    }
}

和配置 yaml 文件:

spring:
  application:
    name: Dashboard

server:
  port: 8000

eureka:
  client:
    fetchRegistry: true
    registerWithEureka: false
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

我正在寻找下一个仪表板:

来自控制台的完整堆栈跟踪是 here。以下是一些片段:

2018-04-12 11:28:25.089 ERROR 15762 --- [qtp295055909-16] ashboardConfiguration$ProxyStreamServlet : Error proxying request: http://localhost:8082/hystrix.stream
java.lang.RuntimeException: org.eclipse.jetty.io.EofException
    at org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardConfiguration$ProxyStreamServlet.doGet(HystrixDashboardConfiguration.java:208)
....
Caused by: org.eclipse.jetty.io.EofException: null
...
Caused by: java.io.IOException: Broken pipe
...

服务本身可以通过 spring 执行器访问:

摘自 pom:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

配置class看起来:

@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
public class TableApp {
    public static void main(String[] args) {
        SpringApplication.run(TableApp.class, args);
    }
}

如何解决这个问题?

Hystrix 仪表板本身不能用于同时监视多个实例。你需要的是 turbine+dashboard。简而言之,turbine 是多个 hystrix 指标流的聚合器。

实例配置:

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream, info, health

spring:
  application:
    name: WRITING
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

这里重要的是公开 hystix.stream 执行器。涡轮机将使用此端点来读取指标。另外,不要忘记添加执行器启动器。

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>

如果一切正确http://localhost:8080/actuator/hystrix.stream端点应该可用。

涡轮配置如下所示:

server:
      port: 8888

spring:
  application:
    name: TURBINE

eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

turbine:
  appConfig: WRITING,READING
  clusterNameExpression: new String('default')

appConfig中,您应该指定用于监控的服务名称。

启动涡轮后 localhost:8888/turbine.stream 将可用。

您可以将此 URL 传递到仪表板并监控为已发现实例的 hystrix 命令聚合的所有数据。

Github 项目示例。

p.s。 您使用的依赖项已弃用。请检查 maven repo

终于找到了解决方法。

问题是控制器 API 必须通过 HystrixCommand 注释上市。

来自文档的片段:

Turbine AMQP by Spring Cloud offers a different model where each
application instance pushes the metrics from Hystrix commands to
Turbine through a central AMQP broker.

我将它添加到所有 Controller 的方法中,没有任何参数,如下所示:

@RestController
@AllArgsConstructor
public class GuestController {
    private DinnerService dinnerService;

    @HystrixCommand
    @PostMapping("/dinner")
    public Integer startDinner(@RequestBody List<Integer> menuItems) {
        return dinnerService.startDinner(menuItems);
    }

    @HystrixCommand
    @DeleteMapping("/dinner/{tableId}")
    public void finishDinner(@PathVariable Integer tableId) {
        dinnerService.finishDinner(tableId);
    }
}

现在一切都很迷人:

现在我明白了,我离它那么近了。

对于使用 spring boot 2 的用户,hystrix.stream 端点已移至 /actuator/hystrix.stream

对我来说这个url有效:

http://localhost:8082/actuator/hystrix.stream

是的,通过以下 属性:

启用此执行器端点
management.endpoints.web.exposure.include=hystrix.stream

当然你的项目中必须包含执行器依赖项。

我能够通过在 中添加以下两个属性来解决 spring-boot-starter-parent 版本 2.0.7.RELEASEspring-cloud-dependencies 版本 Finchley.SR2 的这个问题application.properties.

management.endpoints.web.exposure.include=*
management.endpoints.web.base-path=/

我在 Spring-boot(2.3.3-XXX) 和 spring-cloud (Hoxton.SR7) 的最新版本中遇到了同样的问题,但是当我在 [=20] 中降级版本时=] 文件然后它开始对我正常工作。

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

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR6</spring-cloud.version>
</properties>

希望这会有所帮助:)

  1. 将您的 hystrix.stream url 更正为 http://localhost:8082/actuator/hystrix.stream
  2. 在您的 hystrix 应用程序的配置文件中公开 'hystrix.steam' Web 端点:
management:
  endpoints:
    web:
      exposure:
        include: 'hystrix.stream'
  1. 确保您已将主机添加到 hystrix.dashboard.proxyStreamAllowList,在您的 hystrix-dashboard 应用程序的配置文件中,它看起来像:
hystrix:
  dashboard:
    proxy-stream-allow-list:
      - 'localhost'