服务端常见性能隐患分享

中午午休时,正好收到公司的培训邮件,由公司性能测试组的一名年轻的同事为我们带来压测相关的分享,这部分对俺这个以应用开发为主的程序员来说,感觉帮助很大。课上内容非常的通熟易懂,涉及了一般应用接口开发中主要的性能问题(不属于分布式大并发),实用性非常的强,本文将选取个人认为其中相对常见部分进行介绍,不足之处望大家指出,再次感谢那名牛X同事,嘿嘿。

压力测试(Stress Test)指模拟实际应用中的软硬件环境和相应系统负载情况,在此条件下,对被测系统进行长时间或超大负荷的运行,来测试系统的性能、可靠性、稳定性,因此也被称为负载测试。常见的压测工具有LoadRunner、JMeter等,前者是付费软件,内容比较复杂,适合专业的压测人员使用;后者简单免费,大部分的业务场景都够用了,非常适合开发人员自己进行压测,相关使用介绍请见:http://www.cnblogs.com/wanliwang01/p/JMeter_Base.html

压力测试的相关指标非常的多,初学时很容易迷失在其中,接下来,将通过一个表格介绍最常见的几个指标

指标 诠释
每秒事务数TPS(transaction per second) 最关键的指标,每秒能承受的并发数,需要注意的是,这儿强调的是并发(比如一秒可以顺序处理10个事务,并不能称之为是并发数,需要注意),这是最关键的生产指标
响应时间RT(Response Time) 通常关注平均响应时间、和不同分位的响应时间,比如90%要多久,99%要多久
并发数/线程数 在不同的测试工具中,对于一次用户请求有不同的名称,认为是并发的请求数即可
检查点/断言 是对结果的检查,简单来说就是response的结果是否满意的问题
事务成功率 这个也是系统的关键指标,比如当有多事务失败时,系统即使没有宕机,也被认为压力存在问题

压测还需要注意相关因素的考虑,包括并发量的大小、测试场景的选择(单一场景或复合场景)、压测服务器的环境(是单机还是集群)、测试时间的选取(10-15的通过性测试或者是8小时以上的稳定性测试)、压测结果的分析等。根据不同的要求,压测可以分为基准测试、负载测试和稳定性测试等。

在整个压测过程中,除了需要关注压测工具的反馈外,还需要注意以下关注点:数据量(是百万级、千万级或更大)、CPU/内存(可以通过zabbix查看iis wp的情况、用jmx查看java应用的情况)、IO/网络速度、数据库(可以通过数据库的慢日志来查找问题)的情况等。

接下来进入本文的重点,即性能案例的分享,虽然都比较简单(简化了场景),但在工作中常常会因为疏忽而遗漏,而造成比较大的影响,希望大家都能避免接下来的问题,每天都准时回家陪老婆孩子,哈哈。

1.dotNet内存托管(内存泄漏)

在应用开发中,我们常常会依赖于第三方组件(无论是本公司还是其他公司提供),部分的组件存在不完善的问题。比如一些托管资源并不会隐式回收,这时就需要手动的释放,比如Client.Close()。处理这类问题可以通过观察应用的内存使用,如果一段时间内服务没有很高负载,但内存消耗仍然高居不下时,往往是这类问题,可以选用单一场景,查看堆内存使用情况的方式来进一步定位。

2.设计不合理

通常与社交相关的场景,都涉及很大的数据量,这时如果产品设计不合理,就会出现资料大量消耗的问题,这类问题主要通过评审会议来发现。比如我要关注一个朋友,如果实时的将其所有的文字和图片信息都通过过来,就会有巨大的信息量,通过分页(部分)查询和异步同步的方式可以解决此类问题。

3.JVM参数设置不合理

这个主要和JVM的GC有关,如果没有设置合理的老生代和永久代的大小,就很容易触发Full GC(Global GC),可以通过配置jvm相关参数来解决,在上线前一定要注意检查。

4.数据库的隐式转化

这个问题,对于.NET程序员来说,一点也不陌生,SQL Server非常的智能,能帮助我们优化SQL语句而避免全表扫描,但也因为其带来一些问题,比如字符串类型的隐式转换。当数据库的字段类型为char(20)时,如果我们将DAO层的DBType设置为String就会出现字符串类型的隐式转换,因为这儿会将nchar转化为char,这个操作会消耗数据库大量的性能,可以通过执行计划发现。因此,需要习惯将char对应到DBType.AnsiString,varchar对应到DBType.String.

