问题
昨天凌晨1点多,可能是V友太热情,或者爬虫太勤奋,轻境界的服务器宕机了,悄悄地,没有留下错误日志。
我上午收到用户反馈,赶快先重启服务器压压惊,再来分析原因。
连错误日志都没有,这是什么程度的问题呢?
最大的可能性是 JVM内存不够用 或 线程数过多。需要调整相关参数。
另外还需要让服务器能自动恢复。
内存
在调整JVM内存前,先看看系统内存使用情况:
$ free -m
total used free shared buff/cache available
Mem: 1696 1336 68 20 291 155
Swap: 0 0 0
空闲(free)内存几乎没有了。
再看看哪些进程吃了内存:
11869 sorrada+ 20 0 2438544 *417292 15332 S 0.7 24.0 1:24.82 java
5442 sorrada+ 20 0 2420764 *353808 0 S 0.0 20.4 278:47.83 java
3876 mysql 20 0 1111688 *203020 0 S 0.3 11.7 18:38.52 mysqld
2026 sorrada+ 20 0 3118488 *313664 0 S 0.0 18.1 580:09.45 java
第1个是轻境界本体 (417M),第2个是一个无关紧要的程序 (353M),第3个是MySQL (203M),第4个是ElasticSearch (313M)。
于是我kill了那个无关紧要的程序,现在内存情况是:
$ free -m
total used free shared buff/cache available
Mem: 1696 986 431 20 277 505
Swap: 0 0 0
然后要调整JVM最大内存的参数,给它1个G吧~ -Xmx1024m
。
关于线程数,我查了一下文档:
Tomcat的NIO模式的maxThreads默认值为10000,这么大!
改成多少好呢?我算了一下,假设最坏情况下平均每个线程吃5MB,100线程就是500MB,加上已经占用的大约400MB,再加上JVM后台线程和MetaSpace,差不多用完了1G,没有空间留给缓存了,而且会频繁触发Full GC,变成龟速。那就把上限设为60线程吧!
修改Spring Boot的application.properties server.tomcat.max-threads = 60
维持可用(keep alive)
Keepalived这个工具适合维持集群的高可用,我只有一台服务器,就只写了一套shell脚本来确保进程处于运行状态:
https://github.com/sorra/sage...
日志优化
虽然给Logback配置了异步文件输出,但为了开发方便,并没有启用它,而是用了同步文件输出和控制台输出。
这次必须改进了,利用Spring的Profile功能根据环境来加载不同的Logback配置。例如,当profile=production时,启用异步文件输出,关闭同步文件输出,关闭控制台输出。
我在src/main/resources/application.properties文件中存放了默认配置项,包括这一行,把环境设为了开发环境:
spring.profiles.active = dev
# ... other properties ...
我又建了一个只有一行的application.properties文件,存放在源代码的production-files目录内,部署脚本会自动把它copy到生产环境的应用根目录。它有更高优先级,会覆盖前面那个文件的配置:
spring.profiles.active = production
总结
全文介绍了这些改进:调整JVM内存上限、调整Tomcat线程数上限、支持自动恢复、日志优化。
缓存方面:现在只有首页的数据做了缓存,还需要进一步运用缓存,以减少SQL查询,尤其是要避免触发全表扫描。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。