本篇文章内容来自2016年TOP100summit华为架构部资深架构师王启军的案例分享。
编辑:Cynthiaredis
王启军:华为架构部资深架构师。负责华为的云化、微服务架构推动落地,先后参与了华为手机祥云4.0、物联网IoT2.0的架构设计。曾任当当网架构师,主导电商平台架构设计,包括订单、支付、价格、库存、物流等。曾就任于搜狐负责手机微博的研发。“奔跑中的蜗牛”公众号博主。数据库
导读:随着云时代的来临,软件架构突飞猛进,各类新技术层出不穷。“微服务”这个词更是如火如荼,获得了业界的普遍承认。可是,微服务并非银弹,微服务架构下的性能问题在交付项目型的公司尤其重要。
本文主要围绕微服务下的性能问题展开,目的是经过实际问题的解决过程,分析在服务拆分到必定粒度后,服务调用链变长,如何评估、提高总体性能。json
1、问题的提出缓存
在架构设计阶段,你们比较关心的几个基本要素包括:性能、可用性、一致性、扩展性、安全性。其中性能问题在起步阶段每每容易被忽略,但随着架构的逐步演进,规模愈来愈大,性能问题会变得愈来愈重要,极可能一个小小的改动,就能够节省一半的服务器资源。安全
那性能到底表如今哪些方面?
● 一个是响应时间,也就是发送请求和返回结果的耗时;
● 另外一个是吞吐量,也就是单位时间内响应次数。服务器
固然这两个指标是在必定资源限制下才有意义。例如要占用多大磁盘、多少CPU、多大内存等。吞吐量和响应时间之间也互为影响,虽然这不是绝对的。网络
平时比较常见的性能问题包括:架构
● 内存泄露——致使内存耗尽
● 过载——突发流量,大量超时重试
● 网络瓶颈——须要加载的内容太多
● 阻塞——无尽的等待
● 锁——经过限制
● IO繁忙——大量的读写,分布式
● CPU繁忙——计算型常见问题
● 长请求拥塞——链接耗尽 并发
当吞吐量有问题的时候,咱们指望经过线程或者进程的方式来扩展,线程的方式比进程的方式要复杂得多,由于线程方式须要考虑共享数据变化的问题。框架
微服务就是一种进程扩展的模式。咱们能够尝试给微服务下一个定义:
一种架构风格。
● 单个服务尽可能专一一件事情,高内聚、低耦合;
● 进程隔离;
● 每一个服务能够独立的开发、测试、构建、部署;
● 小且灵活;
微服务架构带来的优点包括:
● 交付周期。每一个服务能够独立开发、测试和交付,下降周期;
● 快速沟通。小团队开发,下降代码耦合度致使的沟通成本; 业务按服务拆分,新人不须要了解总体架构,上手快;
● 定制化。能够根据市场需求,灵活多变地组合出新的业务场景;
● 隔离性。进程隔离方式,故障范围有效控制;
● 技术栈。能够根据需求,按服务选择不一样技术栈;
● 演进优化。能够按照服务粒度进行演进优化;
同时带来的问题包括:
● 架构复杂度。因为服务数量暴增引发的各类复杂的架构问题。例如一致性问题、大量远程接口调用的复杂度;
● 管理成本。服务数量爆炸致使管理、运维成本升高。咱们但愿交付周期短,周期短必然引发变动快,变动是可用性的天敌。须要经过自动化、可视化的手段解决问题;
● 故障定位。例如一个涉及几十个服务的请求,如何在故障发生的时候快速定位问题;
● 性能损失。本来一次调用能够返回结果,如今须要流经几个或几十个服务才能返回结果,如何提高响应时间的问题; 因为拆分致使的吞吐量下降,如何补偿?云化就意味着能够横向扩展。架构如何实现扩展?提高总体的系统吞吐量。
2、实践过程
第一步,树立目标。
一般你获得的需求是这样的:“速度要快!”“跟之前比,性能不能下降”。很明显,这并非一个有效的指标。
如何设立目标呢?先列出几种常见却无效的目标。
● 平均响应时间1s
能够看这组数据,[2, 5, 3, 4, 301, 4, 2, 8, 7, 3, 3, 1, 1, 8, 2] AVG(f)=23.6平均响应时间由于一次很是严重的超时致使偏离。没法正确描述响应时间。
● 99%请求要在1S内完成
首先,不一样的业务,响应时间不该该相同;
其次,单纯的设定响应时间毫无心义,要在吞吐量之下进行设定;
● 支持100万并发用户?
首先,这并不等于系统吞吐量的设定;
其次,系统目前有多大数据量,增加速度是前提;
● 错误率
指标再高,有错误也没用。
咱们能够尝试这样来设定:
例以下单操做,
响应时间95%<1s
吞吐量>10万tps
系统数据量:10亿>订单表>1亿……
增加速度:1亿/年
资源限制:服务器资源……
其余影响因素……
同时,其余目标也要同步设定,例如系统总体可用性、一致性等。
第二步,寻找瓶颈点。
首先进行压力测试。能够从生产环境引流进行测试,测试环境测出来的结果毫无心义。另外,要基于场景测试,单测某个功能无心义。
其次,要进行全面的监控,包括调用链分析,快速定位性能瓶颈点。
第三步,优化。
优化的手段有不少,包括:同步转异步、阻塞转非阻塞、数据冗余、数据拆分、数据合并、压缩、简化业务环节等等。关键取决于应用场景和成本。
服务化框架
如图1所示,一个电商里的详情页面会调用价格、库存、商品等服务,综合展现信息,若是是串行调用,总耗时等于每一个服务耗时之和;若是是并行调用,总耗时等于三个服务耗时的最大值,性能提高显著。
还有不少其余的优化点,例如:
● 使用高效的序列化协议,protobuf、thrift等协议要比http+json的方式好不少,能够在服务内部使用;
● 采用长链接,避免重复创建链接致使的性能损失;
● 业务线程和IO线程隔离等。
消息中间件
经过消息中间件能够削峰填谷,提高吞吐量。如图2,下单操做直接发送到MQ即返回,由MQ保障最终一致性,还可以下降响应时间。把依赖关系从强依赖变成弱依赖。也就是说,订单系统的暂时不可用,对下单操做无影响。另外,MQ的吞吐量远远大于关系型数据库,MQ扩展相对要方便不少。
固然,使用MQ也有必定的问题,有一个一致性的时间窗口,对于要求强一致的业务来讲,是比较致命的。
分布式缓存
缓存是被用来提高性能的利器。本地缓存不能共享,会致使比较大的内存浪费,另外一方面,垃圾回收也会影响业务服务。在微服务架构中,咱们广泛要求把状态外置到缓存、数据库中,大型应用多采用分布式缓存。
因为数据库扩展起来比较复杂,带来的后遗症较多,用缓存来平衡数据库的压力是很是好的作法。
分布式缓存,例如redis、memcache,吞吐量大概在10万qps这个级别,相对数据库几千qps来讲是一个很是大的提高。
固然,分布式缓存带来的问题就是一致性的问题,何时去更新缓存?若是缓存更新失败、数据库更新成功怎么办?
数据库
数据库的优化是很是直接有效的。
以优先级来排序,优化的方式以下:
● 索引、冗余、批量写入
● 减少锁粒度
● 减少复杂查询
● 适当转移事务处理
● 提高硬件性能
● 读写分离
● 分库
● 垂直分表
● 水平分表
● 根据业务状况选择NoSql
3、案例分析
如图3,在电商中,一个价格服务,为了提高写的效率,能够采用消息中间件,为了解决重复提交的问题,(特别是当某个系统不可用的时候,用户会频繁提交,致使人为的风暴)能够经过缓存去作排重。
若是一个用户提交了一百万价格变更信息,另外一个用户提交了一个价格修改请求,这个请求会被那一百万请求阻塞很长时间,这时候就须要消息中间件有优先级的概念,若是不能作优先级,能够经过创建多个队列分类来解决问题。
若是一个用户提交了一百万条价格修改,发现其中有一个错了,改了其中一条再提交,按照上述方式会致使新版本被老版本覆盖,咱们须要经过创建版本号的方式解决这个问题。
4、总结
● 并非全部的地方都须要高性能,须要权衡代码可读性维护性,架构复杂度 ;
● 优化以前,找到驱动力;
● 正确对待优化带来的其余问题。
11月9-12日,北京国家会议中心,第六届TOP100全球软件案例研究峰会,华为精益敏捷专家陈军将分享《华为百人团队精益看板演进变革之路》;华为云计算测试经理李超峰将分享《华为云虚拟化质量平台建设实践》。
TOP100全球软件案例研究峰会已举办六届,甄选全球软件研发优秀案例,每一年参会者达2000人次。包含产品、团队、架构、运维、大数据、人工智能等多个技术专场,现场学习谷歌、微软、腾讯、阿里、百度等一线互联网企业的最新研发实践。大会开幕式单天体验票申请入口