在 Jersey 2 中使用 Hystrix Java Servlet 和 Servlet 过滤器
Using a Hystrix Java Servlet & Servlet Filter in Jersey 2
我正在使用 Netflix 的 Hystrix 库在我正在构建的 REST 客户端中连接到远程服务时充当断路器。我想通过他们提供的库设置事件流和仪表板监控。查看他们的示例应用程序 here,看来我需要将他们的 servlet 过滤器和 servlet 类 应用到我的 Web 应用程序。
我正在使用 Spring Boot with Jersey 2 并在 JerseyConfig.java(没有 web.xml)中连接我的资源和过滤器。我知道 Jersey Filters 与 Servlet Filters 不同,并且正在努力将两者集成在一起。
那么,如何使用 Java Servlet 过滤器并将其用作 Jersey 过滤器以及如何使用 Java Servlet 并将其用作 Jersey 资源?
我目前对 Servlet 的策略是像这样包装它们。一人一份。
@Path("/hystrix.stream")
public class HystrixResource extends HystrixUtilizationSseServlet {
@Context
HttpServletRequest httpRequest;
@Context
HttpServletResponse httpResponse;
//This returns void because it is a text/stream output that must remain open,
//so the httpResponse is continually written to until the conenction is closed
@GET
public void doGet() throws ServletException, IOException {
doGet(httpRequest, httpResponse);
}
}
这可能有效,但由于某种原因数据基本上是空的。我猜是因为过滤器没有工作。
data: {"type":"HystrixUtilization","commands":{},"threadpools":{}}
我不太清楚如何包装 Servlet 过滤器,因为它们期望与 Jersey ContainerRequestFilter 不同的输入和输出。我的 JerseyConfig 中的以下实现似乎什么都不做,因为日志没有表明正在注册过滤器,而且我无法在调试模式下中断这些文件中的行。
@Component
@ApplicationPath("/")
public class JerseyConfig extends ResourceConfig {
private static final Logger LOGGER = Logger.getLogger("JerseyConfig");
public JerseyConfig(){
//filter to provide a bridge between JAX-RS and Spring request attributes
register(RequestContextFilter.class);
register(SpringComponentProvider.class);
//handles custom serialization
register(new ObjectMapperContextResolver());
//try to register the filters - which doesn't work because these aren't Jersey Filters
register(HystrixRequestContextServletFilter.class);
register(HystrixRequestLogViaResponseHeaderServletFilter.class);
registerResources();
/*
* Enable the logging filter to see the HTTP response for each request.
*/
register(new LoggingFilter(LOGGER, true));
}
}
不应在 Jersey 配置中注册 Servlet 和 Servlet 过滤器。他们将被忽略。您应该改为使用 Spring 注册它们 Boot with ServletRegistrationBean
s and FilterRegistrationBean
s.
在你的Spring配置中,你可以做类似
的事情
@Bean
public ServletRegistrationBean someServlet() {
ServletRegistrationBean registration = ServletRegisrationBean(
new HystrixMetricsStreamServlet(), "/hystrix.stream");
registration.setName("HystrixMetricsStreamServlet");
return registration;
}
@Bean
public FilterRegistrationBean someFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HystrixRequestContextServletFilter());
registration.setUrlPatterns(Arrays.asList("/*"));
registration.setName("HystrixRequestContextServletFilter");
// you can also set the order of filters if you need to
return registration;
}
还有:
- 您不需要注册
SpringComponentProvider
。这是自动注册的。
- 如果您在尝试访问以这种方式注册的 servlet 时收到 404,那是因为您使用的是默认的 Jersey 映射
/*
,它占用了所有请求。您可以更改映射或将 Jersey 注册为过滤器以转发未找到的请求。参见
另一种方法,也是我最终选择的方法,如果您在 Spring 引导项目中,则使用 Spring cloud/boot 启动器。这使我不必像另一个答案中所示那样显式定义 bean 和过滤器。最终基本上开箱即用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<exclusions>
<!--We're running our Jersey server w/ Jackson 2. This import uses Jackson 1.x and creates a breaking conflict.-->
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
参考Circuit Breaker入门指南。我面临的一个问题是 Jackson 1 vs Jackson 2 冲突,并且能够添加库排除。我以前基本上有 Hystrix 库 jar,但没有任何连接使其工作。
我正在使用 Netflix 的 Hystrix 库在我正在构建的 REST 客户端中连接到远程服务时充当断路器。我想通过他们提供的库设置事件流和仪表板监控。查看他们的示例应用程序 here,看来我需要将他们的 servlet 过滤器和 servlet 类 应用到我的 Web 应用程序。
我正在使用 Spring Boot with Jersey 2 并在 JerseyConfig.java(没有 web.xml)中连接我的资源和过滤器。我知道 Jersey Filters 与 Servlet Filters 不同,并且正在努力将两者集成在一起。
那么,如何使用 Java Servlet 过滤器并将其用作 Jersey 过滤器以及如何使用 Java Servlet 并将其用作 Jersey 资源?
我目前对 Servlet 的策略是像这样包装它们。一人一份。
@Path("/hystrix.stream")
public class HystrixResource extends HystrixUtilizationSseServlet {
@Context
HttpServletRequest httpRequest;
@Context
HttpServletResponse httpResponse;
//This returns void because it is a text/stream output that must remain open,
//so the httpResponse is continually written to until the conenction is closed
@GET
public void doGet() throws ServletException, IOException {
doGet(httpRequest, httpResponse);
}
}
这可能有效,但由于某种原因数据基本上是空的。我猜是因为过滤器没有工作。
data: {"type":"HystrixUtilization","commands":{},"threadpools":{}}
我不太清楚如何包装 Servlet 过滤器,因为它们期望与 Jersey ContainerRequestFilter 不同的输入和输出。我的 JerseyConfig 中的以下实现似乎什么都不做,因为日志没有表明正在注册过滤器,而且我无法在调试模式下中断这些文件中的行。
@Component
@ApplicationPath("/")
public class JerseyConfig extends ResourceConfig {
private static final Logger LOGGER = Logger.getLogger("JerseyConfig");
public JerseyConfig(){
//filter to provide a bridge between JAX-RS and Spring request attributes
register(RequestContextFilter.class);
register(SpringComponentProvider.class);
//handles custom serialization
register(new ObjectMapperContextResolver());
//try to register the filters - which doesn't work because these aren't Jersey Filters
register(HystrixRequestContextServletFilter.class);
register(HystrixRequestLogViaResponseHeaderServletFilter.class);
registerResources();
/*
* Enable the logging filter to see the HTTP response for each request.
*/
register(new LoggingFilter(LOGGER, true));
}
}
不应在 Jersey 配置中注册 Servlet 和 Servlet 过滤器。他们将被忽略。您应该改为使用 Spring 注册它们 Boot with ServletRegistrationBean
s and FilterRegistrationBean
s.
在你的Spring配置中,你可以做类似
的事情@Bean
public ServletRegistrationBean someServlet() {
ServletRegistrationBean registration = ServletRegisrationBean(
new HystrixMetricsStreamServlet(), "/hystrix.stream");
registration.setName("HystrixMetricsStreamServlet");
return registration;
}
@Bean
public FilterRegistrationBean someFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HystrixRequestContextServletFilter());
registration.setUrlPatterns(Arrays.asList("/*"));
registration.setName("HystrixRequestContextServletFilter");
// you can also set the order of filters if you need to
return registration;
}
还有:
- 您不需要注册
SpringComponentProvider
。这是自动注册的。 - 如果您在尝试访问以这种方式注册的 servlet 时收到 404,那是因为您使用的是默认的 Jersey 映射
/*
,它占用了所有请求。您可以更改映射或将 Jersey 注册为过滤器以转发未找到的请求。参见
另一种方法,也是我最终选择的方法,如果您在 Spring 引导项目中,则使用 Spring cloud/boot 启动器。这使我不必像另一个答案中所示那样显式定义 bean 和过滤器。最终基本上开箱即用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<exclusions>
<!--We're running our Jersey server w/ Jackson 2. This import uses Jackson 1.x and creates a breaking conflict.-->
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
参考Circuit Breaker入门指南。我面临的一个问题是 Jackson 1 vs Jackson 2 冲突,并且能够添加库排除。我以前基本上有 Hystrix 库 jar,但没有任何连接使其工作。