• 综合客户反馈的现场情况,服务前一天可以使用正常,第二天早晨发现报错; 初步怀疑是晚上什么操作导致的,大概是定时任务
  • 查看服务日志,综合几天日志,发现每晚都会执行一个日志清除的定时任务 scheduledtask.CleanLogJob
{"log":"\u001b[2m2022-10-30 00:00:00.001\u001b[0;39m \u001b[32m INFO\u001b[0;39m \u001b[35m1\u001b[0;39m \u001b[2m---\u001b[0;39m \u001b[2m[ne-scheduling-1]\u001b[0;39m \u001b[36mc.newatc.api.scheduledtask.CleanLogJob  \u001b[0;39m \u001b[2m:\u001b[0;39m ----开启定时清理日志文件----2022-10-29T16:00:00.001343Z\n","stream":"stdout","time":"2022-10-29T16:00:00.002200283Z"}
{"log":"\n","stream":"stderr","time":"2022-10-29T16:00:32.158196254Z"}
{"log":"Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread \"Hikari housekeeper\"\n","stream":"stderr","time":"2022-10-29T16:00:32.158216755Z"}
{"log":"\u001b[2m2022-10-30 00:01:22.799\u001b[0;39m \u001b[31mERROR\u001b[0;39m \u001b[35m1\u001b[0;39m \u001b[2m---\u001b[0;39m \u001b[2m[ne-scheduling-1]\u001b[0;39m \u001b[36mo.s.s.s.TaskUtils$LoggingErrorHandler   \u001b[0;39m \u001b[2m:\u001b[0;39m Unexpected error occurred in scheduled task\n","stream":"stdout","time":"2022-10-29T16:01:22.800399506Z"}
{"log":"\n","stream":"stdout","time":"2022-10-29T16:01:22.800414807Z"}
{"log":"java.lang.OutOfMemoryError: Java heap space\n","stream":"stdout","time":"2022-10-29T16:01:22.800417418Z"}
{"log":"\n","stream":"stdout","time":"2022-10-29T16:01:22.800419609Z"}
  • 定时任代码是先根据当前日期查询7天前的所有数据,再全部删除。当某一天数据量特别大,无法全部加载到内存时,就会内存溢出,程序就会假死
