Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
spring boot处理大请求体-通过多线程处理大容量_Spring_Spring Boot_Spring Batch_Batch Processing - Fatal编程技术网

spring boot处理大请求体-通过多线程处理大容量

spring boot处理大请求体-通过多线程处理大容量,spring,spring-boot,spring-batch,batch-processing,Spring,Spring Boot,Spring Batch,Batch Processing,我有一个spring引导控制器,它接收许多用户,如下所示 示例json { "users": [ { "name":"john", "age":18, "type":"1"}, { "name":"kim", , "age":18, "type":"2"}, { "name":"Fits", "age":18, "type","3"}, ] } 请求处理程序 @RequestMapping(value = "/users", method = RequestM

我有一个spring引导控制器,它接收许多用户,如下所示

示例json

{
  "users": [
    { "name":"john", "age":18, "type":"1"},
    { "name":"kim", , "age":18, "type":"2"},
    { "name":"Fits", "age":18, "type","3"},
  ]
 }
请求处理程序

@RequestMapping(value = "/users", method = RequestMethod.POST, headers = "Accept=application/json")
public void Add(@RequestBody List<user> users) throws Exception {

 // Here I am iterating users and writing one by one to different message topic based on the type
 // if any error in the given user while writing to message topic I am storing that user in other DB


}
@RequestMapping(value=“/users”,method=RequestMethod.POST,headers=“Accept=application/json”)
public void Add(@RequestBody List users)引发异常{
//在这里,我迭代用户并根据类型逐个编写不同的消息主题
//如果给定用户在写入消息主题时出现任何错误,我将该用户存储在其他数据库中
}
当我在用户列表中有大约100个用户时,它工作得很好,但是如果列表很大,比如1000个,那么它需要花费太多的时间。 那么,是否有任何spring批处理作业可以分配给它来执行此操作


我只想返回http响应代码202来请求并将此有效负载分配给spring批处理作业

一个选项是在单独的线程中为长时间运行的进程使用spring
异步任务
,因此不必等待执行整个请求并返回响应

首先像这样配置异步任务

@Configuration
@EnableAsync
public class AsynchTaskConfiguration{

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("ProcessUsers-");
        executor.initialize();
        return executor;
    }
}
在这里,您可以在服务中使用异步任务来处理用户

@Service
public class UserProcessingService {


    private final AnotherUserProcessingService service;
    @Autowired
    public UserProcessingService (AnotherUserProcessingService service) {
        this.service= service;
    }

    @Async
    public CompletableFuture<List<User>> processUser(List<User> users) throws InterruptedException {

        users.forEach(user -> logger.info("Processing " + user));
        List<User> usersListResult = service.process(users);
        // Artificial delay of 1s for demonstration purposes
        Thread.sleep(1000L);
        return CompletableFuture.completedFuture(usersListResult);
    }

}
@服务
公共类UserProcessingService{
私有最终另一个用户处理服务;
@自动连线
公共用户处理服务(另一个用户处理服务){
服务=服务;
}
@异步的
公共CompletableFuture processUser(列表用户)引发InterruptedException{
users.forEach(user->logger.info(“处理”+用户));
List usersListResult=service.process(用户);
//出于演示目的,人为延迟1s
睡眠(1000L);
返回CompletableFuture.completedFuture(usersListResult);
}
}
processUser(User-User)
@Async
注释,表示根据上面提供的
taskExecutor
配置,该方法将在单独的线程中运行
@EnableAsync
启用
Spring
在后台线程中运行任何用
@Async
注释的方法。 并确保使用异步任务处理用户的服务必须在
@Configuration
类中创建,或由
@ComponentScan
拾取。您可以根据需要自定义
taskExecutor

在这里您可以找到工作原理。

重要

1)如果一个请求中有1000个用户,请将这些用户列表作为小块发送

public class ThreadManager {

    private static ThreadPoolExecutor stpe = null;


    static {
         /**
         *
         *  corePoolSize --->the number of threads to keep in the pool, even
         *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
         *        
         *  maximumPoolSize --- >the maximum number of threads to allow in the
         *        pool
         *        
         *  keepAliveTime---> when the number of threads is greater than
         *        the core, this is the maximum time that excess idle threads
         *        will wait for new tasks before terminating.
         *        
         *  unit the time unit for the {@code keepAliveTime} argument
         *  
         *  workQueue the queue to use for holding tasks before they are
         *        executed.  This queue will hold only the {@code Runnable}
         *        tasks submitted by the {@code execute} method.

         */
        stpe = new ThreadPoolExecutor(5, 10, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1090));
        System.out.println("THREAD MANAGER INTIALIZED SUCCESSFULLY");
    }

    public static void execute(Runnable task) {
        stpe.execute(task);
    }
}

我不明白你在问什么。您是否希望现有的批处理作业定义能够为您做到这一点?在我看来,您想要转移到批处理作业的逻辑非常特定于您自己的领域和需求,此时不会仅仅存在于野外。如果是这样,那么你真的在问“我如何使用SpringBatch?”这个问题超出了本网站的范围。我想,有几十个文档集和教程可以教您如何使用SpringBatch。我建议你看看那里。是的,我想利用SpringBatch并将我的业务逻辑添加到其中。你开始尝试这样做了吗?你有没有代码可以给我们看,让我们看看你在尝试什么?如果不是,那么这不是一个适合这个网站的问题。本网站旨在解决特定的编程问题,而不是提供使用SpringBatch等完整技术的培训。再一次,我希望已经有很多资源可以帮助你。谷歌“Spring Batch”会为你提供大量潜在的学习选择。我不清楚你到底有什么具体问题。您想知道如何通过HTTP请求启动Spring批处理作业吗?您想知道如何将业务逻辑编写为Spring批处理作业吗?您想知道如何将HTTP请求中的参数传递给Spring批处理作业吗?我有一个用户列表,如何将用户列表传递给异步任务,并在异步任务线程池中逐个迭代。这里,如果我将池大小设置为10,并且所有线程将从一开始迭代用户列表,那么如何跟踪标记,因此,每个线程从用户列表中选择不同的用户,我需要接收该请求并分配给asnyc任务,然后在异步任务进程中重新执行202m,如果我以某种异步方式提供了任何错误。。由于我返回202,在处理第一个请求时,我可能会收到更多的请求,因此它是在que中还是需要单独处理它们。。
 public class User {

    private String name;
    private String mobile;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

@RestController
public class UserController {

    @PostMapping("/users")
    public void Add(@RequestBody List<User> users) throws Exception {
        /**
         * Here we are rotating user's list and assigning each and every user into a
         * separate worker thread, so that work will be done parallely
         */
        for (User user : users) {
            try {
                ThreadManager.execute(new UserWork(user));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
  public class UserWork implements Runnable {



    private User user;

    public UserWork(User user) {
        this.user = user;
    }

    @Override
    public void run() {
        // Please add your businees logic here
// Here I am iterating users and writing one by one to different message topic based on the type
 // if any error in the given user while writing to message topic I am storing that user in other DB
    }

}