Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Tomcat上的SpringWeb服务端点-并发调用配置_Multithreading_Spring Mvc_Tomcat7_Spring Integration - Fatal编程技术网

Multithreading Tomcat上的SpringWeb服务端点-并发调用配置

Multithreading Tomcat上的SpringWeb服务端点-并发调用配置,multithreading,spring-mvc,tomcat7,spring-integration,Multithreading,Spring Mvc,Tomcat7,Spring Integration,我有一个Spring应用程序,它有一个Web服务端点,在收到一个调用时,它会将请求负载传递给Spring IntegrationMessagingGateway,以进行EIP处理 我的应用程序部署在一个tomcat7容器上,并使用spring4api构建 我正在尝试运行一个性能测试,在该测试中,我对web服务进行多个并发调用。当我执行这个测试时,每个请求都得到了很好的处理,并且成功地收到了每个请求的响应,但是Spring应用程序似乎在处理两个请求。i、 e.第三个请求仅在第二个请求的响应发送回客

我有一个Spring应用程序,它有一个Web服务
端点
,在收到一个调用时,它会将请求负载传递给Spring Integration
MessagingGateway
,以进行EIP处理

我的应用程序部署在一个
tomcat7
容器上,并使用spring4api构建

我正在尝试运行一个性能测试,在该测试中,我对web服务进行多个并发调用。当我执行这个测试时,每个请求都得到了很好的处理,并且成功地收到了每个请求的响应,但是Spring应用程序似乎在处理两个请求。i、 e.第三个请求仅在第二个请求的响应发送回客户端后由应用程序处理。(调试时,我可以看到只有两个线程处理请求)

我想知道我的Spring应用程序的执行线程配置应该在哪里进行,以便支持并发处理多个web服务客户端请求(例如,10个以上并发线程)。这应该在Tomcat容器的配置中的某个地方完成吗?Web服务配置中的某个地方?Spring集成的消息网关配置?Spring集成的请求集成流配置?这些配置的组合?或者完全在别的地方

我的堆栈是:

Tomcat 7.0.55
Spring/Integration 4 APIs
Spring Java DSL 1 API
对于我的测试,我使用的是SoapUI 4.5.0,我正在使用以下配置执行负载测试:

@Endpoint
@EnableIntegration
@IntegrationComponentScan(basePackages = "com.company.test.gateway")
@ComponentScan(basePackages = "com.company.test.gateway")
public class TestServiceEndpoint {

    private static final String NAMESPACE_URI = "http://www.company.com/test";

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    private TestGateway gateway;

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "test")
    @ResponsePayload
    public TestResponse process(
            @RequestPayload TestRequest request) throws Exception {

        TestResponse response = gateway.process(request);

        return response;
    }
}
@MessagingGateway
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public interface TestGateway {

    @Gateway(requestChannel = "test.request.ch", replyChannel = "test.response.ch")
    TestResponse process(TestRequest request);
}
@Configuration
public class IntegrationConfig {

    @Bean(name = "test.request.ch")
    public DirectChannel testRequestCh() {
        return new DirectChannel();
    }

    @Bean(name = "test.response.ch")
    public DirectChannel testResponseCh() {
        return new DirectChannel();
    }

    @Bean
    public Executor taskExecutor() {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(10);
        return executor;
    }

    @Bean
    public IntegrationFlow requestFlow() {

        return IntegrationFlows
                .from("test.request.ch")
                .enrichHeaders(
                        m -> {
                            m.header(MessageHeaders.ERROR_CHANNEL,
                                    "test.error.ch", true);
                        })
                .handle("testSplitter", "split")
                .channel(MessageChannels.executor("requestSplitterFlowExecutor",
                        this.taskExecutor()))
                .route("testRouter", "route")
                        .get();
    }

    ...
}
线程:10,策略:线程,开始线程:10,结束线程:10,每个线程限制运行1次。

我假设这个配置可以测试对web服务URL的10个并发调用

*更新以包括当前配置*

端点配置:

@Endpoint
@EnableIntegration
@IntegrationComponentScan(basePackages = "com.company.test.gateway")
@ComponentScan(basePackages = "com.company.test.gateway")
public class TestServiceEndpoint {

    private static final String NAMESPACE_URI = "http://www.company.com/test";

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    private TestGateway gateway;

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "test")
    @ResponsePayload
    public TestResponse process(
            @RequestPayload TestRequest request) throws Exception {

        TestResponse response = gateway.process(request);

        return response;
    }
}
@MessagingGateway
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public interface TestGateway {

    @Gateway(requestChannel = "test.request.ch", replyChannel = "test.response.ch")
    TestResponse process(TestRequest request);
}
@Configuration
public class IntegrationConfig {

    @Bean(name = "test.request.ch")
    public DirectChannel testRequestCh() {
        return new DirectChannel();
    }

