我目前正在开发一个Spring-boot项目,我必须通过REST Web服务将文件(一次一个)发送到服务器,然后将服务器发送到Cassandra集群。
这部分有效,但当我开始对我的项目进行压力测试(使用Gatling)时出现了我的问题。
这是:
- 当我在不发送文件的情况下测试我的工作时,我的延迟时间约为10-15毫秒;
- 当我测试我的工作在请求正文中发送文件时,我的延迟也大约为10-15毫秒(可能会高出5或10毫秒,我不记得了);
- 但是,我的问题出现在这里,当我通过发送input
的文件测试Web服务,并使用MultipartFile获取它时,延迟变化很大,从最快请求的10毫秒到12000毫秒( !!)最长的。
我试图将内存限制中的文件设置为1Go(原来是~10ko),但它没有改变任何东西。 执行测试时我没有收到任何错误,它只是很长......
此外,该项目正在使现有的Web服务现代化,该服务作为JAX-WS运行,具有WSDL和所有功能。处理旧项目的团队(我们正在从DBMS转换到另一个)的响应时间平均为~10!
这是我的conf(这是POC,机器很便宜):
- Web服务器:Wildfly 9-0-1.FINAL开箱即用,在CentOS Server 7.1上;
- 压力测试机:Gatling 2.1.7,与Wildfly相同的CentOS版本,但在另一台机器上;
- 一个8节点的Cassandra集群。
这是我的pom(没有公司的秘密|关于spring-boot依赖,它不是我的项目的父级,它已经有一个):
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.3.0.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>oss-jfrog-artifactory</id>
<name>oss-jfrog-artifactory-releases</name>
<url>http://oss.jfrog.org/artifactory/oss-release-local</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</>
</pluginRepository>
</pluginRepositories>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.0.RELEASE</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
StartApp.java:
package foo.bar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@SpringBootApplication
@EnableAutoConfiguration(exclude = MultipartAutoConfiguration.class)
public class StartApp extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(StartApp.class);
}
public static void main(String[] args) {
SpringApplication.run(StartApp.class, args);
}
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxInMemorySize(1024 * 1024 * 1024); // 1Go
return multipartResolver;
}
}
WS.java(只有相关函数):
import static org.springframework.web.bind.annotation.RequestMethod.POST;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import service.DaoException;
import service.ErrCode;
import service.IService;
...
@Inject IService service;
...
@RequestMapping(path = "/insert/{foo}/{bar}", method = POST)
public ResponseEntity<Void> insert(@PathVariable String foo,
@PathVariable String bar,
@RequestParam MultipartFile document) {
HttpStatus httpCode = HttpStatus.CREATED;
try (InputStream is = document.getInputStream()) {
service.insert(foo, bar, is);
} catch (DaoException e) {
logger.error("Problème lors de l'insertion du document : "
+ e.getMessage());
httpCode = handleError(e.getCode());
} catch (IOException e1) {
logger.error("Problème lors du traitement du document envoyé : "
+ e1.getMessage());
httpCode = handleError(ErrCode.PB_TECHNIQUE);
}
return ResponseEntity.status(httpCode).build();
}
Simulation.scala:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.Path
import java.util.Base64
import java.io.File
import java.lang.String
class RestSimulation1 extends Simulation {
val DEBIT = 30 //Clients per second
val DUREE = 300 //Duration
val httpConf = http
.baseURL("http://myserver:8080") // Here is the root for all relative urls
.acceptHeader("text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8") // Here are the common headers
.doNotTrackHeader("1")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate")
.userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")
//Feeders creation
val feeder = csv("9k_rest.csv").queue
object Insert {
val insert = feed(feeder)
.exec(http("insertion")
.post("/webservice/ws/insert/${fooo}/${bar}")
.formUpload("document", "rest_insert_${format}.txt")
.check(status.is(201)))
}
val scn = scenario("").exec(Insert.insert)
setUp(scn.inject( constantUsersPerSec(DEBIT) during(DUREE seconds))).protocols(httpConf)
}
我做错了什么?
感谢您的帮助:)