Spring多部分文件

时间:2016-01-07 10:20:24

标签: java spring spring-boot

我目前正在开发一个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)


}

我做错了什么?

感谢您的帮助:)

0 个答案:

没有答案