5. 特殊场景

这儿的特殊指一般不容易发生,很难重现的场景,往往会出现在与配置相关的场景中。比如写10条配置信息到Redis,如果出现10个并发的情况,如果代码不完善,就可能在Redis中产生100条记录,这会明显影响系统的性能。由于这种情况,往往只会在初次配置时发生,因此很难排查,需要在日常代码的编写中,养成考虑并发问题的习惯。

6.IIS Threads过多

这部分我的印象比较深,刚开始学习多线程编程时,觉得非常的炫酷,因此偏向于起一个线程去处理耗时的操作,比如数据库相关操作。当系统调用频繁时即压力很大时,会创建非常多的新线程和数据库连接,最终导致iis中大量线程处于wait状态,即使请求数下降,线程数和系统消耗不能回落,这部分可以考虑使用单例模式解决,减少资源的消耗。

7.线程block

这部分需要提高代码能力,无论是使用系统管理的线程池或者是.NET中提供的异步编程模型,都可以得到一定的解决。一定要记住的是,即使是.NET线程,也是需要消耗很多系统资源的,在使用时一定要注意对其进行管理。记得的一个例子是,通过多线程写日志,当TPS从200变为300时,RT直接从30ms变为800ms,出现了数量级的变化,最后发现是因为写日志造成的block。在压测过程中,尤其要注意RT数量级的变化,如果出现,必须引起重视。

8.Java/dotNET反射

反射通常与框架有关,有时个人为了简化代码,也会自己编写一个小框架,这是一定需要性能问题,如果接口有一定的性能要求,且自身不能很好的使用反射时(主要熟悉反射元数据的缓存甚至动态发射元数据),还是推荐出点体力。

9.mysql索引失效

这个问题也非常的常见,由于SQLServer的SQL优化的强大,造成个人在编写SQL语句时常常不注意细节。但当使用MySQL时,就需要严格的按照SQL标准来编写查询代码了,不然就会出现索引失效的情况,比如组合索引不按照顺序来编写(遵循最左前缀匹配原则)、勿用函数(比如DateDiff等时间日期函数,可以通过应用程序计算的方式处理)等,这部分可以说是最常见的性能调优点了。

10.锁问题(间隙锁)

比如在一个事务中同时使用delete/update和insert语句,当出现并发状况时,会出现大量事务失败的情况,解决方案就是分析事务,尽可能将其分解到两个事务中。

11.Linux内核配置问题(与运维相关)

这部分与操作系统内核的配置有关,比如Linux默认的内核配置tcp连接是不能重用的,然而当并发量变大时,比如每秒4000TPS,就会出现大量连接Time_wait的情况,如果继续积聚,就会消耗完所有的连接,最终造成服务不可用的情况。解决个问题只需要在网络中添加tcp_tx_used的配置即可,这是连接数就可以稳定在4000+左右,这儿想说的是,如果所有可能情况都排查了,就可以考虑操作系统级别的问题了哈。

路漫漫其修远兮,吾将上下而求索! J

时间: 2024-08-09 18:02:20

服务端常见性能隐患分享的相关文章

docker下编译mangoszero WOW60级服务端(一)

这几天看到暴雪准备开放怀旧服的新闻,突然想到几年前用大芒果window一键服务端自己搭建过服务,就想着在Linux环境下重新编译一套,毕竟Linux作为服务端,性能和稳定性都会高一些,于是在mac虚拟机中安了个centos7,按照官方文档搞了一套. 虚拟中搭建完成之后,想着不如在docker中做几个镜像,到时一键启动就可以搭建完成一套服务端,多么轻松. 经过几天的努力,完成了60级镜像和70级镜像的制作,由于镜像有些大,目前只把60级镜像推送到了阿里云,有兴趣的朋友可以pull下来玩玩,当然客户

TYPESDK 服务端设计思路与架构之六:性能及调优初步

经过本系列前几篇文字的分析和设计,我们成功地开发出了自己的SDK服务端.在我们自己的调试环境下运行一切正常,但是当然我们不能就这样把这套SDK服务端部署上线到正式生产环境,稍有正式大型项目经验的同学应该都知道性能优化以及部署上线相关设计对于服务端项目的重要性.我们到目前为止的分析设计中,并没有考虑到这些设计.那么,针对我们SDK服务端这样的应用场景,应该着重关注哪些相关的优化和设计呢? 数据存取优化 在我们的应用场景中,需要使用到存储的场景主要在以下几个处理中: l  获取配置信息 对每个收到的

