首页 > 解决方案 > Spring Boot 在负载测试(50 个用户)时给出不同的响应

问题描述

我们已经将项目技术从Java servlet升级到Spring Boot。它适用于单用户事务模式,但不适用于多用户测试。

我的项目配置

UI - 角度
业务逻辑 - Java Spring Boot
后端 - 没有 SQL 获取调用
没有休眠

Session - 无状态会话
我们不根据用户的会话进行处理。我们仅处理员工 ID 和案例 ID(75 % 获取请求,25 % 发布请求)。它适用于单用户时间。LoadNinja 负载测试运行 50 个用户时间 - 我们将得到另一个用户对我的响应。

如果我向服务器请求我的详细信息(同时加载 ninja 为 50 个用户测试运行相同的进程),我的名字是 Apple,但我得到的是 Orange 用户详细信息的响应。有时我得到一个空指针异常。

我无法追踪问题的原因 - 您能否就项目配置更改提出建议。

提前致谢。

EmployeeController.java

package com.apa.documentprocessor.constants;

import java.io.IOException;

import javax.xml.bind.JAXBException;

import org.apache.commons.httpclient.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    EmployeeService employeeservice;
    
    @Autowired
    Employee employee;
    
    @RequestMapping("/getDetails")
    public void getEmployeeDetails() throws HttpException, IOException, JAXBException {
        
        employee.setEmpId("100");
        employee.setEmpName("Nuno");
        employee.setDept("Research");
        employee.setLocation("India");
        
        
        EmployeePerformance emp = employeeservice.EmployeeDetails(employee);
        
        System.out.println(emp.toString());
        
        
    }
    
}

EmployeeService.java

package com.apa.documentprocessor.constants;

import java.io.IOException;
import java.io.StringReader;


import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.stereotype.Component;
import org.xml.sax.InputSource;



@Component
public class EmployeeService {

    @Autowired
    EmployeePerformance empPerformance;
    
    @Autowired
    private AutowireCapableBeanFactory beanFactory;
    
    public EmployeePerformance EmployeeDetails(Employee emp) throws HttpException, IOException, JAXBException {
            
        
        this.empPerformance = beanFactory.createBean(EmployeePerformance.class);
        this.empPerformance = getDetails(emp);
        
        
        return empPerformance;
        
    }


    private EmployeePerformance getDetails(Employee emp) throws HttpException, IOException, JAXBException {
        
        
        String result;
        String url=emp.getEmpName();
        
        
        HttpClient client = new HttpClient();
        GetMethod method = new GetMethod(url);
        method.addRequestHeader("3454362523", emp.getEmpId());
        
        client.executeMethod(method);
        
        result = method.getResponseBodyAsString();
        
        JAXBContext jaxbContext = JAXBContext.newInstance(EmployeePerformance.class);
        
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        
        EmployeePerformance empPerformance = (EmployeePerformance) jaxbUnmarshaller
                .unmarshal(new InputSource(new StringReader(result)));
        
        
        empPerformance.setProject("Banking");
        empPerformance.setRating("Good");
        
        return empPerformance;
    }
    
    
}

员工绩效.java

package com.apa.documentprocessor.constants;

import org.springframework.stereotype.Component;

@Component
public class EmployeePerformance {

    String empName;
    String rating;
    String project;
    String position;
    
    
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public String getRating() {
        return rating;
    }
    public void setRating(String rating) {
        this.rating = rating;
    }
    public String getProject() {
        return project;
    }
    public void setProject(String project) {
        this.project = project;
    }
    public String getPosition() {
        return position;
    }
    public void setPosition(String position) {
        this.position = position;
    }
    
    
}

雇员.java

package com.apa.documentprocessor.constants;

import org.springframework.stereotype.Component;

@Component
public class Employee {

    
    String empId;
    String empName;
    String dept;
    String location;
    
    
    public String getEmpId() {
        return empId;
    }
    public void setEmpId(String empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public String getDept() {
        return dept;
    }
    public void setDept(String dept) {
        this.dept = dept;
    }
    public String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    
    
    
}

标签: javaspringspring-boot

解决方案


你的代码有缺陷,不要制作Employee也不要EmployeePerformance春天管理的豆子。只需在需要时构建一个新实例。使用 Spring 这一事实并不意味着一切都需要由 Spring 管理。

@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    EmployeeService employeeservice;
    
    @RequestMapping("/getDetails")
    public void getEmployeeDetails() throws HttpException, IOException, JAXBException {
        Employee employee = new Employee();
        employee.setEmpId("100");
        employee.setEmpName("Nuno");
        employee.setDept("Research");
        employee.setLocation("India");
        
        EmployeePerformance emp = employeeservice.EmployeeDetails(employee);
        
        System.out.println(emp.toString());
    }  
}

关于HttpClient不要每次都构造一个,而是重用它,或者甚至更好地使用RestTemplate它来完成所有开箱即用的操作,包括编组。

@Component
public class EmployeeService {

    private final RestTemplate http;
    
    public EmployeeService(RestTemplate http) {
      this.http=http;
    }

    public EmployeePerformance EmployeeDetails(Employee emp) throws HttpException, IOException, JAXBException {           
        return getDetails(emp);
    }

    private EmployeePerformance getDetails(Employee emp) throws HttpException, IOException, JAXBException {
        
        String url=emp.getEmpName();
        RequestEntity req = RequestEntity.get(url).header("3454362523", emp.getEmpId()).build();  
        
        EmployeePerformance empPerformance = http.exchange(req, EmployeePerformance.class).getBody();       
        
        empPerformance.setProject("Banking");
        empPerformance.setRating("Good");
        
        return empPerformance;
    }
}

在您的配置中,您需要添加以下内容

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
  return builder.requestFactory(HttpComponentsClientHttpRequestFactory.class).build();
}

有了这个,您不再共享状态并重用重对象,而不是每次需要它们时都构建它们。


推荐阅读