springBatch配置远程step

远程Step数据处理的示意图

消息队列和AMQ服务器的配置

	<!--定义消息网关 defaultChannel为默认发送的消息队列名称   -->
<bean:bean id="messagingGateway" class="org.springframework.integration.core.MessagingTemplate">
		<bean:property name="defaultChannel" ref="requests" />
		<bean:property name="receiveTimeout" value="1000" />
	</bean:bean>

	<!--定义requests的adapter-->
	<int-jms:outbound-channel-adapter connection-factory="connectionFactory" channel="requests"
		destination-name="requests" />
	<!--定义使用的channel requests 和 incoming -->
	<int:channel id="requests" />
	<int:channel id="incoming" />
	<!--定义消息转换器 从incoming获取消息,写消息到replies-->
	<int:transformer input-channel="incoming" output-channel="replies" 
	    ref="headerExtractor" method="extract" />

	<!--定义响应的channel-->
	<int:channel id="replies" scope="thread">
		<int:queue /> <!--定义replies是一个队列标识-->
		<int:interceptors> <!--定义一个拦截器 把replies的信息发送到incoming队列上 -->
			<!--   MessageSourcePollerInterceptor-->
			<bean:bean id="pollerInterceptor"
			    class="org.springframework.batch.integration.chunk.MessageSourcePollerInterceptor">
				<bean:property name="messageSource"><!--replies-->
					<bean:bean class="org.springframework.integration.jms.JmsDestinationPollingSource">
						<bean:constructor-arg>
							<bean:bean class="org.springframework.jms.core.JmsTemplate">
								<bean:property name="connectionFactory" ref="connectionFactory" />
								<bean:property name="defaultDestinationName" value="replies" />
								<bean:property name="receiveTimeout" value="100" />
							</bean:bean>
						</bean:constructor-arg>
					</bean:bean>
				</bean:property>
				<bean:property name="channel" ref="incoming"/>
			</bean:bean>
		</int:interceptors>
	</int:channel>

    <!--jmsTemplate基本配置-->
	<bean:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<bean:property name="connectionFactory" ref="connectionFactory" />
		<bean:property name="receiveTimeout" value="100" />
		<bean:property name="sessionTransacted" value="true" />
	</bean:bean>	
			
    <!--定义了jms服务器-->
	<amq:broker useJmx="false" persistent="false" schedulerSupport="false">
    	<amq:transportConnectors>
			<amq:transportConnector uri="tcp://localhost:61616"/>
		</amq:transportConnectors>
	</amq:broker>
	<amq:connectionFactory id="connectionFactory" brokerURL="tcp://localhost:61616"/>

配置本地的step(使用RemoteChunkHandlerFactoryBean)

<!-- 定义chunkWriter,chunkWriter负责将本地Step中读取数据通过messagingGateway发送到远程Step中,ChunkMessageChannelItemWriter是一个StepExecutionListener类型的拦截器-->
<bean:bean id="chunkWriter" scope="step"
	    class="org.springframework.batch.integration.chunk.ChunkMessageChannelItemWriter" >
		<bean:property name="messagingOperations" ref="messagingGateway" />
		<bean:property name="replyChannel" ref="replies" />
		<bean:property name="maxWaitTimeouts" value="10" />
	</bean:bean>

<!-- 定义chunkHandler,stepRemoteChunk 对应默认的 chunkProcessor-->
<bean:bean id="chunkHandler" 	    class="org.springframework.batch.integration.chunk.RemoteChunkHandlerFactoryBean">
		<bean:property name="chunkWriter" ref="chunkWriter" />
		<bean:property name="step" ref="stepRemoteChunk" />
</bean:bean>	

配置本地的step(使用ChunkProcessorChunkHandler,仅chunkHandler部分)

	<bean:bean id="chunkHandler"
		class="org.springframework.batch.integration.chunk.ChunkProcessorChunkHandler">
		<bean:property name="chunkProcessor">
			<bean:bean class="org.springframework.batch.core.step.item.SimpleChunkProcessor">
				<bean:property name="itemWriter" ref="jdbcItemWriter"/>
				<bean:property name="itemProcessor">
					<bean:bean class="org.springframework.batch.item.support.PassThroughItemProcessor"/>
				</bean:property>
			</bean:bean>
		</bean:property>
	</bean:bean>

 配置远程step

 <!-- 设置监听器,监听队列requests,处理执行chunkHandler的handleChunk,结果返回到replies-->
 <jms:listener-container connection-factory="connectionFactory" 
	    transaction-manager="transactionManager"
		acknowledge="transacted" concurrency="1">
		<jms:listener destination="requests" response-destination="replies" 
		    ref="chunkHandler" method="handleChunk" />
	</jms:listener-container>
  

