使用 JMH 测试 Spring MVC 吞吐量
Testing Spring MVC throughtput with JMH
所以我正在尝试对 Spring MVC(主要是 REST 控制器)进行一些基准测试,没有容器;只是 Spring 及其请求处理。使用 Jersey,我可以做这样的事情:
private volatile ApplicationHandler handler;
private volatile ContainerRequest request;
@Setup
public void start() throws Exception {
handler = new ApplicationHandler(new JerseyAppConfig());
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Setup(Level.Iteration)
public void request() {
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Benchmark
public Future<ContainerResponse> measure() throws Exception {
return handler.apply(request);
}
ApplicationHandler
是 Jersey 请求处理的主要入口点。我所有的 Jersey 配置都在 JerseyConfig
中。基本上所有发生的事情都是我创建请求 (ContainerRequest
),然后处理请求只是调用处理程序并传入请求。请求经过请求处理周期后返回response
我正在尝试使用 Spring MVC 模仿相同的功能。真的,我什至不知道我会怎么做。我刚开始往墙上扔东西,希望它能粘住。我有点想也许我可以用 DispatcherServlet
(或者更准确地说是 FrameworkSevlet
)来做到这一点。但是为了做到这一点,我能看到的唯一方法是通过反射使受保护的 processRequest
可访问。这是我的尝试
private volatile AnnotationConfigWebApplicationContext appContext;
private volatile FrameworkServlet dispatcherServlet;
private volatile HttpServletRequest request;
private volatile HttpServletResponse response;
private volatile Method processRequest;
@Setup
public void start() throws Exception {
appContext = new AnnotationConfigWebApplicationContext();
appContext.register(SpringAppConfig.class);
dispatcherServlet = new DispatcherServlet(appContext);
processRequest = dispatcherServlet.getClass().getSuperclass()
.getDeclaredMethod("processRequest",
HttpServletRequest.class,
HttpServletResponse.class);
processRequest.setAccessible(true);
}
@Setup(Level.Iteration)
public void request() throws Exception {
request = new MockHttpServletRequest("GET", "/hello");
response = new MockHttpServletResponse();
}
@Benchmark
public void measure() throws Exception {
processRequest.invoke(dispatcherServlet, request, response);
}
虽然这不起作用。我在 this line 收到 NPE,我猜这意味着 webApplicationContext
为空。不过我是上面设置的。
NPE 与否,我什至不确定我是否以正确的方式进行此操作;如果还有其他一些我应该研究的组件而不是 DispatcherServlet
。
有人知道如何使这项工作有效吗?我应该查看另一个组件,调用不同的方法吗?我可能缺少任何配置才能真正使我的上述尝试起作用?
要求站
- 使用 JMH
- 仅测试 Spring 请求到响应处理的吞吐量。
See complete runnable project on GitHub
您可以查看 Spring 框架代码库 here which can give you pointer on proper setup required and request/response mocks. Also you can have an example of proper setup here 中提供的 DispatcherServlet
的测试用例 here which can give you pointer on proper setup required and request/response mocks. Also you can have an example of proper setup here。
所以我正在尝试对 Spring MVC(主要是 REST 控制器)进行一些基准测试,没有容器;只是 Spring 及其请求处理。使用 Jersey,我可以做这样的事情:
private volatile ApplicationHandler handler;
private volatile ContainerRequest request;
@Setup
public void start() throws Exception {
handler = new ApplicationHandler(new JerseyAppConfig());
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Setup(Level.Iteration)
public void request() {
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Benchmark
public Future<ContainerResponse> measure() throws Exception {
return handler.apply(request);
}
ApplicationHandler
是 Jersey 请求处理的主要入口点。我所有的 Jersey 配置都在 JerseyConfig
中。基本上所有发生的事情都是我创建请求 (ContainerRequest
),然后处理请求只是调用处理程序并传入请求。请求经过请求处理周期后返回response
我正在尝试使用 Spring MVC 模仿相同的功能。真的,我什至不知道我会怎么做。我刚开始往墙上扔东西,希望它能粘住。我有点想也许我可以用 DispatcherServlet
(或者更准确地说是 FrameworkSevlet
)来做到这一点。但是为了做到这一点,我能看到的唯一方法是通过反射使受保护的 processRequest
可访问。这是我的尝试
private volatile AnnotationConfigWebApplicationContext appContext;
private volatile FrameworkServlet dispatcherServlet;
private volatile HttpServletRequest request;
private volatile HttpServletResponse response;
private volatile Method processRequest;
@Setup
public void start() throws Exception {
appContext = new AnnotationConfigWebApplicationContext();
appContext.register(SpringAppConfig.class);
dispatcherServlet = new DispatcherServlet(appContext);
processRequest = dispatcherServlet.getClass().getSuperclass()
.getDeclaredMethod("processRequest",
HttpServletRequest.class,
HttpServletResponse.class);
processRequest.setAccessible(true);
}
@Setup(Level.Iteration)
public void request() throws Exception {
request = new MockHttpServletRequest("GET", "/hello");
response = new MockHttpServletResponse();
}
@Benchmark
public void measure() throws Exception {
processRequest.invoke(dispatcherServlet, request, response);
}
虽然这不起作用。我在 this line 收到 NPE,我猜这意味着 webApplicationContext
为空。不过我是上面设置的。
NPE 与否,我什至不确定我是否以正确的方式进行此操作;如果还有其他一些我应该研究的组件而不是 DispatcherServlet
。
有人知道如何使这项工作有效吗?我应该查看另一个组件,调用不同的方法吗?我可能缺少任何配置才能真正使我的上述尝试起作用?
要求站
- 使用 JMH
- 仅测试 Spring 请求到响应处理的吞吐量。
See complete runnable project on GitHub
您可以查看 Spring 框架代码库 here which can give you pointer on proper setup required and request/response mocks. Also you can have an example of proper setup here 中提供的 DispatcherServlet
的测试用例 here which can give you pointer on proper setup required and request/response mocks. Also you can have an example of proper setup here。