《什么是微服务.docx》由会员分享,可在线阅读,更多相关《什么是微服务.docx(29页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、什么是微服务一、微效劳介绍1.什么是微效劳在介绍微效劳时首先得先理解什么是微效劳顾名思义微效劳得从两个方面去理解什么是微、什么是效劳微狭义来讲就是体积小、著名的2pizza团队很好的诠释了这一解释2pizza团队最早是亚马逊CEOBezos提出来的意思是讲单个效劳的设计所有介入人从设计、开发、测试、运维所有人加起来只需要2个披萨就够了。而所谓效劳一定要区别于系统效劳一个或一组相对较小且独立的功能单元是用户可以感悟最小功能集。2.微效劳来历微效劳最早由MartinFowler与JamesLewis于2021年度共同提出微效劳架构风格是一种使用一套小效劳来开发单个应用的方式途径每个效劳运行在自己的
2、进程中并使用轻量级机制通信通常是HTTPAPI这些效劳基于业务才能构建并可以通过自动化部署机制来独立部署这些效劳使用不同的编程语言实现和不同数据存储技术并保持最低限度的集中式管理。3.为什么需要微效劳在传统的IT行业软件大多都是各种独立系统的堆砌这些系统的问题总结来讲就是扩展性差可靠性不高维护本钱高。到后面引入了SOA效劳化但是由于SOA早期均使用了总线形式这种总线形式是与某种技术栈强绑定的比方J2EE。这导致很多企业的遗留系统很难对接切换时间太长本钱太高新系统稳定性的收敛也需要一些时间。最终SOA看起来很美但却成为了企业级奢侈品中小公司都望而生畏。3.1最期的单体架构带来的问题单体架构在规模
3、比拟小的情况下工作情况良好但是随着系统规模的扩大它暴露出来的问题也越来越多主要有以下几点1.复杂性逐渐变高比方有的工程有几十万行代码各个模块之间区别比拟模糊逻辑比拟混乱代码越多复杂性越高越难解决遇到的问题。2.技术债务逐渐上升公司的人员流动是再正常不过的事情有的员工在离任之前疏于代码质量的自己管束导致留下来很多坑由于单体工程代码量庞大的惊人留下的坑很难被觉察这就给新来的员工带来很大的烦恼人员流动越大所留下的坑越多也就是所谓的技术债务越来越多。3.部署速度逐渐变慢这个就很好理解了单体架构模块非常多代码量非常庞大导致部署工程所花费的时间越来越多曾经有的工程启动就要一二特别钟这是多么恐惧的事情啊启动
4、几次工程一天的时间就过去了留给开发者开发的时间就非常少了。4.阻碍技术创新比方以前的某个工程使用struts2写的由于各个模块之间有着千丝万缕的联络代码量大逻辑不够清楚假如如今想用springmvc来重构这个工程将是非常困难的付出的本钱将非常大所以更多的时候公司不得不硬着头皮继续使用老的struts架构这就阻碍了技术的创新。5.无法按需伸缩比方讲电影模块是CPU密集型的模块而订单模块是IO密集型的模块假设我们要提升订单模块的性能比方加大内存、增加硬盘但是由于所有的模块都在一个架构下因此我们在扩展订单模块的性能时不得不考虑其它模块的因素因为我们不能因为扩展某个模块的性能而损害其它模块的性能进而无
5、法按需进展伸缩。3.2微效劳与单体架构区别单体架构所有的模块全都耦合在一块代码量大维护困难微效劳每个模块就相当于一个单独的工程代码量明显减少遇到问题也相对来讲比拟好解决。单体架构所有的模块都共用一个数据库存储方式比拟单一微效劳每个模块都可以使用不同的存储方式比方有的用redis有的用mysql等数据库也是单个模块对应自己的数据库。单体架构所有的模块开发所使用的技术一样微效劳每个模块都可以使用不同的开发技术开发形式更灵敏。3.3微效劳与SOA区别微效劳从本质意义上看还是SOA架构。但内涵有所不同微效劳并不绑定某种特殊的技术在一个微效劳的系统中可以有Java编写的效劳可以以有Python编写的效劳
6、他们是靠Restful架构风格统一成一个系统的。所以微效劳本身与详细技术实现无关扩展性强。4.微效劳本质微效劳关键其实不仅仅是微效劳本身而是系统要提供一套根底的架构这种架构使得微效劳可以独立的部署、运行、晋级不仅如此这个系统架构还让微效劳与微效劳之间在构造上“松耦合而在功能上那么表现为一个统一的整体。这种所谓的“统一的整体表现出来的是统一风格的界面统一的权限管理统一的平安策略统一的上线经过统一的日志以及审计方法统一的调度方式统一的访问入口等等。微效劳的目的是有效的拆分应用实现敏捷开发以及部署。微效劳提倡的理念团队间应该是inter-operate,notintegrate。inter-oper
7、ate是定义好系统的边界以及接口在一个团队内全栈让团队自治原因就是因为假如团队按照这样的方式组建将沟通的本钱维持在系统内部每个子系统就会更加内聚彼此的依赖耦合能变弱跨系统的沟通本钱也就能降低。5.什么样的工程合适微效劳微效劳可以按照业务功能本身的独立性来划分假如系统提供的业务是非常底层的如操作系统内核、存储系统、网络系统、数据库系统等等这类系统都偏底层功能以及功能之间有着严密的配合关系假如强迫拆分为较小的效劳单元会让集成工作量急剧上升并且这种人为的切割无法带来业务上的真正的隔离所以无法做到独立部署以及运行也就不合适做成微效劳了。能不能做成微效劳取决于四个要素小微效劳体积小2pizza团队。独可
8、以独立的部署以及运行。轻使用轻量级的通信机制以及架构。松为效劳之间是松耦合的。6.微效劳折分与设计从单体式构造转向微效劳架构中会持续碰到效劳边界划分的问题比方我们有user效劳来提供用户的根底信息那么用户的头像以及图片等是应该单独划分为一个新的service更好还是应该合并到user效劳里呢假如效劳的粒度划分的过粗那就回到了单体式的老路假如过细那效劳间调用的开销就变得不可无视了管理难度也会指数级增加。目前为止还没有一个可以称之为效劳边界划分的标准只能根据不同的业务系统加以调节拆分的大原那么是当一块业务不依赖或者极少依赖其它效劳有独立的业务语义为超过2个的其他效劳或者客户端提供数据那么它就应该被
9、拆分成一个独立的效劳模块。6.1微效劳设计原那么单一职责原那么意思是每个微效劳只需要实现自己的业务逻辑就可以了比方订单管理模块它只需要处理订单的业务逻辑就可以了其它的不必考虑。效劳自治原那么意思是每个微效劳从开发、测试、运维等都是独立的包括存储的数据库也都是独立的自己就有一套完好的流程我们完全可以把它当成一个工程来对待。不必依赖于其它模块。轻量级通信原那么首先是通信的语言非常的轻量第二该通信方式需要是跨语言、跨平台的之所以要跨平台、跨语言就是为了让每个微效劳都有足够的独立性可以不受技术的钳制。接口明确原那么由于微效劳之间可能存在着调用关系为了尽量防止以后由于某个微效劳的接口变化而导致其它微效劳
10、都做调整在设计之初就要考虑到所有情况让接口尽量做的更通用更灵敏进而尽量防止其它模块也做调整。7.微效劳优势与缺点7.1特性每个微效劳可独立运行在自己的进程里一系列独立运行的微效劳共同构建起了整个系统每个效劳为独立的业务开发一个微效劳一般完成某个特定的功能比方订单管理用户管理等微效劳之间通过一些轻量级的通信机制进展通信例如通过RESTAPI或RPC的方式进展调用。7.2特点易于开发以及维护由于微效劳单个模块就相当于一个工程开发这个模块我们就只需关心这个模块的逻辑即可代码量以及逻辑复杂度都会降低进而易于开发以及维护。启动较快这是相对单个微效劳来讲的相比于启动单体架构的整个工程启动某个模块的效劳速度
11、明显是要快很多的。部分修改容易部署在开发中发现了一个问题假如是单体架构的话我们就需要重新发布并启动整个工程非常耗时间但是微效劳那么不同哪个模块出现了bug我们只需要解决那个模块的bug就可以了解决完bug之后我们只需要重启这个模块的效劳即可部署相对简单不必重启整个工程进而大大节约时间。技术栈不受限比方订单微效劳以及电影微效劳原来都是用java写的如今我们想把电影微效劳改成nodeJs技术这是完全可以的而且由于所关注的只是电影的逻辑而已因此技术更换的本钱也就会少很多。按需伸缩我们上面讲了单体架构在想扩展某个模块的性能时不得不考虑到其它模块的性能会不会受影响对于我们微效劳来讲完全不是问题电影模块通
12、过什么方式来提升性能不必考虑其它模块的情况。7.3缺点运维要求较高对于单体架构来讲我们只需要维护好这一个工程就可以了但是对于微效劳架构来讲由于工程是由多个微效劳构成的每个模块出现问题都会造成整个工程运行出现异常想要知道是哪个模块造成的问题往往是不容易的因为我们无法一步一步通过debug的方式来跟踪这就对运维人员提出了很高的要求。分布式的复杂性对于单体架构来讲我们可以不使用分布式但是对于微效劳架构来讲分布式几乎是必会用的技术由于分布式本身的复杂性导致微效劳架构也变得复杂起来。接口调整本钱高比方用户微效劳是要被订单微效劳以及电影微效劳所调用的一旦用户微效劳的接口发生大的变动那么所有依赖它的微效劳都
13、要做相应的调整由于微效劳可能非常多那么调整接口所造成的本钱将会明显进步。重复劳动对于单体架构来讲假如某段业务被多个模块所共同使用我们便可以抽象成一个工具类被所有模块直接调用但是微效劳却无法这样做因为这个微效劳的工具类是不能被其它微效劳所直接调用的进而我们便不得不在每个微效劳上都建这么一个工具类进而导致代码的重复。8.微效劳开发框架目前微效劳的开发框架最常用的有以下四个SpringCloud:/projects.spring.io/spring-cloud如今非常流行的微效劳架构Dubbo/dubbo.ioDropwizard:/dropwizard.io关注单个微效劳的开发Consul、etc
14、detc.微效劳的模块9.Sprintcloud以及Sprintboot区别SpringBoot:旨在简化创立产品级的Spring应用以及效劳简化了配置文件使用嵌入式web效劳器含有众多开箱即用微效劳功能可以以及springcloud结合部署。SpringCloud微效劳工具包为开发者提供了在分布式系统的配置管理、效劳发现、断路器、智能路由、微代理、控制总线等开发工具包。二、微效劳理论先知1.客户端怎样访问这些效劳APIGateway传统的开发方式所有的效劳都是本地的UI可以直接调用如今按功能拆分成独立的效劳跑在独立的一般都在独立的虚拟机上的Java进程了。客户端UI怎样访问他的后台有N个效劳
15、前台就需要记住管理N个效劳一个效劳下线/更新/晋级前台就要重新部署这明显不效劳我们拆分的理念十分当前台是挪动应用的时候通常业务变化的节奏更快。另外N个小效劳的调用也是一个不小的网络开销。还有一般微效劳在系统内部通常是无状态的用户登录信息以及权限管理最好有一个统一的地方维护管理OAuth。所以一般在后台N个效劳以及UI之间一般会一个代理或叫APIGateway他的作用包括提供统一效劳入口让微效劳对前台透明聚合后台的效劳节省流量提升性能提供平安过滤流控等API管理功能我的理解其实这个APIGateway可以有很多广义的实现方法可以是一个软硬一体的盒子可以以是一个简单的MVC框架甚至是一个Node.
16、js的效劳端。他们最重要的作用是为前台通常是挪动应用提供后台效劳的聚合提供一个统一的效劳出口解除他们之间的耦合不过APIGateway也有可能成为单点故障点或性能的瓶颈。2.效劳之间怎样通信效劳调用因为所有的微效劳都是独立的Java进程跑在独立的虚拟机上所以效劳间的通行就是IPCinterprocesscommunication已经有很多成熟的方案。如今根本最通用的有两种方式。这几种方式展开来讲都可以写本书而且大众一般都比拟熟悉细节了就不展开讲了。RESTJAX-RSSpringBootRPCThrift,Dubbo异步消息调用(Kafka,Notify)一般同步调用比拟简单一致性强但是容易出
17、调用问题性能体验上也会差些十分是调用层次多的时候。RESTful以及RPC的比拟也是一个很有意思的话题。一般REST基于HTTP更容易实现更容易被承受效劳端实现技术也更灵敏些各个语言都能支持同时能跨客户端对客户端没有特殊的要求只要封装了HTTP的SDK就能调用所以相对使用的广一些。RPC也有自己的优点传输协议更高效平安更可控十分在一个公司内部假如有统一个的开发标准以及统一的效劳框架时他的开发效率优势更明显些。就看各自的技术积累实际条件自己的选择了。而异步消息的方式在分布式系统中有十分广泛的应用他既能减低调用效劳之间的耦合又能成为调用之间的缓冲确保消息积压不会冲垮被调用方同时能保证调用方的效劳体
18、验继续干自己该干的活不至于被后台性能拖慢。不过需要付出的代价是一致性的减弱需要承受数据最终一致性还有就是后台效劳一般要实现幂等性因为消息发送出于性能的考虑一般会有重复保证消息的被收到且仅收到一次对性能是很大的考验最后就是必须引入一个独立的broker如果公司内部没有技术积累对broker分布式管理也是一个很大的挑战。3.这么多效劳怎么查找效劳发现在微效劳架构中一般每一个效劳都是有多个拷贝来做负载平衡。一个效劳随时可能下线可以能应对临时访问压力增加新的效劳节点。效劳之间怎样互相感悟效劳怎样管理这就是效劳发现的问题了。一般有两类做法也各有优缺点。根本都是通过zookeeper等类似技术做效劳注册信
19、息的分布式管理。当效劳上线时效劳提供者将自己的效劳信息注册到ZK或者类似框架并通过心跳维持长链接实时更新链接信息。效劳调用者通过ZK寻址根据可定制算法找到一个效劳还可以将效劳信息缓存在本地以进步性能。当效劳下线时ZK会发通知给效劳客户端。客户端做优点是架构简单扩展灵敏只对效劳注册器依赖。缺点是客户端要维护所有调用效劳的地址有技术难度一般大公司都有成熟的内部框架支持比方Dubbo。效劳端做优点是简单所有效劳对于前台调用方透明一般在小公司在云效劳上部署的应用采用的比拟多。4.效劳挂了怎么办分布式最大的特性就是网络是不可靠的。通过微效劳拆分能降低这个风险不过假如没有十分的保障结局肯定是噩梦。我们刚遇
20、到一个线上故障就是一个很不起眼的SQL计数功能在访问量上升时导致数据库load彪高影响了所在应用的性能进而影响所有调用这个应用效劳的前台应用。所以当我们的系统是由一系列的效劳调用链组成的时候我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多重试机制限流熔断机制负载平衡降级本地缓存这些方法根本上都很明确通用就不详细讲明了。比方Netflix的Hystrixs:/github/Netflix/Hystrix5.微效劳需要考虑的问题这里有一个图非常好的总结微效劳架构需要考虑的问题包括APIGateway效劳间调用效劳发现效劳容错效劳部署数据调用三、微效劳重要部件1.微效劳根本才能2.效
21、劳注册中心效劳之间需要创立一种效劳发现机制用于帮助效劳之间相互感悟彼此的存在。效劳启动时会将自身的效劳信息注册到注册中心并订阅自己需要消费的效劳。效劳注册中心是效劳发现的核心。它保存了各个可用效劳实例的网络地址IPAddress以及Port。效劳注册中心必需要有高可用性以及实时更新功能。上面提到的NetflixEureka就是一个效劳注册中心。它提供了效劳注册以及查询效劳信息的RESTAPI。效劳通过使用POST恳求注册自己的IPAddress以及Port。每30秒发送一个PUT恳求刷新注册信息。通过DELETE恳求注销效劳。客户端通过GET恳求获取可用的效劳实例信息。Netflix的高可用N
22、etflixachieveshighavailability是通过在AmazonEC2运行多个实例来实现的,每一个Eureka效劳都有一个弹性IPAddress。当Eureka效劳启动时有DNS效劳器动态的分配。Eureka客户端通过查询DNS来获取Eureka的网络地址IPAddress以及Port。一般情况下都是返回以及客户端在同一个可用区Eureka效劳器地址。其他可以作为效劳注册中心的有etcd高可用分布式强一致性的key-valueKubernetes以及CloudFoundry都是使用了etcd。consul一个用于discovering以及configuring的工具。它提供了允
23、许客户端注册以及发现效劳的API。Consul可以进展效劳安康检查以确定效劳的可用性。zookeeper在分布式应用中被广泛使用高性能的协调效劳。ApacheZookeeper最初为Hadoop的一个子工程但如今是一个顶级工程。2.1zookeeper效劳注册以及发现简单来讲zookeeper可以充当一个效劳注册表ServiceRegistry让多个效劳提供者形成一个集群让效劳消费者通过效劳注册表获取详细的效劳访问地址ip端口去访问详细的效劳提供者。如下列图所示详细来讲zookeeper就是个分布式文件系统每当一个效劳提供者部署后都要将自己的效劳注册到zookeeper的某一途径上:/serv
24、ice/version/ip:port,比方我们的HelloWorldService部署到两台机器那么zookeeper上就会创立两条目录分别为/HelloWorldService/1.0.0/100.19.20.01:16888/HelloWorldService/1.0.0/100.19.20.02:16888。zookeeper提供了“心跳检测功能它会定时向各个效劳提供者发送一个恳求实际上建立的是一个socket长连接假如长期没有响应效劳中心就认为该效劳提供者已经“挂了并将其剔除比方100.19.20.02这台机器假如宕机了那么zookeeper上的途径就会只剩/HelloWorldSe
25、rvice/1.0.0/100.19.20.01:16888。效劳消费者会去监听相应途径/HelloWorldService/1.0.0一旦途径上的数据有任务变化增加或者减少zookeeper都会通知效劳消费方效劳提供者地址列表已经发生改变进而进展更新。更为重要的是zookeeper与生俱来的容错容灾才能比方leader选举可以确保效劳注册表的高可用性。3.负载平衡效劳高可用的保证手段为了保证高可用每一个微效劳都需要部署多个效劳实例来提供效劳。此时客户端进展效劳的负载平衡。3.1负载平衡的常见策略3.1.1随机把来自网络的恳求随机分配给内部中的多个效劳器。3.1.2轮询每一个来自网络中的恳求轮
26、流分配给内部的效劳器从1到N然后重新开场。此种负载平衡算法合适效劳器组内部的效劳器都具有一样的配置并且平均效劳恳求相对平衡的情况。3.1.3加权轮询根据效劳器的不同处理才能给每个效劳器分配不同的权值使其可以承受相应权值数的效劳恳求。例如效劳器A的权值被设计成1B的权值是3C的权值是6那么效劳器A、B、C将分别承受到10%、30、60的效劳恳求。此种平衡算法能确保高性能的效劳器得到更多的使用率防止低性能的效劳器负载过重。3.1.4IPHash这种方式通过生成恳求源IP的哈希值并通过这个哈希值来找到正确的真实效劳器。这意味着对于同一主机来讲他对应的效劳器总是一样。使用这种方式你不需要保存任何源IP
27、。但是需要注意这种方式可能导致效劳器负载不平衡。3.1.5最少连接数客户端的每一次恳求效劳在效劳器停留的时间可能会有较大的差异随着工作时间加长假如采用简单的轮循或者随机平衡算法每一台效劳器上的连接进程可能会产生极大的不同并没有到达真正的负载平衡。最少连接数平衡算法对内部中需负载的每一台效劳器都有一个数据记录记录当前该效劳器正在处理的连接数量当有新的效劳连接恳求时将把当前恳求分配给连接数最少的效劳器使平衡更加符合实际情况负载更加平衡。此种平衡算法合适长时处理的恳求效劳如FTP。4.容错容错这个词的理解直面意思就是可以容下错误不让错误再次扩张让这个错误产生的影响在一个固定的边界之内“千里之堤毁于蚁
28、穴我们用容错的方式就是让这种蚁穴不要变大。那么我们常见的降级限流熔断器超时重试等等都是容错的方法。在调用效劳集群时假如一个微效劳调用异常如超时连接异常网络异常等那么根据容错策略进展效劳容错。目前支持的效劳容错策略有快速失败失效切换。假如连续失败屡次那么直接熔断不再提议调用。这样可以防止一个效劳异常拖垮所有依赖于他的效劳。4.1容错策略4.1.1快速失败效劳只提议一次待用失败立即报错。通常用于非幂等下性的写操作4.1.2失效切换效劳提议调用当出现失败后重试其他效劳器。通常用于读操作但重试会带来更长时间的延迟。重试的次数通常是可以设置的4.1.3失败平安失败平安当效劳调用出现异常时直接忽略。通常用
29、于写入日志等操作。4.1.4失败自动恢复当效劳调用出现异常时记录失败恳求定时重发。通常用于消息通知。4.1.5forkingCluster并行调用多个效劳器只要有一个成功即返回。通常用于实时性较高的读操作。可以通过forksn来设置最大并行数。4.1.6播送调用播送调用所有提供者逐个调用任何一台失败那么失败。通常用于通知所有提供者更新缓存或者日志等本地资源信息。5.熔断熔断技术可以讲是一种“智能化的容错当调用知足失败次数失败比例就会触发熔断器翻开有程序自动切断当前的RPC调用,来防止错误进一步扩大。实现一个熔断器主要是考虑三种形式关闭翻开半开。各个状态的转换如下列图。我们在处理异常的时候要根据
30、详细的业务情况来决定处理方式比方我们调用商品接口对方只是临时做了降级处理那么作为网关调用就要切到可交换的效劳上来执行或获取托底数据给用户友好提示。还有要区分异常的类型比方依赖的效劳崩溃了这个可能需要花费比拟久的时间来解决。可以能是由于效劳器负载临时过高导致超时。作为熔断器应该可以甄别这种异常类型进而根据详细的错误类型调整熔断策略。增加手动设置在失败的效劳恢复时间不确定的情况下管理员可以手动强迫切换熔断状态。最后熔断器的使用场景是调用可能失败的远程效劳程序或分享资源。假如是本地缓存本地私有资源使用熔断器那么会增加系统的额外开销。还要注意熔断器不能作为应用程序中业务逻辑的异常处理替代品。有一些异常
31、比拟顽固突然发生无法预测而且很难恢复并且还会导致级联失败举个例子假设一个效劳集群的负载非常高假如这时候集群的一局部挂掉了还占了很大一局部资源整个集群都有可能遭殃。假如我们这时还是不断进展重试的话结果大多都是失败的。因此此时我们的应用需要立即进入失败状态(fast-fail)并采取适宜的方法进展恢复。我们可以用状态机来实现CircuitBreaker它有以下三种状态关闭(Closed)默认情况下CircuitBreaker是关闭的此时允许操作执行。CircuitBreaker内部记录着最近失败的次数假如对应的操作执行失败次数就会续一次。假如在某个时间段内失败次数或失败比率到达阈值CircuitB
32、reaker会转换到开启(Open)状态。在开启状态中CircuitBreaker会启用一个超时计时器设这个计时器的目的是给集群相应的时间来恢复故障。当计时器时间到的时候CircuitBreaker会转换到半开启(Half-Open)状态。开启(Open)在此状态下执行对应的操作将会立即失败并且立即抛出异常。半开启(Half-Open)在此状态下CircuitBreaker会允许执行一定数量的操作。假如所有操作全部成功CircuitBreaker就会假定故障已经恢复它就会转换到关闭状态并且重置失败次数。假如其中任意一次操作失败了CircuitBreaker就会认为故障仍然存在所以它会转换到开启
33、状态并再次开启计时器再给系统一些时间使其从失败中恢复6.限流以及降级保证核心效劳的稳定性。为了保证核心效劳的稳定性随着访问量的不断增加需要为系统可以处理的效劳数量设置一个极限阀值超过这个阀值的恳求那么直接回绝。同时为了保证核心效劳的可用可以对否些非核心效劳进展降级通过限制效劳的最大访问量进展限流通过管理控制台对单个微效劳进展人工降级7.SLASLAService-LevelAgreement的缩写意思是效劳等级协议。是关于网络效劳供给商以及客户间的一份合同其中定义了效劳类型、效劳质量以及客户付款等术语。典型的SLA包括以下工程分配给客户的最小带宽客户带宽极限能同时效劳的客户数目在可能影响用户行
34、为的网络变化之前的通知安排拨入访问可用性运用统计学效劳供给商支持的最小网络利用性能如99.9%有效工作时间或者每天最多为1分钟的停机时间各类客户的流量优先权客户技术支持以及效劳惩罚规定为效劳供给商不能知足SLA需求所指定。8.API网关这里讲的网关是指API网关直面意思是将所有API调用统一接入到API网关层有网关层统一接入以及输出。一个网关的根本功能有统一接入、平安防护、协议适配、流量管控、长短链接支持、容错才能。有了网关之后各个API效劳提供团队可以专注于自己的的业务逻辑处理而API网关更专注于平安、流量、路由等问题。9.多级缓存最简单的缓存就是查一次数据库然后将数据写入缓存比方redis
35、中并设置过期时间。因为有过期失效因此我们要关注下缓存的穿透率这个穿透率的计算公式比方查询方法queryOrder(调用次数1000/1s)里面嵌套查询DB方法queryProductFromDb(调用次数300/s)那么redis的穿透率就是300/1000,在这种使用缓存的方式下是要重视穿透率的穿透率大了讲明缓存的效果不好。还有一种使用缓存的方式就是将缓存持久化也就是不设置过期时间这个就会面临一个数据更新的问题。一般有两种方法一个是利用时间戳查询默认以redis为主每次设置数据的时候放入一个时间戳每次读取数据的时候用系统当前时间以及上次设置的这个时间戳做比照比方超过5分钟那么就再查一次数据库
36、。这样可以保证redis里面永远有数据一般是对DB的一种容错方法。还有一个就是真正的让redis做为DB使用。就是图里面画的通过订阅数据库的binlog通过数据异构系统将数据推送给缓存同时将将缓存设置为多级。可以通过使用jvmcache作为应用内的一级缓存一般是体积小访问频率大的更合适这种jvmcache方式将一套redis作为二级remote缓存另外最外层三级redis作为持久化缓存。10.超时以及重试超时与重试机制也是容错的一种方法但凡发生RPC调用的地方比方读取redisdbmq等因为网络故障或是所依赖的效劳故障长时间不能返回结果就会导致线程增加加大cpu负载甚至导致雪崩。所以对每一个R
37、PC调用都要设置超时时间。对于强依赖RPC调用资源的情况还要有重试机制但是重试的次数建议1-2次另外假如有重试那么超时时间就要相应的调小比方重试1次那么一共是发生2次调用。假如超时时间配置的是2s那么客户端就要等待4s才能返回。因此重试超时的方式超时时间要调小。这里也再谈一下一次PRC调用的时间都消耗在哪些环节一次正常的调用统计的耗时主要包括调用端RPC框架执行时间网络发送时间效劳端RPC框架执行时间效劳端业务代码时间。调用方以及效劳方都有各自的性能监控比方调用方tp99是500ms效劳方tp99是100ms找了网络组的同事确认网络没有问题。那么时间都花在什么地方了呢两种原因客户端调用方还有一
38、个原因是网络发生TCP重传。所以要注意这两点。11.线程池隔离在抗量这个环节Servlet3异步的时候有提到过线程隔离。线程隔离的之间优势就是防止级联故障甚至是雪崩。当网关调用N多个接口效劳的时候我们要对每个接口进展线程隔离。比方我们有调用订单、商品、用户。那么订单的业务不可以影响到商品以及用户的恳求处理。假如不做线程隔离当访问订单效劳出现网络故障导致延时线程积压最终导致整个效劳CPU负载满。就是我们讲的效劳全部不可用了有多少机器都会被此刻的恳求塞满。那么有了线程隔离就会使得我们的网关能保证部分问题不会影响全局。12.降级以及限流关于降级限流的方法业界都已经有很成熟的方法了比方FAILBACK
39、机制限流的方法令牌桶漏桶信号量等。这里谈一下我们的一些经历降级一般都是由统一配置中心的降级开关来实现的那么当有很多个接口来自同一个提供方这个提供方的系统或者这机器所在机房网络出现了问题我们就要有一个统一的降级开关不然就要一个接口一个接口的来降级。也就是要对业务类型有一个大闸刀。还有就是降级切记暴力降级什么是暴力降级的比方把论坛功能降调结果用户显示一个大白板我们要实现缓存住一些数据也就是有托底数据。限流一般分为分布式限流以及单机限流假如实现分布式限流的话就要一个公共的后端存储效劳比方redis在大nginx节点上利用lua读取redis配置信息。我们如今的限流都是单机限流并没有施行分布式限流。13.网关监控以及统计API网关是一个串行的调用那么每一步发生的异常要记录下来统一存储到一个地方比方elasticserach中便于后续对调用异常的分析。鉴于公司docker申请都是统一分配而且分配之前docker上已经存在3个agent了不再允许增加。我们自己实现了一个agent程序来负责收集效劳器上面的日志输出然后发送到kafka集群再消费到elasticserach中通过web查询。如今做的追踪功能还比拟简单这块还需要继续丰富。武晓兵