专栏首页一猿小讲经验分享一箩筐,从此再也不入坑

经验分享一箩筐,从此再也不入坑

01. 聊 啥

世人都说路不齐、别人骑马我骑驴、回头看看推车汉、比上不足下有余!

你骑马来我骑驴,看看眼前我不如;回头一看推车汉,比上不足比下余。

回头总结一下以往填过的坑,感觉自己还真挺牛掰。

今天不闲聊,主题不跑偏,就想送你们一箩筐经验,预防你们再入坑。

吃个核桃,坐稳,扶好,我们开始。

02. 聊 开

经验一:CPU 长期利用率为 100%

问题现象:

多用户并发情况下,CPU 利用率长期为100%,DUMP 线程信息,发现 CPU 利用率高的线程都与 HashMap 操作相关。

原因分析:

  • 在并发情况下选择非线程安全的容器是没有保障的,HashMap是非线程安全的;
  • HashMap 在多线程情况下,进行扩容很容易导致死循环,最终导致 CPU 利用率 100%。

解决方法:

  • 在并发场景下,避免使用 hashMap;
  • 在并发场景下,若一定要使用 HashMap,使用同步锁或者使用 ConcurrentHashMap 替代 HashMap。

经验二:数据库访问相当的慢

问题现象:

数据库请求次数多,响应慢。

原因分析:

在索引具备的前提下,数据库分配连接数少,且缺少缓存。

解决方法:

  • 对于需要连接到数据库的应用,要考虑查询的结果是否可以复用;
  • 对于查询结果时效性不高而且需要多次调用的请求,做缓存往往可以节省数据库的资源,也使应用本身效率大大提高。

经验三:系统连接数巨多

问题现象:

系统连接数巨多

原因分析:

Tomcat 容器默认的通讯方式为 TCP/IP + BIO,这种模式往往不适合大并发的情况,BIO 模式生成 Socket 会消耗过多的本地资源,Socket 连接的建立一般比较慢,能支持的连接数有限。

一般都采取 accept 获取 Socket 以后采用一个 thread 来处理,one connection one thread,无论连接是否有真正数据请求,都需要独占一个 thread。

如果我们 server 端需要支持大量连接,但这些连接同时发送请求的峰值不会很多,一般建议替换成 NIO 模式。

解决方法:

替换成 TCP/IP+NIO,NIO 模型是内置的,调用很方便,只需要修改配置文件conf/server.xml文件,将配置文件中 protocol 修改成 org.apache.coyote.http11.Http11NioProtocol,重启即可生效。

下面的配置是已经改过了的,默认 protocol 是HTTP/1.1

<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"  
connectionTimeout="20000"
redirectPort="8443"
maxThreads="500"
minSpareThreads="20"
acceptCount="100"
disableUploadTimeout="true"
enableLookups="false"
URIEncoding="UTF-8" />

经验四:使用HttpClient的版本问题

问题现象:

不是每个请求都能正确返回,可能遇到 The remote server returned an error.(417) Unkown

原因分析:

系统使用的是 4.0.3 版本,该版本发布时 Expect:100-continue 默认为开启状态,即客户端每次与服务器通讯过程,每次先向服务器发送一个请求,看服务器是否能处理这个请求,一般应用在上传一些特殊的文件或者比较大数据量的交互上,有时候会造 time_wait 很多。

该问题在 HttpClient 4.1 版本中解决,默认为关闭该功能。

解决方法:

升级到 4.1 以上版本,默认为关闭该功能。

经验五:使用 log4j 日志性能的问题

问题现象:

日志 IO 占用大量的系统资源,CPU 利用率高,TPS 偏低,热点方法在

org.apache.log4j.Category.callAppenders
ch.qos.logback.core.OutputStreamAppender.subAppend
等与日志相关的方法。

原因分析:

日志量过大,IO 频繁。日志对系统性能的影响程度主要体现在以下几方面

  • 日志输出的选项设置,有些选项极慢, 例如 C/class、 F/file 、L/line 、l 、M/method速度极慢,尽量避免使用;
  • 日志输出双份,某些应用通常将业务日志同时输出到控制台和另外一个文件或者日志信息在同一份文件中输出两次;
  • 日志输出的目的地,输出到控制台的速度比输出到文件系统的速度要慢;
  • 日志输出格式不一样对性能也会有影响,如简单输出布局(SimpleLayout)比格式化输出布局(PatternLayout)输出速度要快。可以根据需要尽量采用简单输出布局格式输出日志信息;
  • 日志级别越低输出的日志内容就越多,对系统系能影响很大;
  • 日志输出方式的不同,对系统系能也是有一定影响的,采用异步输出方式比同步输出方式性能要高;
  • 每次接收到日志输出事件就打印一条日志内容比当日志内容达到一定大小时打印性能要低。

