当前位置: 首页 > news >正文

游戏开发网站建设做暧电影在线观看网站

游戏开发网站建设,做暧电影在线观看网站,关闭网站怎么不保存我做的更改,企业网络拓扑图的设计方案我们一个java服务上线后#xff0c;偶尔会发生内存OOM(Out Of Memory)问题#xff0c;但由于OOM导致服务不响应请求#xff0c;健康检查多次不通过#xff0c;最后部署平台kill了java进程#xff0c;这导致定位这次OOM问题也变得困难起来。 最终#xff0c;在多次review代…我们一个java服务上线后偶尔会发生内存OOM(Out Of Memory)问题但由于OOM导致服务不响应请求健康检查多次不通过最后部署平台kill了java进程这导致定位这次OOM问题也变得困难起来。 最终在多次review代码后发现是SQL意外地查出大量数据导致的如下 sql idconditionswhereif testouterId ! nulland outer_id #{outerId}/ifif testorderType ! null and orderType ! and order_type #{orderType}/if.../where /sqlselect idqueryListByConditions resultMaporderResultMapselect * from order include refidconditions/ /select查询逻辑类似上面的示例在Service层有个根据outer_id的查询方法然后直接调用了Mapper层一个通用查询方法queryListByConditions。 但我们有个调用量极低的场景可以不传outer_id这个参数导致这个通用查询方法没有添加这个过滤条件导致查了全表进而导致OOM问题。 我们内部对这个问题进行了复盘考虑到OOM问题还是蛮常见的所以给大家也分享下。 事前# 在OOM问题发生前为什么测试阶段没有发现问题 其实在编写技术方案时是有考虑到这个场景的但在提测时忘记和测试同学沟通此场景导致遗漏了此场景的测试验证。 关于测试用例不全面其实不管是疏忽问题、经验问题、质量意识问题或人手紧张问题从人的角度来说都很难彻底避免人没法像机器那样很听话的、不疏漏的执行任何指令。 既然人做不到那就让机器来做这就是单元测试、自动化测试的优势通过逐步积累测试用例可覆盖的场景就会越来越多。 当然实施单元测试等方案也会增加不少成本需要权衡质量与研发效率谁更重要毕竟在需求不能砍的情况下质量与效率的关系是得此失彼这是任何一本项目管理的书都提到过的。 事中# 在感知到OOM问题发生时由于进程被部署平台kill导致现场丢失难以快速定位到问题点。 一般java里面是推荐使用-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/home/dump/这种JVM参数来保存现场的这两个参数的意思是当JVM发生OOM异常时自动dump堆内存到文件中但在我们的场景中这个方案难以生效如下 在堆占满之前会发生很多次FGCjvm会尽最大努力腾挪空间导致还没有OOM时系统实际已经不响应了然后被kill了这种场景无dump文件生成。就算有时幸运JVM发生了OOM异常开始dump由于dump文件过大(我们约10G)导致dump文件还没保存完进程就被kill了这种场景dump文件不完整无法使用。 为了解决这个问题有如下2种方案 方案1利用k8s容器生命周期内的Hook# 我们部署平台是套壳k8s的k8s提供了preStop生命周期钩子在容器销毁前会先执行此钩子只要将jmap -dump命令放入preStop中就可以在k8s健康检查不通过并kill容器前将内存dump出来。 要注意的是正常发布也会调用此钩子需要想办法绕过我们的办法是将健康检查也做成脚本当不通过时创建一个临时文件然后在preStop脚本中判断存在此文件才dumppreStop脚本如下 if [ -f /tmp/health_check_failed ]; thenecho Health check failed, perform dumping and cleanups...;pidps h -o pid --sort-pmem -C java|head -n1|xargs;if [[ $pid ]]; thenjmap -dump:formatb,file/home/work/logs/applogs/heap.hprof $pidfi elseecho No health check failure detected. Exiting gracefully.; fi 注也可以考虑在堆占用高时才dump内存效果应该差不多。 方案2容器中挂脚本监控堆占用占用高时自动dump# #!/bin/bashwhile sleep 1; donow_time$(date %F_%H-%M-%S)pidps h -o pid --sort-pmem -C java|head -n1|xargs;[[ ! $pid ]] { unset n pre_fgc; sleep 1m; continue; }data$(jstat -gcutil $pid|awk NR1{print $4,$(NF-2)});read old fgc $data;echo $now_time: $old $fgc;if [[ $(echo $old|awk $180{print $0}) ]]; then(( n ))else(( n0 ))fiif [[ $n -ge 3 || $pre_fgc $fgc -gt $pre_fgc $n -ge 1 ]]; thenjstack $pid /home/dump/jstack-$now_time.log;if [[ $ ~ dump ]];thenjmap -dump:formatb,file/home/dump/heap-$now_time.hprof $pid;elsejmap -histo $pid /home/dump/histo-$now_time.log;fi{ unset n pre_fgc; sleep 1d; continue; }fipre_fgc$fgc done每秒检查老年代占用3次超过80%或发生一次FGC后还超过80%记录jstack、jmap数据此脚本保存为jvm_old_mon.sh文件。 然后在程序启动脚本中加入nohup bash jvm_old_mon.sh dump 即可添加dump参数时会执行jmap -dump导全部堆数据不添加时执行jmap -histo导对象分布情况。 事后# 为了避免同类OOM case再次发生可以对查询进行兜底在底层对查询SQL改写当发现查询没有limit时自动添加limit xxx避免查询大量数据。 优点对数据库友好查询数据量少。 缺点添加limit后可能会导致查询漏数据或使得本来会OOM异常的程序添加limit后正常返回并执行了后面意外的处理。 我们使用了Druid连接池使用Druid Filter实现的话大致如下 public class SqlLimitFilter extends FilterAdapter {// 匹配limit 100或limit 100,100private static final Pattern HAS_LIMIT_PAT Pattern.compile(LIMIT\\s[\\d?](\\s*,\\s*[\\d?])?\\s*$, Pattern.CASE_INSENSITIVE);private static final int MAX_ALLOW_ROWS 20000;/*** 若查询语句没有limit自动加limit* return 新sql*/private String rewriteSql(String sql) {String trimSql StringUtils.stripToEmpty(sql);// 不是查询sql不重写if (!StringUtils.lowerCase(trimSql).startsWith(select)) {return sql;}// 去掉尾部分号boolean hasSemicolon false;if (trimSql.endsWith(;)) {hasSemicolon true;trimSql trimSql.substring(0, trimSql.length() - 1);}// 还包含分号说明是多条sql不重写if (trimSql.contains(;)) {return sql;}// 有limit语句不重写int idx StringUtils.lowerCase(trimSql).indexOf(limit);if (idx -1 HAS_LIMIT_PAT.matcher(trimSql.substring(idx)).find()) {return sql;}StringBuilder sqlSb new StringBuilder();sqlSb.append(trimSql).append( LIMIT ).append(MAX_ALLOW_ROWS);if (hasSemicolon) {sqlSb.append(;);}return sqlSb.toString();}Overridepublic PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql)throws SQLException {String newSql rewriteSql(sql);return super.connection_prepareStatement(chain, connection, newSql);}//...此处省略了其它重载方法 }本来还想过一种方案使用MySQL的流式查询并拦截jdbc层ResultSet.next()方法在此方法调用超过指定次数时抛异常但最终发现MySQL驱动在ResultSet.close()方法调用时还是会读取剩余未读数据查询没法提前终止故放弃之。
http://wiki.neutronadmin.com/news/283996/

