spring boot处理大请求体-通过多线程处理大容量
我有一个spring引导控制器,它接收许多用户,如下所示 示例jsonspring 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
{
"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
}
}