远程job配置

<!-- 配置和普通job没有区别  reader:jdbcItemPageReader writer:jdbcItemWriter-->
<job id="remoteChunkJob">
		<step id="stepRemoteChunk">
			<tasklet>
				<chunk reader="jdbcItemPageReader" writer="jdbcItemWriter" commit-interval="10" />
			</tasklet>
		</step>
	</job>

读取数据库配置

<!-- 从db分页读数据 -->
	<bean:bean id="jdbcItemPageReader" scope="step" 
	    class="org.springframework.batch.item.database.JdbcPagingItemReader">
        <bean:property name="dataSource" ref="dataSource"/>
        <bean:property name="queryProvider" ref="refQueryProvider" />
    	<bean:property name="pageSize" value="2"/>
        <bean:property name="rowMapper" ref="custCreditRowMapper"/>
    </bean:bean>
    
     <bean:bean id="refQueryProvider" scope="step" 
         class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
         <bean:property name="dataSource" ref="dataSource"/>
         <bean:property name="selectClause" value="select ID,ACCOUNTID,NAME,AMOUNT,DATE,ADDRESS"/>
         <bean:property name="fromClause" value="from t_credit"/>
         <bean:property name="whereClause" value="where ID between 1 and 15"/>
         <bean:property name="sortKey" value="ID"/>
      </bean:bean>    
         
    <bean:bean id="custCreditRowMapper" 
        class="com.juxtapose.example.ch11.partition.db.CreditBillRowMapper"/>
    

 写数据库配置

<bean:bean id="jdbcItemWriter" 
        class="org.springframework.batch.item.database.JdbcBatchItemWriter">
        <bean:property name="dataSource" ref="dataSource"/>
        <bean:property name="sql" value="insert into t_destcredit (ID,ACCOUNTID,NAME,AMOUNT,DATE,ADDRESS) values (:id,:accountID,:name,:amount,:date,:address)"/>
        <bean:property name="itemSqlParameterSourceProvider">
            <bean:bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider"/>
        </bean:property>
    </bean:bean>
 

### 如何解决Spring Batch远程分区分片处理耗时差异大不均衡问题 #### 背景介绍 在企业应用中,批处理任务对于日常运营至关重要。然而,在执行大规模数据处理时,可能会遇到资源分配不均的问题,特别是在分布式环境中使用远程分区策略时[^1]。 #### 远程分区的概念及其挑战 为了提高性能,Spring Batch引入了`Partitioning`(分区)机制,允许将工作负载划分为多个独立的部分来并行执行。当涉及到跨不同节点上的远程分区时,如果各部分之间的工作量存在显著差异,则可能导致某些工作者完成得更快而其他仍在忙碌的状态,从而降低了整体吞吐率和效率[^3]。 #### 动态调整Chunk Size以平衡负载 一种可能的方法是在配置阶段尝试预测每一片区所需的时间,并据此设置不同的chunk大小。通过这种方式可以使得较重的任务拥有更大的批次提交单位,减少事务频率;而对于那些预计会很快结束的小型作业则采用较小的批量尺寸加快响应速度。不过这种方法依赖于预先估计的能力以及良好的历史数据分析作为依据[^2]。 ```java @Bean public Step partitionedStep() { return stepBuilderFactory.get("partitionedStep") .<String, String> chunk(1000)//动态计算此值 .reader(itemReader()) .processor(itemProcessor()) .writer(itemWriter()) .partitioner(slaveStep(), new CustomPartitioner())//自定义分区器实现逻辑判断 .gridSize(gridSize) .taskExecutor(taskExecutor()) .build(); } ``` #### 使用智能调度算法重新分配剩余未完成项 另一种更为灵活的方式是监控各个子任务的实际进度情况,在发现有明显滞后现象发生时主动介入干预——即将已完成片区内多余出来的资源调配给落后者继续其后续待办事项直至全部结束为止。这通常涉及到了额外的心跳检测机制或是专门设计用于协调此类活动的服务组件。 #### 实施细粒度控制与反馈循环 最后还可以考虑增加更多层次上的精细化管理措施比如按需启动/停止特定实例、实时跟踪状态变化趋势等手段进一步增强系统的适应性和鲁棒性。同时建立有效的日志记录体系以便事后审查整个过程中的表现特征找出潜在改进空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值