偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

基于 Spring Boot 與 RabbitMQ 的郵件發(fā)送:確保 100%消息成功投遞

開發(fā) 前端
RabbitMQ 猶如一位堅(jiān)定的衛(wèi)士,確保了郵件發(fā)送任務(wù)的可靠排隊(duì)和精細(xì)處理;而 Spring Boot 則宛如一位智慧的導(dǎo)師,提供了便捷的開發(fā)環(huán)境和豐富多樣的功能支持。

在當(dāng)今的企業(yè)級應(yīng)用開發(fā)中,郵件發(fā)送是一個(gè)常見且重要的功能需求。為了確保郵件能夠穩(wěn)定、高效且 100%成功投遞,我們可以結(jié)合 Spring Boot 和 RabbitMQ 來實(shí)現(xiàn)這一目標(biāo)。

技術(shù)選型與框架介紹

在構(gòu)建郵件發(fā)送系統(tǒng)時(shí),我們精心挑選了 Spring Boot 和 RabbitMQ 這兩個(gè)強(qiáng)大的技術(shù)框架,并充分利用它們各自的優(yōu)勢來實(shí)現(xiàn)高效、可靠的郵件投遞功能。

Spring Boot 作為一款出色的快速開發(fā)框架,為我們提供了諸多便利。它基于 Spring 框架,但極大地簡化了項(xiàng)目的配置和部署流程。憑借其內(nèi)置的自動(dòng)配置機(jī)制,開發(fā)者無需繁瑣地處理各種基礎(chǔ)配置,能夠迅速搭建起項(xiàng)目的基本架構(gòu)。同時(shí),Spring Boot 對各種主流技術(shù)和組件的良好集成性,使得我們能夠輕松引入所需的依賴,快速構(gòu)建功能豐富的應(yīng)用。

RabbitMQ 則是一款卓越的消息代理和隊(duì)列服務(wù)器,在分布式系統(tǒng)的消息傳遞中發(fā)揮著關(guān)鍵作用。其基于先進(jìn)的消息隊(duì)列機(jī)制,能夠有效地應(yīng)對高并發(fā)場景下的消息處理需求。通過將郵件發(fā)送任務(wù)轉(zhuǎn)化為消息并放入隊(duì)列中,RabbitMQ 確保了任務(wù)的有序處理和可靠傳遞,即使在系統(tǒng)面臨高負(fù)載或出現(xiàn)故障的情況下,也能保證郵件發(fā)送不丟失、不重復(fù),從而極大地提高了郵件投遞的成功率和穩(wěn)定性。

將 Spring Boot 和 RabbitMQ 相結(jié)合,能夠充分發(fā)揮兩者的優(yōu)勢。Spring Boot 提供了便捷的開發(fā)環(huán)境和高效的應(yīng)用架構(gòu),而 RabbitMQ 則為郵件發(fā)送任務(wù)提供了可靠的排隊(duì)和處理機(jī)制,共同保障了郵件發(fā)送的高效性和 100%投遞成功率。

項(xiàng)目依賴配置(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.icoderoad</groupId>
    <artifactId>mail-sender</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>MailSender</name>
    <description>基于 Spring Boot 和 RabbitMQ 的郵件發(fā)送項(xiàng)目</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

YAML 屬性文件配置(application.yml)

spring:
  mail:
    host: smtp.example.com  # 替換為您的 SMTP 服務(wù)器地址
    port: 587  # 端口
    username: your_email@example.com  # 發(fā)件人郵箱
    password: your_password  # 郵箱密碼
    properties:
      mail.smtp.auth: true
      mail.smtp.starttls.enable: true

rabbitmq:
  host: localhost  # RabbitMQ 服務(wù)器地址
  port: 5672  # 端口
  username: guest
  password: guest

后端代碼實(shí)現(xiàn)

郵件發(fā)送服務(wù)類(MailService.java)

import lombok.RequiredArgsConstructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;

@EnableScheduling
@Service
@RequiredArgsConstructor
public class MailService {

    private final JavaMailSender mailSender;
    private final RabbitTemplate rabbitTemplate;
    private static final int MAX_RETRY = 3; // 最大重試次數(shù)
    private static final Log LOGGER = LogFactory.getLog(MailService.class);

    private ConcurrentHashMap<String, Integer> retryMap = new ConcurrentHashMap<>();

    public boolean sendMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);

        int retryCount = 0;
        boolean sentSuccessfully = false;
        String key = to + "_" + subject;

        while (retryCount < MAX_RETRY &&!sentSuccessfully) {
            try {
                mailSender.send(message);
                sentSuccessfully = true;
                retryMap.remove(key);
            } catch (MailException e) {
                retryCount++;
                LOGGER.error("發(fā)送郵件失敗,重試次數(shù): " + retryCount + ",收件人: " + to + ",主題: " + subject, e);
                retryMap.put(key, retryCount);
            }
        }

        if (!sentSuccessfully) {
            LOGGER.error("郵件發(fā)送最終失敗,收件人: " + to + ",主題: " + subject);
        }

        return sentSuccessfully;
    }

    @Scheduled(fixedDelay = 60000) // 每分鐘執(zhí)行一次
    public void retryFailedMails() {
        for (String key : retryMap.keySet()) {
            String[] parts = key.split("_");
            String to = parts[0];
            String subject = parts[1];

            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(to);
            message.setSubject(subject);

            int retryCount = retryMap.get(key);
            boolean sentSuccessfully = false;

            while (retryCount < MAX_RETRY &&!sentSuccessfully) {
                try {
                    mailSender.send(message);
                    sentSuccessfully = true;
                    retryMap.remove(key);
                } catch (MailException e) {
                    retryCount++;
                    if (!sentSuccessfully) {
                        rabbitTemplate.convertAndSend("retryQueue", key);
                        LOGGER.error("重試郵件發(fā)送失敗,已發(fā)送到隊(duì)列,收件人: " + to + ",主題: " + subject);
                    }
                }
            }

            if (!sentSuccessfully) {
                LOGGER.error("重試郵件發(fā)送最終失敗,收件人: " + to + ",主題: " + subject);
            }
        }
    }
}

