Java+MySQL开发智能农业监控系统(传感器数据+预警通知)
·
技术选型与架构设计
后端框架:Spring Boot 2.7.x(简化配置,集成Web/定时任务)
数据库:MySQL 8.0(时序数据存储)+ Redis(缓存实时数据)
通信协议:MQTT(传感器数据传输)+ HTTP(管理端交互)
前端技术:Vue.js + ECharts(数据可视化)
数据库设计
-- 传感器设备表
CREATE TABLE `sensor_device` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50) NOT NULL COMMENT '设备名称',
`location` POINT NOT NULL COMMENT 'GPS坐标',
`status` TINYINT DEFAULT 1 COMMENT '1在线 0离线'
);
-- 传感器数据记录表(按月份分表)
CREATE TABLE `sensor_data_202307` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`device_id` INT NOT NULL,
`temperature` DECIMAL(5,2) COMMENT '温度℃',
`humidity` DECIMAL(5,2) COMMENT '湿度%',
`soil_moisture` DECIMAL(5,2) COMMENT '土壤湿度%',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_device_time` (`device_id`, `created_at`)
) PARTITION BY RANGE (UNIX_TIMESTAMP(created_at)) (
PARTITION p202307 VALUES LESS THAN (UNIX_TIMESTAMP('2023-08-01'))
);
-- 预警规则表
CREATE TABLE `alert_rule` (
`id` INT PRIMARY KEY,
`device_type` VARCHAR(20) NOT NULL,
`metric_type` ENUM('temperature','humidity','soil_moisture'),
`operator` ENUM('>','<','=','≠'),
`threshold` DECIMAL(10,2) NOT NULL,
`severity` ENUM('critical','warning')
);
核心功能实现
MQTT数据接收处理
@Component
public class MqttSensorListener implements MqttCallback {
@Autowired
private SensorDataService dataService;
@Override
public void messageArrived(String topic, MqttMessage message) {
String payload = new String(message.getPayload());
SensorData data = JSON.parseObject(payload, SensorData.class);
// 数据校验
if(data.getTemperature() < -50 || data.getTemperature() > 100) {
throw new InvalidDataException("温度值异常");
}
// 异步写入数据库
CompletableFuture.runAsync(() -> {
dataService.saveData(data);
checkAlertRules(data); // 触发预警检查
});
}
}
动态预警规则检查
public void checkAlertRules(SensorData data) {
List<AlertRule> rules = ruleDao.getRulesByDeviceType(data.getDeviceType());
rules.forEach(rule -> {
double actualValue = getValueByMetric(data, rule.getMetricType());
if(checkCondition(actualValue, rule.getOperator(), rule.getThreshold())) {
Alert alert = new Alert();
alert.setDeviceId(data.getDeviceId());
alert.setRuleId(rule.getId());
alert.setActualValue(actualValue);
alertDao.save(alert);
// 推送通知
pushNotification(alert);
}
});
}
private boolean checkCondition(double value, String operator, double threshold) {
switch(operator) {
case ">": return value > threshold;
case "<": return value < threshold;
case "=": return Math.abs(value - threshold) < 0.01;
case "≠": return Math.abs(value - threshold) > 0.01;
default: return false;
}
}
性能优化方案
数据存储优化
- 使用MySQL分区表按时间范围存储传感器数据
- 超过3个月的数据自动归档到ClickHouse
- 实时数据双写Redis(SortedSet结构存储最新100条)
预警通知降级策略
@Slf4j
@Service
public class NotificationService {
@Resource
private SMSProvider smsProvider;
@Resource
private EmailSender emailSender;
@Retryable(maxAttempts=3, backoff=@Backoff(delay=1000))
public void sendAlert(Severity severity, String message) {
switch(severity) {
case CRITICAL:
smsProvider.send(message); // 短信优先
break;
case WARNING:
emailSender.send(message); // 邮件通知
break;
}
}
@Recover
public void recoverSend(Exception e, Severity severity, String message) {
log.error("通知发送失败,降级到站内信", e);
saveToMessageQueue(message); // 最终一致性处理
}
}
数据可视化接口
RESTful API设计
@RestController
@RequestMapping("/api/sensor")
public class SensorDataController {
@GetMapping("/{deviceId}/stats")
public ResponseEntity<DataStats> getHourlyStats(
@PathVariable int deviceId,
@RequestParam @DateTimeFormat(iso=ISO.DATE_TIME) LocalDateTime start,
@RequestParam @DateTimeFormat(iso=ISO.DATE_TIME) LocalDateTime end) {
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(5, TimeUnit.MINUTES))
.body(dataService.getStats(deviceId, start, end));
}
@GetMapping("/{deviceId}/history")
public List<SensorData> getHistoryData(
@PathVariable int deviceId,
@RequestParam(defaultValue="1d") String duration) {
TemporalAmount period = Duration.parse("PT" + duration.toUpperCase());
LocalDateTime end = LocalDateTime.now();
LocalDateTime start = end.minus(period);
return dataService.queryRange(deviceId, start, end);
}
}
系统安全措施
- 设备认证:每个传感器设备使用TLS双向认证,MQTT连接需验证客户端证书
- 数据加密:敏感字段使用AES-256加密存储,密钥由KMS管理
- 权限控制:基于Spring Security实现RBAC模型
- 审计日志:记录所有数据修改操作,使用Elasticsearch存储日志
部署方案
容器化部署
# 数据库服务
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
ports:
- "3306:3306"
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- ./redis/data:/data
性能监控
- Prometheus采集JVM/MySQL指标
- Grafana展示实时监控看板
- 关键业务指标埋点:
- 数据接收延迟(ms)
- 预警触发准确率(%)
- 通知送达成功率(%)
更多推荐

所有评论(0)