相关文章:

  • 广州专业做外贸网站建设如何设计大型电商网站建设
  • 江苏 江苏省住房和城乡建设厅网站充电宝关键词优化
  • 站长工具爱情岛武威 网站建设
  • 怎样暂停域名指向网站wordpress可视化主题制作
  • 如何建网站遂宁怎么做百度快照让网站排前面
  • 温州做网站建设公司建设网站为网站网站做广告
  • 微信微网站开发报价车轮违章查询是什么网站开发
  • CMS源码就可以做网站吗wordpress 用户api
  • 宝思哲手表网站免费软件电视剧最全
  • 免费的软件网站抖音代运营合作策划书
  • 深圳网站设计 工作室小程序商城开发平台
  • 怎样给网站或者商品做推广史先生 网站建设
  • 网站页面设计内容网站风格确认书
  • 电商扶贫网站建设手机排行榜前十名
  • 安阳网站建设价格丹阳官方网站建站
  • 备案期间怎么访问网站企业建立网站需要
  • wordpress站点前台请求数过多wordpress 外贸 开发
  • 酒店建设网站的意义超酷网站
  • 有没有代做模型的网站大数据营销精准营销
  • 杭州网站推广优化公司免费的短视频app大全下载
  • 游戏网站服务器租用淘词神器
  • 网站后台口令网页的后台管理系统
  • 泽成seo网站排名963中华室内设计网
  • 网站制作公司网站源码群晖wordpress性能
  • 制作网站建设的公司简单个人网站模板
  • 做本地分类信息网站赚钱吗图书网站开发介绍
  • 优秀企业网站欣赏wordpress 站内链接
  • 怎样给网站做国内网站建设的趋势是怎样的
  • 360搜索怎么做网站自然优化如何给网站增加内链
  • 如何在国外社交网站上做原单外贸大多数软件仍然是定制开发的