JavaEE - EJB/CDI 方法持续时间机制
JavaEE - EJB/CDI Method Duration Mechanism
不确定如何给这个问题起标题,但希望描述能给出更好的解释。我正在寻找一种方法来使用自定义注释(如“@Duration”或 aa 等)来注释 ejb 方法或 cdi 方法,以便在给定持续时间后花费太长时间来终止方法执行。我想一些伪代码会让一切变得清晰:
public class myEJBorCdiBean {
@Duration(seconds = 5)
public List<Data> complexTask(..., ...)
{
while(..)
// this takes more time than the given 5 seconds so throw execption
}
总而言之,一个方法需要非常长的时间,它会抛出一个给定的持续时间过期错误或类似的错误
有点超时机制,不知道有没有类似的,我是javaEE新手
提前谢谢大家
您不应该在 EJB/CDI 容器中使用线程 API。 EJB 规范明确指出:
The enterprise bean must not attempt to manage threads. The enterprise
bean must not attempt to start, stop, suspend, or resume a thread, or
to change a thread’s priority or name. The enterprise bean must not
attempt to manage thread groups.
托管 bean 及其业务方法的调用必须由容器完全控制,以避免损坏其状态。根据您的用例,将此操作卸载到专用服务(javaee 之外),或者您可以使用 EJB @Singleton
和 Schedule
提出一些半黑客解决方案 - 这样您可以定期检查一些控制标志。如果您在 Wildfly/JBoss 上 运行ning,您可能会为此滥用 @TransactionTimeout
注释 - 因为 EJB 方法默认情况下是事务感知的,在事务上设置超时将有效地控制调用超时豆的方法。我不确定其他应用程序服务器如何支持它。
如果异步处理是一个选项,那么 EJB @Asynchronous
可能会有一些帮助:参见 Asynchronous tutorial - Cancelling and asynchronous operation。
作为一般建议:不要 运行 在 EJB/CDI 中长时间执行 运行ning 操作。每个请求都会产生一个新线程,线程是有限的资源,你的应用程序将更难扩展和维护(long 运行ning op ~= state),如果你的服务器在方法调用期间崩溃会发生什么,将如何集群环境中的用例工作。再次很难说,在不了解您的用例的情况下,什么是更好的方法,但是研究 java EE 批处理 api、带有消息驱动 bean 的 JMS 或带有 @Asynchronous
[= 的异步处理17=]
这是一个非常有意义的想法——将一个复杂的任务限制在一定的执行时间内。在实际的网络计算中,当复杂的搜索任务的持续时间超过最大可接受的时间量时,许多用户将不愿意等待完成。
企业容器控制着线程池,以及CPU-资源在活动线程中的分配。它这样做还考虑了耗时 I/O-tasks(通常是磁盘访问)期间的保留时间。
尽管如此,对开始任务变量进行编程是有意义的,因此在复杂任务期间不时地验证该特定任务的持续时间。我建议你编写一个本地的、可运行的任务,它从作业队列中挑选预定的任务。我在 Glassfish 下的 Java 企业后端应用程序 运行 中有这方面的经验。
首先是接口定义Duration.java
// Duration.java
@Qualifier
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Duration {
public int minutes() default 0; // Default, extended from class, within path
}
现在遵循作业的定义TimelyJob.java
// TimelyJob.java
@Duration(minutes = 5)
public class TimelyJob {
private LocalDateTime localDateTime = LocalDateTime.now();
private UUID uniqueTaskIdentifier;
private String uniqueOwnerId;
public TimelyJob(UUID uniqueTaskIdentifier, String uniqueOwnerId) {
this.uniqueTaskIdentifier = uniqueTaskIdentifier;
this.uniqueOwnerId = uniqueOwnerId;
}
public void processUntilMins() {
final int minutes = this.getClass().getAnnotation(Duration.class).minutes();
while (true) {
// do some heavy Java-task for a time unit, then pause, and check total time
// break - when finished
if (minutes > 0 && localDateTime.plusMinutes(minutes).isAfter(LocalDateTime.now())) {
break;
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
System.err.print(e);
}
}
// store result data in result class, 'synchronized' access
}
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public UUID getUniqueTaskIdentifier() {
return uniqueTaskIdentifier;
}
public String getUniqueOwnerId() {
return uniqueOwnerId;
}
}
执行定时作业的Runnable任务-TimedTask.java-实现如下:
// TimedTask.java
public class TimedTask implements Runnable {
private LinkedBlockingQueue<TimelyJob> jobQueue = new LinkedBlockingQueue<TimelyJob>();
public void setJobQueue(TimelyJob job) {
this.jobQueue.add(job);
}
@Override
public void run() {
while (true) {
try {
TimelyJob nextJob = jobQueue.take();
nextJob.processUntilMins();
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.print(e);
}
}
}
}
并且在单独的代码中, TimedTask
的凝视
public void initJobQueue() {
new Thread(new TimedTask()).start();
}
此功能实际上在 Java 中实现了批处理作业调度程序,使用注释来控制结束任务时间限制。
不确定如何给这个问题起标题,但希望描述能给出更好的解释。我正在寻找一种方法来使用自定义注释(如“@Duration”或 aa 等)来注释 ejb 方法或 cdi 方法,以便在给定持续时间后花费太长时间来终止方法执行。我想一些伪代码会让一切变得清晰:
public class myEJBorCdiBean {
@Duration(seconds = 5)
public List<Data> complexTask(..., ...)
{
while(..)
// this takes more time than the given 5 seconds so throw execption
}
总而言之,一个方法需要非常长的时间,它会抛出一个给定的持续时间过期错误或类似的错误
有点超时机制,不知道有没有类似的,我是javaEE新手
提前谢谢大家
您不应该在 EJB/CDI 容器中使用线程 API。 EJB 规范明确指出:
The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.
托管 bean 及其业务方法的调用必须由容器完全控制,以避免损坏其状态。根据您的用例,将此操作卸载到专用服务(javaee 之外),或者您可以使用 EJB @Singleton
和 Schedule
提出一些半黑客解决方案 - 这样您可以定期检查一些控制标志。如果您在 Wildfly/JBoss 上 运行ning,您可能会为此滥用 @TransactionTimeout
注释 - 因为 EJB 方法默认情况下是事务感知的,在事务上设置超时将有效地控制调用超时豆的方法。我不确定其他应用程序服务器如何支持它。
如果异步处理是一个选项,那么 EJB @Asynchronous
可能会有一些帮助:参见 Asynchronous tutorial - Cancelling and asynchronous operation。
作为一般建议:不要 运行 在 EJB/CDI 中长时间执行 运行ning 操作。每个请求都会产生一个新线程,线程是有限的资源,你的应用程序将更难扩展和维护(long 运行ning op ~= state),如果你的服务器在方法调用期间崩溃会发生什么,将如何集群环境中的用例工作。再次很难说,在不了解您的用例的情况下,什么是更好的方法,但是研究 java EE 批处理 api、带有消息驱动 bean 的 JMS 或带有 @Asynchronous
[= 的异步处理17=]
这是一个非常有意义的想法——将一个复杂的任务限制在一定的执行时间内。在实际的网络计算中,当复杂的搜索任务的持续时间超过最大可接受的时间量时,许多用户将不愿意等待完成。
企业容器控制着线程池,以及CPU-资源在活动线程中的分配。它这样做还考虑了耗时 I/O-tasks(通常是磁盘访问)期间的保留时间。
尽管如此,对开始任务变量进行编程是有意义的,因此在复杂任务期间不时地验证该特定任务的持续时间。我建议你编写一个本地的、可运行的任务,它从作业队列中挑选预定的任务。我在 Glassfish 下的 Java 企业后端应用程序 运行 中有这方面的经验。
首先是接口定义Duration.java
// Duration.java
@Qualifier
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Duration {
public int minutes() default 0; // Default, extended from class, within path
}
现在遵循作业的定义TimelyJob.java
// TimelyJob.java
@Duration(minutes = 5)
public class TimelyJob {
private LocalDateTime localDateTime = LocalDateTime.now();
private UUID uniqueTaskIdentifier;
private String uniqueOwnerId;
public TimelyJob(UUID uniqueTaskIdentifier, String uniqueOwnerId) {
this.uniqueTaskIdentifier = uniqueTaskIdentifier;
this.uniqueOwnerId = uniqueOwnerId;
}
public void processUntilMins() {
final int minutes = this.getClass().getAnnotation(Duration.class).minutes();
while (true) {
// do some heavy Java-task for a time unit, then pause, and check total time
// break - when finished
if (minutes > 0 && localDateTime.plusMinutes(minutes).isAfter(LocalDateTime.now())) {
break;
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
System.err.print(e);
}
}
// store result data in result class, 'synchronized' access
}
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public UUID getUniqueTaskIdentifier() {
return uniqueTaskIdentifier;
}
public String getUniqueOwnerId() {
return uniqueOwnerId;
}
}
执行定时作业的Runnable任务-TimedTask.java-实现如下:
// TimedTask.java
public class TimedTask implements Runnable {
private LinkedBlockingQueue<TimelyJob> jobQueue = new LinkedBlockingQueue<TimelyJob>();
public void setJobQueue(TimelyJob job) {
this.jobQueue.add(job);
}
@Override
public void run() {
while (true) {
try {
TimelyJob nextJob = jobQueue.take();
nextJob.processUntilMins();
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.print(e);
}
}
}
}
并且在单独的代码中, TimedTask
public void initJobQueue() {
new Thread(new TimedTask()).start();
}
此功能实际上在 Java 中实现了批处理作业调度程序,使用注释来控制结束任务时间限制。