Springboot支払受注タイムアウト自動処理

6083 ワード

今日出会ったシーンはタイトルのようです.
             (            )。 

思いついた解決策
1.    
2.redis 【Redis     (keyspace & keyevent notification)】

(https://blog.csdn.net/qijiqiguai/article/details/78229111)ここに紹介があります
3.rabbitmq     

主にシナリオ2とシナリオ3をそれぞれお話しします
シナリオ2:マシン上のredisプロファイルconf/redisを見つける.conf,新規行notify-keyspace-events Ex
プロファイルの変更が完了したらredisサービスを再起動します.
(コンフィギュレーションファイルが変更されても有効でない場合は、redis-cliコマンドラインインタフェースに入り、非永続化コンフィギュレーションCONFIGset notify-keyspace-events Exを使用します)
コードは以下の通りです.例は直接走ることができます.TopicMessageListener onMessageメソッドの下でポイントを中断すると、期限切れのredis値がブレークポイントに入ることがわかります.https://github.com/KingestCode/redisnotify.git
シナリオ3:RabbitMQ遅延メッセージ実装
  • 前提rabbitmq 2)インストール遅延プラグインがインストールされているhttp://www.rabbitmq.com/community-plugins.html

  • 必ずバージョン番号を選んでください.私はRabbitMQ 3.7.4を使っているので、rabbitmqに対応しています.delayed_message_Exchangeプラグインも3.7を選択する必要があります.xの.
    プラグインをダウンロードした後、RabbitMQインストールディレクトリのpluginsディレクトリに配置し、次のコマンドを使用してプラグインを起動します.
    ./rabbitmq-plugins enable rabbitmq_delayed_message_exchange
    統合RabbitMQ
    
            org.springframework.boot
            spring-boot-starter-amqp
    
    

    アプリケーションでymlはrabbitmqの構成に参加します
    spring.rabbitmq.host=127.0.0.1
    server:
      port: 8081
    redis:
      hostname: localhost
      port: 6379
    spring:
      rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        password: guest
        virtual-host: /
        publisher-confirms: true
        publisher-returns: true
        template:
          mandatory: true
        connection-timeout: 15000
    

    RabbitMqConfig
    
    @Configuration
    @ConfigurationProperties(prefix = "spring.rabbitmq")
    public class RabbitMqConfig {
        private String host;
        private int port;
        private String userName;
        private String password;
    
        @Bean
        public ConnectionFactory connectionFactory() {
            CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(host,port);
            cachingConnectionFactory.setUsername(userName);
            cachingConnectionFactory.setPassword(password);
            cachingConnectionFactory.setVirtualHost("/");
            cachingConnectionFactory.setPublisherConfirms(true);
            return cachingConnectionFactory;
        }
    
        @Bean
        public RabbitTemplate rabbitTemplate() {
            RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
            return rabbitTemplate;
        }
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
    }
    
    

    QueueConfig
    
    @Configuration
    public class QueueConfig {
        @Bean
        public CustomExchange delayExchange() {
            Map args = new HashMap<>();
            args.put("x-delayed-type", "direct");
            return new CustomExchange("test_exchange", "x-delayed-message",true, false,args);
        }
    
        @Bean
        public Queue queue() {
            Queue queue = new Queue("test_queue_1", true);
            return queue;
        }
    
        @Bean
        public Binding binding() {
            return BindingBuilder.bind(queue()).to(delayExchange()).with("test_queue_1").noargs();
        }
    
    }
    

    メッセージ送信:MessageServiceImpl
    
    @Service
    public class MessageServiceImpl {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void sendMsg(String queueName,String msg) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("      :"+sdf.format(new Date()));
            rabbitTemplate.convertAndSend("test_exchange", queueName, msg, new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    message.getMessageProperties().setHeader("x-delay",3000);
                    return message;
                }
            });
        }
    }
    
    

    メッセージ受信:MessageReceiver
    @Component
    public class MessageReceiver {
    
        @RabbitListener(queues = "test_queue_1")
        public void receive(String msg) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("      :"+sdf.format(new Date()));
            System.out.println("      :"+msg);
        }
    }
    

    テストクラス:RabbitmqApplicationTests
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = UserApplication.class)
    public class RabbitmqApplicationTests {
        @Autowired
        private MessageServiceImpl messageService;
    
        @Test
        public void send() {
            messageService.sendMsg("test_queue_1","hello i am delay msg");
        }
    
    }
    
    

    実行後、メッセージ送信時間:2018-05-03 12:44:53秒後、Spring Bootコンソールから出力されます.メッセージ受信時間:2018-05-03 12:44:56受信メッセージ:hello i am delay msg
    最後に、タイミングタスクとredisとrabbitmqの違いについて説明します.その実用的なタイミングタスクは、確かに問題があります.もともと業務システムは10分後、注文が支払われていない場合は、すぐに注文をキャンセルし、商品の在庫を解放することを望んでいました.しかし、データ量が大きくなると、未払いの注文データを取得する時間が長くなり、一部の注文は10分もしないうちにキャンセルされ、15分、20分などかもしれません.そうすると、在庫がすぐに解放されず、単数化にも影響します.遅延メッセージを利用すれば,理論的には設定された時間に従って注文キャンセル操作を行うことができる.
    現在、RabbitMQを用いた遅延メッセージの実装に関するネット上の記事の多くは、RabbitMQのデッドメッセージキューをどのように利用して実現するかを説明しており、実装案は煩雑で複雑に見え、元のRabbitMQ Client APIを用いて実現されているが、さらに煩雑である.
    Spring BootはすでにRabbitMQ Client APIをパッケージ化しており、使いやすくなっています.以下、rabbitmqの利用方法について詳しく説明します.delayed_message_ExchangeプラグインとSpring Bootは、遅延メッセージを実現します.
    redisとrabbitmqの方式はデータの正確性を保証します
    rabbitmq関連コードが必要な場合はメッセージを残してください.の