解决方法:

  • 精简日志输出内容,合理设置日志输出格式,避免使用那些极慢的选项;
  • 设置日志缓存,以及缓存大小;
  • 将业务日志仅输出到文件系统,且仅输出一份(以log4j为例,对于日志输出多份的情况举例如下):
同一份日志输出到两个文件的情况
log4j.rootLogger=DEBUG, stdout, system
表示将等级为 DEBUG 的日志信息输出到 stdout 和 system 这两个目的地,
此配置将使得日志输出两份,
将此行改成 log4j.rootLogger=DEBUG, system;
表示将日志只输出到 system 这一个目的地;

经验六:logback 比 log4j 拥有更好的性能

使用 logback 和 log4j 日志组件进行日志打印。

当日志级别为 debug 时,系统平均 tps 比为 logback:log4j=1.31:1

当日志级别为 info 时,系统平均 tps 比为 logback:log4j=1.03:1

日志输出量越大时,使用 logback 日志组件进行日志打印比 log4j 方式在处理速度方面的优势越为明显,实验过程中 logback 比之 log4j 系统处理能力提升幅度为 3%~30%。

经验七:已经分享一箩筐了,再分享箩筐也装不下,唯恐聪明的你们也消化不动了。(有缘再续)

03. 聊 毕

过往从事研发中的点滴经验,送给你们,预防你们再入坑,另外你们也可以在面试的时候吹吹牛啦(哈哈)。

如果你们感觉稍微有点意思,不用赞赏,就点击右下角的“在看”,或者多多分享转发给你们的朋友就很感激。

本文分享自微信公众号 - 一猿小讲(yiyuanxiaojiangV5),作者:一猿小讲

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一篇文章讲透线上应用监控

    “线上服务停了,要重启一下”?久经职场做研发的程序员,视线会逐渐转移到线上应用的运行状态。设想一下,如果你在半夜两点正在酣眠美梦时,微信群里突然炸开锅:“服务停...

    一猿小讲
  • 傻瓜也能玩转日志归集

    关注"一猿小讲"的猿友们都知道,前段时间我在《一文讲懂线上应用系统监控》给大家简单提到了日志归集,埋下了伏笔,今天的这篇分享是来给大家还债的,主要从整体到局部,...

    一猿小讲
  • 玩弄日志归集于手掌之中

    关注“一猿小讲”公众号的粉丝都清楚,在《傻瓜也能玩转日志归集》一文中,分享过一个业界使用成熟的日志归集方案 EFK。而今天,咱们再谈日志归集,但是今天的分享,却...

    一猿小讲
  • 软件系统的黑匣子:我们要怎样写日志

    作为一个软件系统,需要写日志,这是不言而喻的,这是大家都会不假思索地说“那当然”的事。不论是什么语言,写日志的专用框架也不一而足,写到文本的,写到数据库的,写到...

    Austin
  • Kubernetes日志收集解决方案

    在大规模集群部署的场景下,容器实例会部署到多个节点上,节点以及节点上的应用产生的日志会随之分散在各个容器的主机上,传统的集群应用大多在本地持久化,这给整个应用系...

    用户5166556
  • 日志中的用户隐私安全

    对于敏捷团队,安全卡应该提到比业务卡更高的优先级,同样需要放在backlog里面进行track,需要kick off、deskcheck,需要一个正经的流程或者...

    ThoughtWorks
  • 业务上云使用腾讯云日志服务方案

    日志服务(Cloud Log Service,下文简称CLS服务)是腾讯云提供的一站式日志数据解决方案,可以快速便捷的接入,享受日志采集、日志存储到日志内容搜索...

    覃春善
  • 惊讶!我定的日志规范被CTO在全公司推广了

    日志文件提供精确的系统记录,根据日志最终定位到错误详情和根源。日志的特点是,它描述一些离散的(不连续的)事件。例如:应用通过一个滚动的文件输出 INFO 或 E...

    猿天地
  • 开源日志框架的原理与分析(下)

    #开发代码时要有意识的设想代码出现问题时的场景,针对场景记录关键程序的运行信息,容易定位问题

    疯狂的KK
  • 日志记录规范总结

    然而,日志记录的好坏直接关系到系统出现问题时定位的速度。同时,我们可以通过对日志的观察和分析,提前发现系统可能的风险,避免线上事故的发生。对于服务端开发人员来说...

    江不知

扫码关注云+社区

领取腾讯云代金券