RabbitMQ 客户端 利用反射技术实现自定义springboot stater,实现多系统之间数据同步

1. 导读

本文主要讲述RabbitMQ客户端的封装和使用,思路不一定准确,但目前生产中是这样使用的,有不对的地方,欢迎批评指正。

本文需要对springboot、spring的spel表达式、rabbitmq工作流程、死信队列机制有一定的了解,熟悉springboot starter的大概思路。

客户端思路
定义客户端
定义所有实体类的父类InterfaceFactoryBean
实现ImportBeanDefinitionRegistrar,扫描自定义注解标注的路径
公用service接口,第三方持久层需实现

2. 客户端

最近公司微服务架构中有需要同步数据库表数据的需求,考虑到封装性和扩展性,减少第三方项目的开发工作量,思路如下(本文不涉及缓存):

2.1. 服务端创建Fanout模式的交换机,提供数据发送接口
2.2. 封装客户端,客户端作为jar包存在,供第三方项目(其他项目,以下都以第三方代称)依赖使用
2.3. 第三方项目依赖的客户端启动创建队列绑定上面的交换机,并创建死信交换机、队列
2.4. 第三方项目依赖的客户端接到数据后,通过反射执行第三方实现的客户端中定义的持久层接口,实现数据入库。
2.5定义死信队列接收消费失败的消息,死信队列通过RestTemplate入库,客户端实现
2.6. 失败的消息会重试3次,重试后再次失败,消息进入死信队列。每次新接收的消息会检查库中是否存在同类型的死信,如果有,直接入库,然后尝试消费当前第一条,成功就继续,失败则终止。(同步的是人员、机构等数据,对顺序性要求高)

3. 开始撸代码 – 客户端

3.1 创建一个spring boot 项目引入依赖如下:

<dependency>
  	   <groupId>org.springframework.boot</groupId>
  	   <artifactId>spring-boot-starter-web</artifactId>
  	   <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
  	</dependency>
	<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
  	<dependency>
	  <groupId>org.projectlombok</groupId>
	  <artifactId>lombok</artifactId>
	</dependency>
	<dependency>
	  <groupId>com.chinacoal.microservice</groupId>
      <artifactId>common-utils</artifactId>
  	  <version>1.0-SNAPSHOT</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-configuration-processor</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
	  <groupId>com.alibaba</groupId>
	  <artifactId>fastjson</artifactId> 
	  <version>1.1.23</version> 
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-jdbc</artifactId>
	</dependency> 

3.2 定义客户端:

@Autowired
private QueueConfig queueConfig;

@RabbitListener(exclusive = false,bindings=@QueueBinding(
			  value=@Queue(autoDelete = "false",durable = "true",value = "#{queueConfig.getName()}",arguments = {
						 @Argument(name = "x-dead-letter-exchange", value = "#{queueConfig.getDLX_EXCHANGE_NAME()}"),
						 @Argument(name = "x-dead-letter-routing-key", value ="#{queueConfig.getROUTE_KEY()}"),
						 @Argument(name = "x_message_ttl", value = "30000")
				 }),exchange=@Exchange(value = "orgFanoutExchange", durable = "true",type = ExchangeTypes.FANOUT,autoDelete = "false")))
    public void receiveMessage(String receiveMessage, Message message, Channel channel) throws Exception  {  
            // 手动签收  
            log.info("接收到消息:[{}]", receiveMessage);  
           
            //执行业务逻辑
			try {
				if(doWork(receiveMessage,message)) {
					//throw new FileUploadException();
					channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
				}else {
					channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
				}
			} catch (Exception e) {
				 log.error("消息签收失败:", e);
				
				 Integer count = Integer.valueOf(String.valueOf(message.getMessageProperties().getHeaders().get("count")));
				 if(count >= 3) {
					 channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
				 }else {
					 message.getMessageProperties().getHeaders().put("count", count + 1);
					 throw e;
				 }
			}
			
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值