Как отправить электронное письмо, если одни и те же данные вставляются в PostgreSQL непрерывно в течение 1 часа?

Вопрос или проблема

Я разрабатываю серверное приложение с использованием Spring Boot, и в моем приложении используется PostgreSQL в качестве базы данных. Данные с датчиков вставляются в базу данных каждую секунду.

Я хочу мониторить данные и отправлять уведомление по электронной почте, если одно и то же значение вставляется в базу данных непрерывно в течение 1 часа. Например:

Если значение 42 вставляется в таблицу каждую секунду в течение 1 часа, я хочу это обнаружить и отправить электронное письмо.
Вот мои основные вопросы:

Должен ли я реализовать эту логику в своем приложении Spring Boot (например, используя запланированную задачу для запроса и мониторинга данных)?
Лучше ли обрабатывать это целиком в PostgreSQL (например, используя триггеры или другие механизмы базы данных)?
Каковы плюсы и минусы каждого подхода, и какой из них вы бы порекомендовали для этого случая? Если возможно, я буду признателен за примеры кода или советы по реализации.

Ответ или решение

Для решения задачи мониторинга вставляемых данных в PostgreSQL и отправки уведомлений по электронной почте при обнаружении повторяющихся значений в течение одного часа, вы можете выбрать один из двух подходов: реализация логики на стороне Spring Boot или использование механизмов базы данных. Давайте рассмотрим оба варианта, их преимущества и недостатки.

Подход 1: Реализация логики в Spring Boot

Принцип работы

В этом подходе вы можете использовать планировщик задач Spring (например, @Scheduled), который будет выполнять SQL-запросы к базе данных через регулярные промежутки времени, например каждую минуту. Этот запрос будет проверять количество повторений одного и того же значения в течение последнего часа.

Пример реализации

  1. Создание метода для проверки данных
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;

@Service
public class SensorDataMonitor {

    @Autowired
    private DataRepository dataRepository;

    @Autowired
    private EmailService emailService;

    @Scheduled(fixedRate = 60000) // каждые 60 секунд
    public void checkRepeatedData() {
        int threshold = 3600; // 60 секунд * 60 минут
        Map<Integer, Long> repeatedValues = dataRepository.findRepeatedValues(threshold);

        for (Map.Entry<Integer, Long> entry : repeatedValues.entrySet()) {
            if (entry.getValue() >= 3600) { // 1 час
                emailService.sendAlert(entry.getKey());
            }
        }
    }
}
  1. Запрос для получения повторяющихся значений
public Map<Integer, Long> findRepeatedValues(int threshold) {
    String sql = "SELECT sensor_value, COUNT(*) FROM sensor_data " +
                 "WHERE timestamp >= NOW() - INTERVAL '1 hour' " +
                 "GROUP BY sensor_value HAVING COUNT(*) >= ?";
    return jdbcTemplate.query(sql, new Object[]{threshold}, rs -> {
        Map<Integer, Long> result = new HashMap<>();
        while (rs.next()) {
            result.put(rs.getInt("sensor_value"), rs.getLong("count"));
        }
        return result;
    });
}
  1. Сервис для отправки уведомлений
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;

@Service
public class EmailService {

    @Autowired
    private JavaMailSender mailSender;

    public void sendAlert(int sensorValue) throws MessagingException {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo("recipient@example.com");
        message.setSubject("Повторяющееся значение датчика");
        message.setText("Значение " + sensorValue + " повторяется более часа.");
        mailSender.send(message);
    }
}

Преимущества и недостатки:

  • Плюсы:

    • Легкость в понимании и отладке.
    • Использование бизнес-логики приложения для обработки данных.
  • Минусы:

    • Увеличенные нагрузки на приложение, особенно если данные поступают часто.
    • Сложность синхронизации и обработки в реальном времени.

Подход 2: Реализация в PostgreSQL

Принцип работы

В этом подходе можно использовать триггеры для отслеживания вставляемых данных и создавать отдельную таблицу или использовать функции PostgreSQL для агрегирования значений.

Пример реализации

  1. Создание триггера и функции
CREATE OR REPLACE FUNCTION check_repeated_values() RETURNS TRIGGER AS $$
DECLARE
    count_records INT;
BEGIN
    SELECT COUNT(*) INTO count_records
    FROM sensor_data
    WHERE sensor_value = NEW.sensor_value
    AND timestamp >= NOW() - INTERVAL '1 hour';

    IF count_records >= 3600 THEN
        PERFORM send_email(NEW.sensor_value); -- Подразумевается, что у вас есть функция send_email
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER monitor_sensor_data
AFTER INSERT ON sensor_data
FOR EACH ROW
EXECUTE FUNCTION check_repeated_values();

Преимущества и недостатки:

  • Плюсы:

    • Меньшая нагрузка на приложение.
    • Реакция на события в реальном времени, без необходимости периодических опросов.
  • Минусы:

    • Сложность в написании и отладке SQL-кода и триггеров.
    • Ограниченный контроль над логикой приложения, так как часть обработка идет непосредственно в базе данных.

Рекомендации

Выбор между этими подходами зависит от специфики вашего приложения и предпочтений в разработке. Если ваше приложение требует возле реального времени или если данные вводятся в большом количестве, то реализация триггеров в PostgreSQL будет более эффективной.

Заключение

Оба подхода имеют свои сильные и слабые стороны. Для менее загруженных систем и большей гибкости в логике лучше использовать Spring Boot, для высоких нагрузок и скорости реакции – встроенные возможности PostgreSQL. Важно провести тестирование и выбор оптимального решения, исходя из ваших требований и инфраструктуры.

Оцените материал
Добавить комментарий

Капча загружается...