域名备案好了后怎么做网站,网络运营商电话,西安到北京高铁,网站开发流程管理如何实现Web应用、网站状态的监控#xff1f;
关键词#xff1a;网站监控,服务器监控,页面性能监控,用户体验监控本文通过代码分析、网站应用介绍网站状态监控的方式下文主要分为网站应用、技术实现两部分
一、网站应用
现在网络上已经存在一些Web网站监控的服务#xff…如何实现Web应用、网站状态的监控
关键词网站监控,服务器监控,页面性能监控,用户体验监控本文通过代码分析、网站应用介绍网站状态监控的方式下文主要分为网站应用、技术实现两部分
一、网站应用
现在网络上已经存在一些Web网站监控的服务虽然功能五花八门但限制较大需付费使用本文介绍的技术运行网站见下方地址不会关闭可以直接使用一个朴实无华且免费的WEB网站监控工具先看下效果
1. 打开网站
【传送门】
https://www.xujian.tech/monitor2. 微信扫码登录
这里通过微信扫码取得小程序openid利用openid标记用户不涉及隐私 扫码完成后会自动跳转到系统
3. 进入监控表
进入系统后选中左侧菜单进入监控表页面
4. 添加监控器
监控器支持POST、GET两种请求方式GET请求时如有参数请直接放置在地址中POST请求时如有参数请在表单中填写JSON键值对对象Header如果有需要也可按JSON对象方式填写仅需如下三步即可完成设置提交后点击刷新即可在页面上看到监控器记录此时还未执行
5. 说明和操作
5.1 关于成功率
初次时显示“未执行”执行正确计算
5.2 关于监控频率
每次执行完成计算下一次执行时间默认30分钟一次免费用户暂不支持自定义频率计时器每5分钟执行一次发现监控器执行时间小于当前时间的就执行请求所以监控频率并非严格按照30分钟一次
5.2 相关操作
新增/编辑监控器后可以点击“立即执行”进行一次请求观察设置是否正确需要修改时可点击“编辑”按钮对监控器内容进行修改点击运行记录可查看近期运行的情况运行记录中点击结果复制可以复制运行的结果当返回内容大于512b的时候只存储前512个内容需要邮件通知的用户可点击右上角头像设置邮箱在系统异常的时候会通过邮件进行提示邮件内容如下
6. 功能拓展
如果有更多建议、合作请在本文下方留言或按网站提示添加作者
二、技术实现
1. 技术栈
实现一个监控器需前端、后端、数据库、缓存等技术本站主要应用了以下技术
序号技术所属端1VUE前端2Vue Element Admin前端3Java后端4MySQL 数据库后端5Redis缓存后端6Nginx运维7MyBaits-plus后端
2. 核心代码
实现web应用监控的核心是定期按规则进行请求并将结果记录遇到错误时发送邮件提醒本文以在Spring Boot中实现为例除Spring Boot基础依赖外还需添加如下依赖 !--发送邮件--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-mail/artifactId/dependency!--糊涂工具实现网络请求、工具类等--dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.20/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.0/version/dependency2.1 监控器实体
记录监控器基本属性、执行时间、统计结果等下方代码含实体和下次执行时间计算方法
Data
Builder
TableName(m_monitor)
public class MMonitor {JsonFormat(shape JsonFormat.Shape.STRING)private Long id;//监控器名称private String name;//创建时间private Date createdAt;//下次运行时间定时器筛选时的重要指标private Date nextRunAt;//上次运行时间private Date lastRunAt;//计时器类型1分钟2小时3天private Integer timerType;//是否已伤处1已删除0正常private Integer isDeleted;//计时器步长整数值private Integer timerLength;//监控器状态1可用0停用private Integer status;//用户微信小程序openidprivate String openid;//请求URLprivate String toUrl;//请求方法GET、POSTprivate String toMethod;//请求参数JSON Objectprivate String toParams;//请求headerJSON Objectprivate String toHeaders;//返回结果包含为成功当toResultCode不等于200的时候生效private String toResult;//返回结果code为成功200表示用code其他表示包含字符串private Integer toResultCode;//POST请求体格式0json,1formprivate Integer toBodyType;// 最新一次运行情况1正常0异常private Integer runStatus;// 最新一次运行情况中文成功、失败、失败原因private String runResult;// 运行成功次数private Integer countSucceed;// 总运行次数private Integer countAll;//分钟数最短步长即最短30分钟一次private static final int MIN_MINUTE_LENGTH 30;// 下次执行时间计算方法public void calNextRunAt(){if(this.lastRunAt null){this.lastRunAt new Date();}timerType timerType null ? 1 : timerType;if(this.timerLength null || this.timerLength 1){this.timerLength 30;}int addMinute 0;switch (timerType){case 1:addMinute timerLength;break;case 2:addMinute 60 * timerLength;break;case 3:addMinute 60 * 24 * timerLength;break;}addMinute Math.max(addMinute,MIN_MINUTE_LENGTH);this.nextRunAt new Date(System.currentTimeMillis() 1000L * 60 * addMinute);}
}
2.2 计时器
利用Spring Boot的Scheduled定时器实现
Component
Slf4j
public class MonitorTimerTask {ResourceMMonitorMapper monitorMapper;AutowiredMonitorService monitorService;Scheduled(cron0 0/5 * * * *)public void exec(){ListMMonitor monitorList monitorMapper.selectList(new LambdaQueryWrapperMMonitor().isNotNull(MMonitor::getNextRunAt).lt(MMonitor::getNextRunAt,DateUtil.formatDateTime(new Date())).eq(MMonitor::getStatus,1).eq(MMonitor::getIsDeleted,0));log.info(String.format(符合执行条件的监控器有%d个, monitorList.size()));for (MMonitor mMonitor : monitorList) {monitorService.run(mMonitor);}}
}定时器不生效记得在SpringBootApplication上添加注解EnableScheduling
2.3 按规则进行请求
即按监控器的toXX字段配置的内容填充请求参数进行请求本段不多说直接上代码
/*** 运行监控器的方法实现运行从这里开始* */Overridepublic void run(MMonitor monitor) {long timestamp System.currentTimeMillis();if(monitor.getIsDeleted() ! null monitor.getIsDeleted() 1){return;}Date date new Date();boolean isSucceed false;String resultMsg 成功;String requestResult ;int code 0;try{HttpResponse httpResponse null;if(monitor.getToMethod() ! null monitor.getToMethod().equalsIgnoreCase(GET)){HttpRequest httpRequest HttpRequest.get(monitor.getToUrl());setHeaders(httpRequest,monitor);httpResponse httpRequest.execute(false);}else{HttpRequest httpRequest HttpRequest.post(monitor.getToUrl());setHeaders(httpRequest,monitor);setPostParams(httpRequest,monitor);httpResponse httpRequest.execute(false);}code httpResponse.getStatus();requestResult httpResponse.body();if(monitor.getToResultCode() 200){isSucceed code 200;if(!isSucceed){throw new Exception(返回结果HTTP CODE不为200);}}else {isSucceed requestResult.contains(monitor.getToResult());if(!isSucceed){throw new Exception(返回结果缺少包含内容);}}}catch (Exception e){isSucceed false;resultMsg e.getMessage();}if(isSucceed){monitor.setCountSucceed(monitor.getCountSucceed() 1);}monitor.setCountAll(monitor.getCountAll() 1);monitor.setRunStatus(isSucceed ? 1 : 0);monitor.setRunResult(resultMsg);monitor.calNextRunAt();monitor.setLastRunAt(date);monitorMapper.updateById(monitor);timestamp System.currentTimeMillis() - timestamp;log.info(monitor.getName() String.format(检查完毕耗时%dms., timestamp));if(requestResult ! null requestResult.length() 512){requestResult requestResult.substring(0,511) ...;}MRunRecord runRecord MRunRecord.builder().monitorId(monitor.getId()).runCode(code).runResult(requestResult).runAt(date).timeSpent(timestamp).openid(monitor.getOpenid()).runStatus(isSucceed ? 1: 0).build();mRunRecordMapper.insert(runRecord);sendEmail(runRecord,monitor);}/*** 发送邮件* */private void sendEmail(MRunRecord runRecord,MMonitor monitor){if(runRecord.getRunStatus() ! null runRecord.getRunStatus() 1){return;}new Thread(() - {MUser user userMapper.selectOne(new LambdaQueryWrapperMUser().eq(MUser::getOpenid,runRecord.getOpenid()).orderByDesc(MUser::getId).last( LIMIT 1));if(user null || StrUtil.isBlank(user.getEmail()) || user.getEmail().length() 5 || !user.getEmail().contains()){return;}String subject 【亚特技术Web监控】【监控异常】 monitor.getName();String text ----------------详情登录网站查看----------------\n -------------------请求内容-------------------\n URL monitor.getToUrl() \n Method monitor.getToMethod() \n -------------------返回内容-------------------\n HttpCode runRecord.getRunCode() \n Result runRecord.getRunResult() \n;eMailUtils.sendTextMailMessage(user.getEmail(), subject, text);}).start();}/*** 分析规则设置Post参数* */private void setPostParams(HttpRequest httpRequest,MMonitor monitor){if(monitor.getToBodyType() ! null monitor.getToBodyType() 1){//application/json 方式请求httpRequest.contentType(application/x-www-form-urlencoded;charsetGBK);try{if(!JSONUtil.isTypeJSONObject(monitor.getToParams())){return;}JSONObject joParams new JSONObject(monitor.getToParams());MapString, Object paramsMap new HashMap();for (String key : joParams.keySet()) {paramsMap.put(key,joParams.getStr(key));}httpRequest.form(paramsMap);}catch (Exception e){}}else if(monitor.getToBodyType() ! null monitor.getToBodyType() 0){httpRequest.contentType(application/json);httpRequest.body(monitor.getToParams());}}/*** 分析规则设置header* */private void setHeaders(HttpRequest httpRequest,MMonitor monitor){try{if(!JSONUtil.isTypeJSONObject(monitor.getToHeaders())){return;}JSONObject joHeader new JSONObject(monitor.getToHeaders());MapString,String headerMap new HashMap();for (String key : joHeader.keySet()) {headerMap.put(key,joHeader.getStr(key));}httpRequest.addHeaders(headerMap);}catch (Exception e){}}三、结尾说明
第一部分说的网站已经可用了欢迎试用、欢迎长期使用、欢迎联系合作、欢迎定制功能第二部分给出了核心内容但这部分实际上不是实现整个网站最耗时的前端开发工作也是费力不讨好的本人同时还提供Java开发一对一教学有需要的添加微信xujian_cq详聊欢迎点赞、收藏、评论