性能问题分析优化实践案例
星球同学问了这样一个性能分析的问题:
他们有一个地图服务,数据都存储在同一个sql server实例中,访问量过高导致服务挂了,开发的解决方案是将地图服务的内存从4G升级到8G,问题就解决了。
她的问题是开发的这种解决办法是否是最优解,有没有更好的解决方案。
由于我对他们的系统架构不太了解,也无法看到具体的日志信息和监控,因此我的分析思路是这样的。
我尝试绘制了大致的服务请求调用链路图,如下图所示:
按照她的描述,现有系统架构下GIS地图服务会被多个不同系统调用,且所有的地图数据都是存储在同一个数据库中。当请求获取地图数据的访问量过高时,就可能出现如下几种场景:
- 应用直连数据库且不作限制,会对数据库造成较大的访问压力;
- 获取地图数据是密集计算型业务,对应用服务内存资源耗用较多;
- 可用内存不足,由于资源竞争导致请求超时、失败,最终资源耗尽而服务宕机;
当然,他们开发同学的解决办法是增加应用服务内存,这个问题暂时被解决了。
但从我的角度来说,增加内存是短时间内的最合适的办法,但长期来说可能存在一些隐患,下面列举一些性能优化的思路和方法,仅供参考。
1、应用服务升配
获取地图数据这种业务场景,在应用层需要做大量的逻辑计算处理,是典型的计算密集型业务,对应用服务的内存资源耗用比较大,因此对地图应用服务提升配置(加内存),是最简单粗暴的方式。
2、服务水平扩容
上面提到是多个业务系统访问同一个地图应用,地图应用可以看作是一个基础公共服务,为了避免单机服务(概率很低)挂掉的不可用风险,因此对地图应用服务水平扩容,将多个系统的请求通过负载均衡,分散访问压力,也是一种办法。
3、熔断+本地缓存
所谓的熔断措施,即当访问压力达到某个临界点(比如内存资源使用率>70%)则将其他请求做超时失败处理,即快速失败,避免过多的请求造成资源竞争导致服务挂掉。
本地缓存是一种应急方案,可以将一部分使用频率较高的地图信息数据挂载在应用服务上,请求不再访问数据库,熔断后直接返回本地数据。但这样做对业务是有损的,会降低地图的精度和准确性,只能作为应急手段。
4、压测+限流+连接池
对该业务应用和相关核心场景进行压测,找到系统的性能瓶颈,明确安全水位指标,然后按照压测的结果进行优化或者限流,业务可用性的前提是应用服务可用(技术角度的SLA)。
不确定他们的系统在应用服务层和应用访问数据库之间是否有连接池配置,但为了应用解耦,建议在应用层增加连接池配置,不要用默认参数,而是通过不断压测找到最合适的配置参数。
同时,应用服务访问数据库不要直连,而是通过DAL组件来访问。这样做的好处是连接可以复用,不同系统的同一类型请求可以合并处理,且可以对过高的请求进行限制。
5、数据库层面读写分离
上述问题当前的系统架构下,数据库是单库,单点问题很可能在较高的访问请求压力下成为稳定性最大的不确定因素。因此可以对数据库进行读写分离操作,按照一主多从的结构对数据库进行垂直分库。
即不同系统请求地图数据,将请求路由到该业务对应的从库,地图数据更新先写入主库,然后再同步到从库。
但这样改造又存在几个问题,首先是改造成本比较高,技术难度不小;其次是主从结构下数据同步问题(地图数据一般数据量比较大,同步耗时较长),可能会影响地图的实时精度。
具体实践中,要综合考虑访问量、投入产出比,再决定是否进行改造。
当然,上述的分析和优化方法仅是我个人基于对这个问题的一些猜测,然后结合个人经验给出的建议,不构成实际操作建议,仅供参考。
性能问题分析和优化,还是要结合具体的业务场景和成本问题,综合考虑,谨慎优化。