要使用Java编写网页监控程序,核心思路是通过定时检测目标网页的状态(如可用性、响应时间、内容变化等),并在异常时触发告警,以下是详细的实现步骤,包括技术选型、代码结构、关键功能实现及部署建议。

技术选型与环境准备
核心库选择:
- HTTP请求:使用
HttpURLConnection(JDK内置)或第三方库如Apache HttpClient、OkHttp,后者支持异步请求和更丰富的功能。 - 定时任务:
java.util.Timer(简单场景)或Spring Scheduler(Spring框架)、Quartz(复杂调度)。 - JSON/XML解析:
Jackson、Gson(JSON),DOM4J、JAXB(XML)。 - 日志记录:
SLF4J+Logback,便于调试和问题追踪。 - 数据库存储:
MySQL/PostgreSQL(关系型)或MongoDB(非关系型),用于存储监控历史数据。 - 告警通知:邮件(
JavaMail)、短信(第三方API如阿里云短信)、企业微信/钉钉机器人(HTTP API调用)。
- HTTP请求:使用
开发环境:
- JDK 8+(推荐11+ LTS版本)
- Maven/Gradle(依赖管理)
- IDE(IntelliJ IDEA/Eclipse)
程序核心功能实现
HTTP请求模块
通过HTTP GET/POST请求获取网页内容,并校验响应状态码和响应时间,示例代码(使用HttpURLConnection):
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.time.Duration;
import java.time.Instant;
public class WebMonitor {
public static MonitorResult checkUrl(String urlString) {
Instant start = Instant.now();
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000); // 5秒连接超时
connection.setReadTimeout(10000); // 10秒读取超时
int statusCode = connection.getResponseCode();
Instant end = Instant.now();
long responseTime = Duration.between(start, end).toMillis();
String content = "";
if (statusCode == 200) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
content += line;
}
}
}
return new MonitorResult(statusCode, responseTime, content);
} catch (Exception e) {
return new MonitorResult(-1, Duration.between(start, Instant.now()).toMillis(), e.getMessage());
}
}
}
class MonitorResult {
private int statusCode;
private long responseTime;
private String content;
// 构造方法、getter略
}定时任务调度
使用Spring Scheduler实现定时监控(需添加@EnableScheduling注解):

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class MonitorScheduler {
@Scheduled(fixedRate = 60000) // 每分钟执行一次
public void monitorWebsites() {
List<String> urls = List.of("https://www.example.com", "https://test.com");
urls.forEach(url -> {
MonitorResult result = WebMonitor.checkUrl(url);
if (result.getStatusCode() != 200) {
AlertService.sendAlert(url, result);
}
// 存储结果到数据库
DatabaseService.saveResult(url, result);
});
}
}内容变化检测
通过对比网页内容的哈希值或关键字段判断是否变更:
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class ContentChangeDetector {
public static boolean hasChanged(String oldContent, String newContent) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] oldHash = digest.digest(oldContent.getBytes(StandardCharsets.UTF_8));
byte[] newHash = digest.digest(newContent.getBytes(StandardCharsets.UTF_8));
return !MessageDigest.isEqual(oldHash, newHash);
} catch (Exception e) {
return false;
}
}
}告警通知模块
以邮件告警为例(使用JavaMail):
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
public class AlertService {
public static void sendAlert(String url, MonitorResult result) {
String to = "admin@example.com";
String subject = "网页监控告警:" + url;
String body = String.format("状态码:%d\n响应时间:%dms\n错误:%s",
result.getStatusCode(), result.getResponseTime(), result.getContent());
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.example.com");
props.put("mail.smtp.auth", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("monitor@example.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}数据库存储设计
使用MySQL存储监控记录,表结构示例:
| 字段名 | 类型 | 说明 |
|—————-|————–|——————–|
| id | BIGINT | 主键,自增 |
| url | VARCHAR(255) | 监控的URL |
| status_code | INT | HTTP状态码 |
| response_time | BIGINT | 响应时间(毫秒) |
| check_time | TIMESTAMP | 检测时间 |
| error_message | TEXT | 错误信息(如有) |
高级功能扩展
- 多线程监控:使用
ExecutorService并发检测多个URL,提高效率。 - SSL证书检查:通过
X509TrustManager验证目标网站的SSL证书有效性。 - 代理支持:在
HttpURLConnection中设置代理服务器地址,适用于内网环境。 - 可视化报表:集成
ECharts或JasperReports生成响应时间趋势图、可用率统计等。
部署与运维
- 打包为可执行JAR:使用Maven Shade Plugin或Spring Boot Maven Plugin生成包含依赖的JAR文件。
- 系统服务化:通过
systemd(Linux)或NSSM(Windows)将程序注册为后台服务。 - 日志管理:配置
Logback按日期分割日志文件,并设置保留天数。 - 监控自身状态:添加程序健康检查接口(如
/health),通过Prometheus+Grafana监控。
相关问答FAQs
Q1: 如何处理网页需要登录才能访问的情况?
A: 可以通过以下方式解决:

- Session管理:首次请求时获取登录页面的
Set-Cookie,后续请求携带该Cookie维持会话。 - 表单提交:解析登录页面的表单结构(如
action、input字段),使用HttpClient模拟POST提交登录数据。 - Headless浏览器:对于复杂验证(如JavaScript渲染),集成
Selenium或Playwright控制无头浏览器完成登录。
Q2: 如何优化监控程序的资源占用?
A: 从以下方面优化:
- 连接池复用:使用
HttpClient的PoolingHttpClientConnectionManager管理HTTP连接,避免频繁创建/销毁连接。 - 异步非阻塞:采用
CompletableFuture或Spring WebFlux(基于Netty)实现异步IO,减少线程阻塞。 - 增量检测:仅检测网页内容的关键部分(如特定
<div>),而非完整HTML,减少数据传输量。 - 缓存策略:对短期内未变化的URL降低检测频率(如从1分钟/次调整为5分钟/次)。
文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/384584.html<