Vue服务端渲染和Vue浏览器端渲染的性能对比

Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司做Vue项目的时候,一直苦于产品.客户对首屏加载要求,SEO的诉求,也想过很多解决方案,本次也是针对浏览器渲染不足之处,采用了服务端渲染,并且做了两个一样的Demo作为比较,更能直观的对比Vue前后端的渲染. talk is cheap,show us the code!话不多说,我们分别来看两个D

PHPer都应该关注的服务端性能问题--听云Server试用笔记

很早就在用国外的NewRelic(http://www.newrelic.com/)的APM产品来监测自己网站的PHP应用性能了.无奈国外的服务从国内访问起来实在是太慢了,虽然New Relic已经上市了,但是这访问慢的问题却是一直没见好转,反而越来越严重.可能是GFW时不时抽风所致,有时候还得翻墙才能访问New Relic的报表.虽说翻墙是码农们必备的技能,但是为了看个报表查个故障都要翻墙的话实在太麻烦了.   最近非常意外地发现国内也有提供和New Relic类似服务的厂商了.听云(http

服务端web开发:PHP简介以及常见语法

服务端web开发 在讲解什么是服务端开发之前,让我们先思考几个问题 网站访问: 当我们做好了.html的网站,如何让别人(朋友,用户)可以访问到呢? 使用U盘拷贝,QQ发送文件等直接将文件共享的方式?---不灵活 将网站放在服务器上,让用户通过网址访问?---绝大多数网站的做法 网站内容更新: 如果用户每次访问我们的网站看到的内容都是一样的,在最初的新鲜劲过去以后估计就再也不想访问我们的网站了o(╯□╰)o,那么如何去更新网站的内容呢? 当有内容,图片,或者界面需要更新是,直接修改.html文件

服务端性能保障之流量并发控制方法

服务端性能保障之流量并发控制方法 7月底最后一个周日,我们品课学院线下性能提升班第二期算是正式开课,零基础的学员不少,有测试管理经验.多年开发或者测试经验的人员也有几位,但是各个都很上进好学,不是因为学习而学习,而是有共同理想而走在一个教室,交流探讨专业知识.他们谦虚且上进.因为他们知道做着没有累积性的工作,却期望老板替你加薪?做得久也未必能领得多,一切以实力见真章,所以他们珍惜每一堂课,认真笔记,发散性的问问题,无论功能测试.测试管理.行业知识.架构设计.软硬件知识等等,的确很考验老师的知识面

分享一个自己使用了很久的C++网络封装库,包含服务端和客户端,支持跨平台

其实就只是对网络底层的一个封装,一些回调全部都已经封装好,直接指定相应的回调函数就可以对收到的数据包进行处理. 个人觉得该网络库比较方便的地方就是可以直接将所有自定义及C++标准库容器直接发送到服务端,而原始的C函数发送时连续存储的内存. 注意,该库使用C11编译,所以客户端必须支持C11,废话不多说下面直接看使用demo. 协议定义(protocols.h) 1 #pragma once 2 #include "protocolbase.h" 3 4 5 //客户端请求登录 6 cl

rsync 服务端和客户端配置--综合架构(干货分享)

rsync 服务器配置文档 1. 配置/etc/rsyncd.conf文件,写入如下内容: uid = rsync gid = rsync fake super = yes use chroot = no max connections = 2000 timeout = 600 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log ignore errors re

服务端软件的服务品质

Web服务端软件的服务品质概要 软件品质概述 提供同样功能.产品和服务的服务者中, 竞争力来自功能的多样化和服务品质的差异化, 无论是个体.企业还是国家. 这里的服务指功能.产品的实现程度和处理能力,以及研发/客服提供的技术支持程度(7*24, 随时响应, 沟通便捷,快速解决,温馨提示,有效指南等). 从某种意义来说, 一切皆服务. 功能和产品只是形式, 服务才是本质.服务响应某种需求从而具备存在价值.个体.企业为社会提供某种类型.某种程度的服务,并获得相应回报. 程序员提供的服务是,在特定的工