我有一个spring boot控制器,可以像下面的一样吸引许多用户
样本json
system("cmd /c .$targetBAT");
<?php
if(isset($_POST['run']))
{
echo $_SESSION["runPath"];
$filename = '\UXAutomation\UXAutomation.bat';
$targetBAT = $_SESSION["runPath"].$filename;
if (file_exists($targetBAT)) {
echo "RESULT:OK";
echo $targetBAT;
system("cmd /c .$targetBAT");
} else {
echo "RESULT:KO";
}
}
?>
请求处理程序
{
"users": [
{ "name":"john", "age":18, "type":"1"},
{ "name":"kim", , "age":18, "type":"2"},
{ "name":"Fits", "age":18, "type","3"},
]
}
当我的用户列表中有大约100个用户时,它工作得很好,但是如果列表很大(如1000个),则需要太多时间。 所以我可以在其中分配任何春季批处理工作来执行此操作吗?
我只想返回http响应代码202来请求并将此有效负载分配给spring批处理作业
答案 0 :(得分:1)
一种选择是将Spring Async Task
用于长时间运行于单独线程中的进程,因此,您将等不及执行整个请求并将响应发送回去。
首先像这样配置异步任务。
@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);
}
}
processUser(User user)
带有@Async
注释,指示该方法将根据上面提供的taskExecutor
配置在单独的线程中运行。 @EnableAsync
使Spring
能够在带有@Async
注释的后台线程中运行任何方法。
并确保您使用异步任务处理用户的服务必须在@Configuration
类内部创建或由@ComponentScan
获取。您可以根据需要自定义taskExecutor
。
在这里您可以找到ThreadPoolTaskExecutor的工作方式。
答案 1 :(得分:0)
https://github.com/softnrajkumar1994/multithreading-example
重要
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);
}
}
上面的类将接收可运行的任务,并使用线程池的空闲线程执行。
示例用户类别:
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
}
}