* 每天零点定时清理日志 @Scheduled(cron = "0 0 0 * * ?") public void deleteLog() log.info("----开启定时清理日志文件----{}", Instant.now()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar c = Calendar.getInstance(); //过去七天 c.setTime(new Date()); c.add(Calendar.DATE, -7); String day = format.format(c.getTime()); List<OpLog> opLogList = findOpLogByDayNum(day); opLogRepository.deleteAll(opLogList); List<SignalAlarm> signalAlarmList = findSignalAlarmByDayNum(day); signalAlarmRepository.deleteAll(signalAlarmList); catch (Exception e) log.error("deleteLog error..", e);
  • 定时任务执行后,内存溢出java.lang.OutOfMemoryError: Java heap space。查看服务的jvm配置,只分配了 512M 内存,对于大量数据读入内存,确实不够用
  • 查看代码提交记录,综合更新部署时间和问题出现时间,基本确定是此问题
  • 让运维人员协助查询了数据库,发现每天新增10万条信号机报警日志,仍有13天(100多万条)的数据存在,确实是删除日志时内存溢出失败
  • 数据量问题确实是到客户现场,有实际这么多设备和用户才暴露出来的,公司测试无法进行此种场景的压力测试,只能把这款产品的第一个用户作为小白鼠了
  • SpringBoot服务因异常宕机或假死时,不再提供服务,会从注册中心掉线,并且整个应用就不可用了
  • 如果只是某些菜单功能不可用,对于客户来说还可以接受,毕竟试运行阶段,有点小问题客户也能理解
  • 如果是整个服务宕机,界面打不开,客户就会对系统的稳定性产生怀疑,印象会不太好
  • 或者说,某些导致宕机的问题,如果及时处理了,客户就暂时发现不了这个问题,就能减少对客户的负面印象
  • 针对于此,写了个shell脚本,监控SpringBoot服务暴露的端点,服务不可用时,进行重启操作
  • 为了防止网络波动造成的影响,重试三次请求,都得不到健康的结果,才认为不可用
  • 具体脚本如下:
#!/bin/bash
# 检查服务是否可用,判断服务状态
function checkHealth() {
    currTime=`date +"%Y-%m-%d %H:%M:%S"`
	echo "$currTime $@"; # 以列表的方式一次性打印所有的参数
	ConsulResult=$(curl -s --connect-timeout 500 --max-time 2  http://$1/actuator/health )
	target="UP"
	local health=1
	if [[ $ConsulResult =~ $target ]]
		echo "$2结果健康";
		sleep 1s;
		ConsulResult=$(curl -s --connect-timeout 500 --max-time 2  http://$1/actuator/health )
		if [[ $ConsulResult =~ $target ]]
			echo "$2结果健康";
			sleep 1s;
			ConsulResult=$(curl -s --connect-timeout 500 --max-time 2  http://$1/actuator/health )
			if [[ $ConsulResult =~ $target ]]
				echo "$2结果健康";
				health=0;
				echo "$2 结果不健康";
	return $health;
# 检查服务健康状态,并处理异常
function dealCheckResult() {
	ipport=$1
	name=$2
	echo "start $name ======================="
	checkHealth $ipport $name
	health=$?
	if [[ $health -eq 1 ]]
		echo "$name 检查完毕,无问题!"
		echo "重启 $name 预计2分钟"
		# 重启服务
		docker stop $name
		sleep 5s
		docker start $name
		sleep 120s
		# 重新检查一次是否启动成功,不成功则再休眠60s
		checkHealth $ipport $name
		health=$?
		currTime=`date +"%Y-%m-%d %H:%M:%S"`
		if [[ $health -eq 1 ]];then
			echo "$currTime $name 服务已重启完成"
			echo "$currTime $name 服务尚未重启完成,再休眠60s等待"
			sleep 60s
	echo "end $name 所有处理完毕==========="
# 获取系统启动时间
uptime=$(cat /proc/uptime)
echo "uptime: $uptime"
uptimeArr=(${uptime//./ })
startTime=${uptimeArr[0]}
echo $startTime
a=`expr $startTime + 1`
b=1800
# 系统启动30分钟内不执行
if [[ "$a" -lt "$b" ]];
  echo "系统启动30分钟内不执行"
echo "启动时间为$startTime秒,正常执行脚本"
echo "先关闭定时任务"
/sbin/service crond stop
ipport1=172.16.1.122:8181
name1=datacenter
dealCheckResult $ipport1 $name1
ipport2=172.16.1.122:8282
name2=unit
dealCheckResult $ipport2 $name2
ipport3=172.16.1.122:8383
name3=core
dealCheckResult $ipport3 $name3
echo "重新启动定时任务"
/sbin/service crond start
				
功能需求: 包括健康数据、健康科普、健康讨论、个人中心四个模块。 健康数据:用户输入数据,如体重(和身高一起计算体重指数BMI)、体温、血压、血糖、心率、步数(跑步步数)、视力、肺活量等,这些数据不是都一定要填,用户填自己已知的,把填写的数据与男性或女性的正常数据范围做对比,不在正常范围内的数据,系统指出并给用户建议,给出的建议和其它数据一起显示在屏幕上。 健康科普:高级用户(通过客服申请,后台认证)可以发布科普类文章,文章要显示用户作者,可以点赞和收藏。该模块有个搜索功能,用户输入关键字,搜索显示带关键字的文章。多个文章在界面上的排序方式有最新和最热两种,最新是根据文章的发布时间依次排序,最热是根据帖子的收藏+点赞共同决定。 健康讨论:用户都可以发布帖子讨论,类似豆瓣帖,可以留言、点赞、转发、收藏。该模块有个搜索功能,用户输入关键字,搜索显示带关键字的帖子。多个帖子在界面上的排序方式有最新和最热两种,最新是根据帖子的发布时间依次排序,最热是根据帖子的收藏+转发+点赞+评论数共同决定。 个人中心:基本信息(昵称、性别、年龄、身高等)、历史健康数据(系统提出的建议也保留)、讨论
最近公司需要在Linux下监控tomcat的服务,一旦tomcat服务存在异常或者宕机,重启tomcat保证服务的正常运行,由于Linux下有Shell脚本可以实现此效果,下面是Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤。 1.编写Shell脚本monitor.sh #!/bin/sh # func:自动监控tomcat脚本并且执行重启操作 # author:EagleHao # date:2018-04-08 # DEFINE # 获取tomcat进程ID(其中[grep -w 'tomcat']代码中的tomcat需要替换为你的tomcat文件夹名) Tomca
1.我的文件格式:cr-out.1.0.0.jar 2.开发使用的是springboot进行开发,这里脚本也是利用springboot中health来获得监控信息 3.shell目录结构 |-- bin #存放所有脚本路径 | |-- EnVariable.sh | |-- out.sh |-- conf #脚本配置文件 | |-- filejar.txt |-- logs #日志
SpringBoot提供了CommandLineRunner、ApplicationRunner两个监听接口,通过这两个接口可以在应用启动时做特殊处理。 使用两者的好处在于,可以方便的使用应用启动参数,根据参数不同做不同的初始化操作。 自定义启动监听由程序实现,并且标识@Component注解,交于IOC管理。在SpringBoot启动成功后就会执行实现类的回调。 第一步: 自定义CommandLineRunner: @Component public class CommandLineStartu
对于服务器来说在线率很重要,出现问题要能及时解决,但系统管理员不能一直守在电脑旁边,通过脚本监控网站出现问题及时通过mail通知管理员,如果是139邮箱还可免费手机短信通知。注:通过系统直接发送mail容易被拦截,可使用mail连接第三方smtp发送邮件。 shell脚本实现代码: 代码如下:#!/bin/bash#set -xwhile truedo list=(www.jb51.net s.jb51.net) mail=jmj@jb51.net date=$(date -d “today” +”%Y-%m-%d-%H:%M:%S”) i=0 id=${#list[*]} while [ $
前面 部署springboot的文章中介绍了 启动和停止项目的方法,如果需要替换包重启,或者查看状态,会有很多不方便的地方。 以此我们可以通过编写一个shell脚本来进行启动(start)停止(stop)重启(restart)操作,一步到位,方便高效。 在项目同级目录下 创建 lgn.sh 脚本,编辑内容如下。 #!/bin/bash #这里可替换为你自己的jar包名称,其他代码无需更改。 APP...
公司经过野蛮生长阶段,系统稳定性,CI,CD持续集成交付,基于Spring Cloud 微服务系统使用Spring Boot健康检查工具,提高发布的效率和全方位监控。在没有监控之前,比如说一个Feign微服务项目,我们可能在SpringBoot项目启动之后通过一个Rest接口比如说 127.0.0.1:8888/ok 这个种接口的形式,集成在自动化脚本里面去校验发布时候正常,或者人工去做一些校验。 其实这些都可以通过 Actuator 工具包去做。 官方文档: docs.spring.io/sp