在 Spring 引导应用程序中实施工作进程
Implementing worker processes in a Spring Boot application
简介
我目前是 运行 一个 Spring- 通过 Heroku 在单个 web dyno 上启动应用程序。由于大量密集的后台任务(从 3rd 方 API 获取资源、发送邮件等),我想将所有这些“繁重的工作”转移给第二个工人 dyno/process。但是,我在将应用程序组件(例如@Repositories)正确暴露给第二个工作进程时遇到了一些困难。
到目前为止我尝试了什么
我创建了第二个主 class (BackgroundWorker
),我在 Procfile 中将其指定为辅助进程。然后调用以下 class 以初始化后台任务。
@Service
@EnableMongoRepositories("com.a.viz.db")
@ComponentScan("com.a.viz.db")
@EntityScan("com.a.viz.model")
public class TaskHandler {
@Autowired
UProductRepository productRepository;
public void initScheduler()
{
Runnable fetchProducts = () -> {
Scheduler.fetchProducts(productRepository);
};
}
}
虽然主要 class 看起来像这样:
public class BackgroundWorker {
static Logger logger = LoggerFactory.getLogger(BackgroundWorker.class);
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.a.viz.workers");
context.refresh();
TaskHandler handler = context.getBean(TaskHandler.class);
handler.initScheduler();
}
}
在 运行 上面的代码片段中,我在 UProductRepository
的具体实现中注入了 bean MongoTemplate
的不满足依赖错误,称为 UProductRepositoryImpl
。
public class UProductRepositoryImpl implements UProductRepositoryCustom {
private final MongoTemplate mongoTemplate;
@Autowired
public UProductRepositoryImpl(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.mongodb.core.MongoTemplate'
如何将 MongoTemplate
公开给第二个工作进程?此外,处理此类问题的好方法是什么?我应该尝试组织我的组件,以便只有相关的组件暴露给工作进程吗?感谢您的关注!
解决方案
因为工作进程也必须是一个 Spring 应用程序(为了允许注入存储库等),它的应用程序上下文必须这样初始化。 web 参数是为了防止设置适当的 web 服务器,因为这不是必需的。
// Other configs..
@EnableAutoConfiguration
public class BackgroundWorker implements ApplicationRunner {
@Autowired
// Repositories..
public static void main(String[] args)
{
new SpringApplicationBuilder(BackgroundWorker.class)
.web(WebApplicationType.NONE)
.run(args);
}
简介
我目前是 运行 一个 Spring- 通过 Heroku 在单个 web dyno 上启动应用程序。由于大量密集的后台任务(从 3rd 方 API 获取资源、发送邮件等),我想将所有这些“繁重的工作”转移给第二个工人 dyno/process。但是,我在将应用程序组件(例如@Repositories)正确暴露给第二个工作进程时遇到了一些困难。
到目前为止我尝试了什么
我创建了第二个主 class (BackgroundWorker
),我在 Procfile 中将其指定为辅助进程。然后调用以下 class 以初始化后台任务。
@Service
@EnableMongoRepositories("com.a.viz.db")
@ComponentScan("com.a.viz.db")
@EntityScan("com.a.viz.model")
public class TaskHandler {
@Autowired
UProductRepository productRepository;
public void initScheduler()
{
Runnable fetchProducts = () -> {
Scheduler.fetchProducts(productRepository);
};
}
}
虽然主要 class 看起来像这样:
public class BackgroundWorker {
static Logger logger = LoggerFactory.getLogger(BackgroundWorker.class);
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.a.viz.workers");
context.refresh();
TaskHandler handler = context.getBean(TaskHandler.class);
handler.initScheduler();
}
}
在 运行 上面的代码片段中,我在 UProductRepository
的具体实现中注入了 bean MongoTemplate
的不满足依赖错误,称为 UProductRepositoryImpl
。
public class UProductRepositoryImpl implements UProductRepositoryCustom {
private final MongoTemplate mongoTemplate;
@Autowired
public UProductRepositoryImpl(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.mongodb.core.MongoTemplate'
如何将 MongoTemplate
公开给第二个工作进程?此外,处理此类问题的好方法是什么?我应该尝试组织我的组件,以便只有相关的组件暴露给工作进程吗?感谢您的关注!
解决方案
因为工作进程也必须是一个 Spring 应用程序(为了允许注入存储库等),它的应用程序上下文必须这样初始化。 web 参数是为了防止设置适当的 web 服务器,因为这不是必需的。
// Other configs..
@EnableAutoConfiguration
public class BackgroundWorker implements ApplicationRunner {
@Autowired
// Repositories..
public static void main(String[] args)
{
new SpringApplicationBuilder(BackgroundWorker.class)
.web(WebApplicationType.NONE)
.run(args);
}