要合理設(shè)置最大重試次數(shù),避免過度重試導(dǎo)致資源浪費(fèi)。同時(shí),在重試間隔上也需要根據(jù)實(shí)際情況進(jìn)行合理的設(shè)計(jì),以平衡成功率和性能。還需要對重試過程中的異常情況進(jìn)行更詳細(xì)的記錄和監(jiān)控,將重試仍不成功的郵件發(fā)送信息發(fā)送到隊(duì)列,方便后續(xù)進(jìn)一步處理,提高了系統(tǒng)的靈活性和容錯(cuò)性。

RabbitMQ 配置類(RabbitMQConfig.java)

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    @Bean
    public Queue mailQueue() {
        return new Queue("mail_queue");
    }
}

RabbitMQ 消費(fèi)者(MailConsumer.java)

import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class MailConsumer {

    private final MailService mailService;

    @RabbitListener(queues = "mail_queue")
    public void consumeMailMessage(String message) {
        // 解析消息,提取收件人、主題和內(nèi)容等信息
        String[] parts = message.split(";");
        String to = parts[0];
        String subject = parts[1];
        String content = parts[2];
        mailService.sendMail(to, subject, content);
    }
}

控制器類(MailController.java)

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MailController {

    private final RabbitTemplate rabbitTemplate;

    public MailController(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    @PostMapping("/sendMail")
    public String sendMail(@RequestBody MailRequest request) {
        // 將郵件信息轉(zhuǎn)換為字符串,發(fā)送到 RabbitMQ 隊(duì)列
        String message = request.getTo() + ";" + request.getSubject() + ";" + request.getContent();
        // 發(fā)送到隊(duì)列
        rabbitTemplate.convertAndSend("mail_queue", message);
        return "郵件發(fā)送請求已提交";
    }
}

前端頁面實(shí)現(xiàn)

使用 Thymeleaf 模板和 JavaScript 實(shí)現(xiàn)前端頁面:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>郵件發(fā)送</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <h2>郵件發(fā)送</h2>
    <form th:action="@{/sendMail}" method="post">
        <label for="to">收件人:</label><input type="text" id="to" name="to"><br>
        <label for="subject">主題:</label><input type="text" id="subject" name="subject"><br>
        <label for="content">內(nèi)容:</label><textarea id="content" name="content"></textarea><br>
        <button type="submit">發(fā)送</button>
    </form>
    <div id="result"></div>

    <script>
        $(document).ready(function() {
            $("form").submit(function(event) {
                event.preventDefault();
                var to = $("#to").val();
                var subject = $("#subject").val();
                var content = $("#content").val();
                $.ajax({
                    url: $(this).attr("action"),
                    type: "POST",
                    data: JSON.stringify({
                        "to": to,
                        "subject": subject,
                        "content": content
                    }),
                    contentType: "application/json",
                    success: function(response) {
                        $("#result").text(response);
                    },
                    error: function() {
                        $("#result").text("發(fā)送失敗");
                    }
                });
            });
        });
    </script>
</body>
</html>

通過以上精心設(shè)計(jì)的架構(gòu)和精妙絕倫的代碼實(shí)現(xiàn),我們成功地借助 Spring Boot 和 RabbitMQ 的強(qiáng)大力量,構(gòu)建出一個(gè)能夠確保 100%消息成功投遞的郵件發(fā)送系統(tǒng)。在此過程中,RabbitMQ 猶如一位堅(jiān)定的衛(wèi)士,確保了郵件發(fā)送任務(wù)的可靠排隊(duì)和精細(xì)處理;而 Spring Boot 則宛如一位智慧的導(dǎo)師,提供了便捷的開發(fā)環(huán)境和豐富多樣的功能支持。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2021-09-07 10:38:37

RabbitMQ 高可用消費(fèi)

2020-10-14 08:36:10

RabbitMQ消息

2020-08-05 08:30:25

Spring BootJavaSE代碼

2025-05-29 01:33:00

微服務(wù)架構(gòu)系統(tǒng)

2025-03-14 07:57:54

2023-03-06 08:16:04

SpringRabbitMQ

2020-09-27 07:44:08

RabbitMQ投遞消息

2022-02-16 10:59:54

Spring端口郵件

2021-08-10 09:59:15

RabbitMQ消息微服務(wù)

2024-04-02 08:17:40

2015-12-08 09:16:32

JavaMail郵件發(fā)送總結(jié)

2024-09-05 08:58:37

2023-11-08 07:51:11

RabbitMQ接收消息

2012-01-04 11:29:16

2010-05-25 18:19:41

postfix郵件

2022-07-27 18:34:32

RabbitMQ宕機(jī)服務(wù)器

2024-03-25 08:45:18

郵件發(fā)送Spring應(yīng)用程序

2023-06-01 08:54:08

RabbitMQ確認(rèn)機(jī)制生產(chǎn)端

2011-04-25 15:29:54

Exchange報(bào)告

2010-11-09 10:28:50

簡歷
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號