    @Bean(name = "test.response.ch")
    public DirectChannel testResponseCh() {
        return new DirectChannel();
    }

    @Bean
    public Executor taskExecutor() {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(10);
        return executor;
    }

    @Bean
    public IntegrationFlow requestFlow() {

        return IntegrationFlows
                .from("test.request.ch")
                .enrichHeaders(
                        m -> {
                            m.header(MessageHeaders.ERROR_CHANNEL,
                                    "test.error.ch", true);
                        })
                .handle("testSplitter", "split")
                .channel(MessageChannels.executor("requestSplitterFlowExecutor",
                        this.taskExecutor()))
                .route("testRouter", "route")
                        .get();
    }

    ...
}
网关配置:

@Endpoint
@EnableIntegration
@IntegrationComponentScan(basePackages = "com.company.test.gateway")
@ComponentScan(basePackages = "com.company.test.gateway")
public class TestServiceEndpoint {

    private static final String NAMESPACE_URI = "http://www.company.com/test";

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    private TestGateway gateway;

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "test")
    @ResponsePayload
    public TestResponse process(
            @RequestPayload TestRequest request) throws Exception {

        TestResponse response = gateway.process(request);

        return response;
    }
}
@MessagingGateway
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public interface TestGateway {

    @Gateway(requestChannel = "test.request.ch", replyChannel = "test.response.ch")
    TestResponse process(TestRequest request);
}
@Configuration
public class IntegrationConfig {

    @Bean(name = "test.request.ch")
    public DirectChannel testRequestCh() {
        return new DirectChannel();
    }

    @Bean(name = "test.response.ch")
    public DirectChannel testResponseCh() {
        return new DirectChannel();
    }

    @Bean
    public Executor taskExecutor() {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(10);
        return executor;
    }

    @Bean
    public IntegrationFlow requestFlow() {

        return IntegrationFlows
                .from("test.request.ch")
                .enrichHeaders(
                        m -> {
                            m.header(MessageHeaders.ERROR_CHANNEL,
                                    "test.error.ch", true);
                        })
                .handle("testSplitter", "split")
                .channel(MessageChannels.executor("requestSplitterFlowExecutor",
                        this.taskExecutor()))
                .route("testRouter", "route")
                        .get();
    }

    ...
}
集成配置:

@Endpoint
@EnableIntegration
@IntegrationComponentScan(basePackages = "com.company.test.gateway")
@ComponentScan(basePackages = "com.company.test.gateway")
public class TestServiceEndpoint {

    private static final String NAMESPACE_URI = "http://www.company.com/test";

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    private TestGateway gateway;

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "test")
    @ResponsePayload
    public TestResponse process(
            @RequestPayload TestRequest request) throws Exception {

        TestResponse response = gateway.process(request);

        return response;
    }
}
@MessagingGateway
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public interface TestGateway {

    @Gateway(requestChannel = "test.request.ch", replyChannel = "test.response.ch")
    TestResponse process(TestRequest request);
}
@Configuration
public class IntegrationConfig {

    @Bean(name = "test.request.ch")
    public DirectChannel testRequestCh() {
        return new DirectChannel();
    }

    @Bean(name = "test.response.ch")
    public DirectChannel testResponseCh() {
        return new DirectChannel();
    }

    @Bean
    public Executor taskExecutor() {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(10);
        return executor;
    }

    @Bean
    public IntegrationFlow requestFlow() {

        return IntegrationFlows
                .from("test.request.ch")
                .enrichHeaders(
                        m -> {
                            m.header(MessageHeaders.ERROR_CHANNEL,
                                    "test.error.ch", true);
                        })
                .handle("testSplitter", "split")
                .channel(MessageChannels.executor("requestSplitterFlowExecutor",
                        this.taskExecutor()))
                .route("testRouter", "route")
                        .get();
    }

    ...
}
干杯,
PM

应用程序一次只处理两条消息(有时甚至只处理一条ata!)的原因根本不是因为Spring配置或Tomcat配置中存在问题,而是因为测试工具SoapUI 4.5.0中存在错误。看


更新SoapUI并重新运行后,现在可以看到消息一次由多个线程处理。

您需要显示集成配置。如果始终使用
DirectChannel
s,则集成流将在tomcat http线程上运行,该线程不应限于2个。嗨,与网关直接关联的通道是
DirectChannel
s。然而,随着流程的进一步深入,事情会变得更加复杂,这取决于消息的路由方式。在我当前运行的性能测试中,
testRouter
将有效负载路由到
PublishSubscribeChannel
,其中有效负载放置在MQ队列中。这是一个发布子频道的原因是,一旦我们知道有效负载已成功放入队列,我们就会进行其他工作。此后,响应最终通过
JMS入站适配器到达,并发送到
test.response.ch
返回网关。框架中没有任何限制线程的内容。我建议您打开调试日志并遵循消息流;确保包含线程名称(
%t
如果是log4j),以便查看发生了什么。