Java 具有单线程执行器的RESTful web服务的体系结构?
我想知道对于带有单线程执行器的RESTful web服务,什么样的体系结构可能是最好的 我的目标是:Java 具有单线程执行器的RESTful web服务的体系结构?,java,web-services,rest,lifecycle,executor,Java,Web Services,Rest,Lifecycle,Executor,我想知道对于带有单线程执行器的RESTful web服务,什么样的体系结构可能是最好的 我的目标是: 调用RESTful web服务 web服务在线程队列中添加一个任务,并每1次执行所有任务1 实例化对象的生命周期非常重要(必须只有一个线程队列)。我知道RESTful web服务生命周期是“每个请求”(我认为类似于@RequestScoped),因此我看到了两个选项: 备选案文1: public class RestService { protected final static Exe
public class RestService {
protected final static Executor executor;
protected final static Implementation1 impl1;
protected final static Implementation2 impl2;
static {
executor = Executors.newSingleThreadExecutor();
impl1 = new Implementation1();
impl2 = new Implementation2();
}
}
@Path("/servicename")
public class MyService extends RestService {
@POST
@Path("/compute")
public void compute(){
executor.execute(new Runnable(){
public void run(){
impl1.compute();
}
});
}
}
备选案文2:
@Singleton
public class RestService {
private Executor executor;
private Implementation1 impl1;
private Implementation2 impl2;
public RestService () {
executor = Executors.newSingleThreadExecutor();
impl1 = new Implementation1();
impl2 = new Implementation2();
}
public void execute(Runnable run){
executor.execute(run);
}
public Implementation1 getImplementation1(){
return impl1;
}
public Implementation2 getImplementation2(){
return impl2;
}
}
@Path("/servicename")
public class MyService {
@Inject
private RestService rs;
@POST
@Path("/compute")
public void compute(){
rs.execute(new Runnable(){
public void run(){
rs.getImplementation1().compute();
}
});
}
}
对于选项1,我不确定静态字段的“生命周期”。我应该使用哪个选项?你会怎么做
谢谢
编辑:
选项3(由EJB容器处理的线程)和“排序”并不重要:
@Singleton
public class RestService {
private final Executor executor;
private final Implementation1 impl1;
private final Implementation2 impl2;
public RestService () {
executor = Executors.newSingleThreadExecutor();
impl1 = new Implementation1();
impl2 = new Implementation2();
}
public void compute1(){
executor.execute(new Runnable(){
public void run(){
impl1.compute();
}
});
}
public void compute2(){
executor.execute(new Runnable(){
public void run(){
impl2.compute();
}
});
}
}
@Path("/servicename")
public class MyService {
@Inject
private RestService rs;
@POST
@Path("/compute1")
public void compute1(){
rs.compute1();
}
@POST
@Path("/compute2")
public void compute2(){
rs.compute2();
}
}
我认为选项3仍然比选项1和2好。我认为这样做是个坏主意。线程应该由容器处理,而不是由代码处理 如果要在JavaEE应用服务器上部署,应该让它处理线程 如果要在非阻塞I/O服务器(如Netty或vert.x)上部署,则应该让它处理线程 在任何情况下都不应该管理线程 静态字段在.class加载时实例化。它们不像实例那样具有“生命周期”。在类装入器删除.class文件之前,它们不会被清理
如果必须有这种行为,我会使用JMS队列来排序处理,或者使用生产者/消费者deque来管理它。您希望处理是异步的。让REST服务将令牌或回执返回给客户机,并让他们回来查看处理何时完成。如果队伍很长,你就无法知道他们的衬衫什么时候准备好了。收据让他们回来检查结果是否有效。我认为这样做不好。线程应该由容器处理,而不是由代码处理 如果要在JavaEE应用服务器上部署,应该让它处理线程 如果要在非阻塞I/O服务器(如Netty或vert.x)上部署,则应该让它处理线程 在任何情况下都不应该管理线程 静态字段在.class加载时实例化。它们不像实例那样具有“生命周期”。在类装入器删除.class文件之前,它们不会被清理
如果必须有这种行为,我会使用JMS队列来排序处理,或者使用生产者/消费者deque来管理它。您希望处理是异步的。让REST服务将令牌或回执返回给客户机,并让他们回来查看处理何时完成。如果队伍很长,你就无法知道他们的衬衫什么时候准备好了。收据允许他们回来检查结果是否可用。如果您使用Spring,然后将业务逻辑分离为单独的组件(bean)将这些bean注入到服务类中,只需更改业务逻辑bean的“scope”属性,就可以有效地控制实现的线程模型 这是一个例子 这种方法可以让您轻松地修改/试验解决方案,并发现适合您情况的最佳替代方案
就架构而言,我建议您将系统分层(松耦合、高内聚、关注点分离等)。在这方面,您可能至少有一个服务层(REST)、一个业务层和一个数据层(dao)。各层通过接口相互作用。使用Spring将事物连接在一起(注入依赖项)。这使您能够灵活地注入不同的实现。例如,为您的业务类注入模拟DAO以进行单元测试。REST服务所在的服务层将执行请求/响应的转换、一些验证、确定要调用的业务组件并调用它们 如果使用Spring,然后将业务逻辑分离为单独的组件(bean),并将这些bean注入到服务类中,那么只需更改业务逻辑bean的“scope”属性,就可以有效地控制实现的线程模型 这是一个例子 这种方法可以让您轻松地修改/试验解决方案,并发现适合您情况的最佳替代方案
就架构而言,我建议您将系统分层(松耦合、高内聚、关注点分离等)。在这方面,您可能至少有一个服务层(REST)、一个业务层和一个数据层(dao)。各层通过接口相互作用。使用Spring将事物连接在一起(注入依赖项)。这使您能够灵活地注入不同的实现。例如,为您的业务类注入模拟DAO以进行单元测试。REST服务所在的服务层将执行请求/响应的转换、一些验证、确定要调用的业务组件并调用它们 如果您一次只能执行一个,我建议您使用一个队列,例如JMSI已经在项目中使用JMS,我认为JMS对于这个简单的项目来说非常重要。如果您一次只能执行一个,我建议您使用一个队列,例如JMSI已经在项目中使用JMS,我认为JMS对于这个简单的项目来说非常重要。我不使用Netty、vetr.x、JMS,但我可以在EJB容器(@Singleton)中创建“线程部分”:
@Path(/servicename”)公共类MyService{@Inject private RestService rs;@POST@Path(/compute)public void compute(){rs.computeimplement1();//包含执行器}
否?也许可以;我不知道