提高系统性能,还有很多的点,现在把能想到的一些点记录下来。
Log Policy and Sampling
Log 基本有两种:
- 存储到硬盘,然后通过第三方工具发到后端服务,如logstach+ ELK ,
- 一种是直接在程序中埋点发到log service.
不论哪种log,我们都要防止log 泛滥,事无巨细,都要report 带了了很多log 冗余,增加了系统的负担。
- 存储硬盘的log 是IO操作,耗费系统资源比较大。因此需要控制他的规模。而不是事无巨细都要记录log,一般来说就是warning 以上的。而且log 文件要rolling 策略, 防止log 文件无限扩张。Batch类型的应用比较特殊,即使是一个batchjob 的log ,由于需要跑很长时间,那么一个batch log 大的有几G, 有时候会把磁盘占满。导致系统跑的很慢。这个时候就需要管理员/自动监控程序删除文件。
- 发向服务端 的log 由于是用户自己写的,很难控制用户到底写什么、有没有意义。 对于大部分成功的交易,显示所有的信息是个巨大的浪费。通常会enable 1% 的采样来减少后台系统的压力。如果真的有需要,可以调整采样率例如100% 来看到所有需要的信息。如果有异常还是要全部发送。这样的定义对后端service的空间是个巨大的节省,但是要控制采样率和判断有没有exception,对于前端其实压力增加了。以前是不需要判断什么,来了什么就发什么,现在的方案下, 需要拿到全部的context 来进行判断。目前的实践是这样做是可行的,虽然压力有上升,但是内存还是在可控范围。
Warm up
有些service在第一次调用需要花很长的时间,要load wsdd 之类的系统配置。有些jsp 访问需要预编译。 在这样的情况下,如果刚enable service, 就出现高并发。会把系统撑爆。举个例子:当系统在全部deploy状态时候,第一台先部署成功,那么很大的流量进入第一台,由于第一个call 它需要很长时间准备,那么这样的情况下会导致这台机器down机。 对于这样的情况,为了提高第一次的访问速度,会用warm up 机制来预热。只有warmup 好了,才允许接入流量。
Retry Limitation
理想来说,有retry 是保证系统健壮的一个措施。但是如果retry写的不好,比如逻辑错误会先向下游发出错误的event 之后再进入retry。 这样的处理retry 的次数越多,对系统的损害越大。
当写入retry的逻辑的时候,一定要保证retry 即使出错,对逻辑也没有影响。 这种bug 通常会隐藏的很深。
DB 操作的优化
数据库操作是一个很昂贵的操作,每次request 都操作DB 是个超级浪费的。 能不能较少数据库操作或者合理的利用数据的特性进行优化,是让系统性能提升的重要方面。
- 几个独立的数据库查询合并一下
- 能不能利用cache 减少DB操作。
- 一个SQL写不好,没有利用到主键,index 当然会很慢。现在的问题是很多程序都用了data 访问的中间件, 比如一起的Hibernate ,系统用的DAL 这些中间件封装了复杂度,但是也需要用户根据中间件的特性来 变成可以高效执行的sql。
- 对于DB需要partition 的情况, cache 就比较复杂。查询也比较复杂,这个需要具体问题具体分析。但是在partition有大量数据的情况下,会造成内存占用太多导致系统变慢。要能限制用户的访问数据量。
Third Party Library
使用第三方library,通常要注意他的性能和正确的使用方法。通常第三方libarry 由于使用的人比较多,性能不会出现大问题,很多时候是注意如何正确的使用。 请看一个例子性能调优之 - DatatypeFactory