这几天每个人都在谈论微服务。微服务之所以火热,是因为与以往的应用开发方式相比,它有很多优势,比如更灵活,更能适应当前需求快速变化的环境。本文将介绍微服务架构设计中的一些要点。微服务架构设计的重点是什么?首先看下图是SpringCloud的整个生态。下图展示了微服务最佳实现的十二条原则:接下来,我将详细阐述微服务架构设计中必须知道的十个关键点。负载均衡+API网关在实现微服务的过程中,不可避免要面对服务的聚合和拆分。当后端服务拆分比较频繁的时候,作为一个移动端APP,往往需要一个统一的入口,将不同的请求路由到不同的服务。是透明的。通过API网关,可以在网关层做简单的数据聚合,不需要在手机APP端做,手机APP功耗更低,用户体验更好。有了统一的API网关,也可以进行统一的鉴权和鉴权,虽然服务之间的相互调用会更复杂,接口也会更多。API网关往往只对外暴露必要的接口,并对接口进行统一的认证和认证,这样内部服务相互访问时,就不需要进行认证和鉴权,效率会更高。通过统一的API网关,可以在这一层设置一定的策略,进行A/B测试、蓝绿发布、预发布环境导流等。API网关往往是无状态的,可以横向扩展而不会成为性能瓶颈。Statelessandindependentstatefulclusterx`影响应用迁移和水平扩展的一个重要因素是应用的状态。无状态服务就是把这个状态搬出去,把session数据、文件数据、结构化数据存储在后端统一存储,让应用只包含业务逻辑。状态是不可避免的,比如ZooKeeper、DB、Cache等等,把这些有状态的东西都汇聚在一个非常中心化的集群中。整个业务分为两部分,一个是无状态部分,一个是有状态部分。无状态部分可以实现两点:跨机房随机部署,即移动性。弹性伸缩,轻松扩容。ZooKeeper、DB、Cache等有状态的部分都有自己的高可用机制,它们必须使用自己的高可用机制来实现这个有状态的集群。虽然是无状态的,但是当前处理的数据还是会在内存中。如果当前进程挂了,一定会丢失一些数据。为了实现这一点,服务必须有重试机制,接口必须有幂等机制。通过服务发现机制,再次调用后端服务的另一个实例即可。数据库的横向扩展数据库是保存状态的,这是最重要的,也是最容易出现瓶颈的。使用分布式数据库,数据库的性能可以随着节点的增加而线性增加。分布式数据库最底层是RDS,主备。通过MySQL的内核开发能力,我们可以实现主备倒换时的数据零丢失。因此,您可以放心,数据落在这个RDS中。即使一个节点挂了,切换后你的数据也不会丢失。再往上就是如何横向承载大吞吐量的问题。上面有一个负载均衡NLB,使用了LVS、HAProxy、Keepalived,下面连接了一层QueryServer。QueryServer可以根据监控数据进行横向扩展。如果发生故障,可以随时更换和修复,而无需业务层感知。另一种是双机房的部署。DDB开发了数据通道NDC组件,可以同步不同机房的不同DDB。这时候不仅是分布在一个数据中心,在多个数据中心也会有类似双活的备份,保证了高可用。缓存在高并发场景下非常重要。一定要有分级缓存,让数据尽可能靠近用户。数据离用户越近,并发度越大,响应时间越短。移动客户端应用程序上应该有一层缓存。并不是所有的数据都是一直从后端取的,只有重要的、关键的、不断变化的数据。尤其是静态数据,你可以偶尔检索一次,不需要去数据中心检索。可以通过CDN将数据缓存在离客户端最近的节点上,就近下载。有的时候没有CDN,还是要回数据中心下载,这叫回源。在数据中心的最外层,我们称之为接入层。可以设置一层缓存,拦截大部分请求,以免对后台数据库造成压力。如果是动态数据,还是需要访问应用,通过应用中的业务逻辑生成,或者从数据库中读取。为了减轻数据库的压力,应用程序可以使用本地缓存或分布式缓存。比如Memcached或者Redis,这样大部分的请求都可以在不访问数据库的情况下从缓存中读取。当然动态数据也可以在一定程度上静态化,即降级为静态数据,从而减轻后端的压力。服务拆分和服务发现当系统无法处理,应用快速变化时,往往需要考虑将一个比较大的服务拆分成一系列的小服务。这样做的第一个好处是开发相对独立。当多人在维护同一个代码仓库时,代码的改动往往会相互影响。经常会出现我什么都不改,测试失败,提交代码时,经常会发生冲突,需要合并代码,大大降低了开发效率。另一个优点是在线是独立的。物流模块对接新的快递公司,需要跟订单一起上线,很不合理。如果我没有更改它,我需要重新启动它。如果我没有改变它,我需要释放它。如果我没有改变它,我需要召开会议。这些是应该分开的时间。然后就是高并发时期的扩容。往往只有最关键的订单和支付流程才是核心,只要扩展关键的交易环节。如果此时附加了许多其他服务,扩容不仅不经济,而且成本很高。有风险。另外,为了容灾和降级,在大促的时候可能需要牺牲一些角落功能,但是如果所有的代码耦合在一起,一些角落功能是很难降级的。当然,拆分完成之后,应用之间的关系就变得更加复杂了。因此,需要一种服务发现机制来管理应用程序之间的关系,实现自动修复、自动关联、自动负载均衡、自动容错切换。服务编排和弹性伸缩服务拆分时,会有很多进程。因此需要进行服务编排来管理服务之间的依赖关系,并对服务的部署进行编码,也就是我们常说的基础设施即代码。这样,业务的发布、更新、回滚、扩容、缩容都可以通过修改编排文件来实现,从而增加可追溯性、易管理性和自动化能力。由于布局文件也可以由代码仓库进行管理,因此可以通过修改布局文件中五个服务的配置来更新一百个服务中的五个。提交编排文件后,代码仓库自动触发自动部署升级脚本,更新线上环境。当新环境发现问题时,当然希望这五个服务能自动回滚。如果没有安排文件,则需要手动记录本次升级了哪五项服务。有了布局文件,只要在代码仓库里revert,就会回滚到之前的版本。所有操作都在代码库中可见。统一配置中心服务拆分后,服务数量非常大。如果所有的配置都以配置文件的形式放在应用程序本地,管理起来会非常困难。可想而知,当成百上千个进程之间出现配置问题时,很难发现。因此需要一个统一的配置中心来管理所有的配置,统一下发配置。在微服务中,配置往往分为以下几类:一类是几乎不变的配置,可以直接打到容器镜像中。第二类是将在启动时确定的配置。这个配置往往是在容器启动的时候通过环境变量传入的。第三类是统一配置,需要通过配置中心进行分发。比如大促的时候,有些功能需要降级,哪些功能可以降级,哪些功能不能降级,都可以在配置文件中统一配置。统一的日志中心也有大量的进程,上千个容器很难一一登录查看日志,所以需要一个统一的日志中心来收集日志。为了使采集到的日志便于分析,对日志规范有一定的要求。当所有业务都遵循统一的日志规范时,可以在日志中心统一追溯一个交易过程。比如在最新的日志搜索引擎中,如果搜索事务号,就可以看到是在哪个进程中发生了错误或者异常。熔断、限流、降级服务必须具备熔断、限流、降级的能力。当一个服务调用另一个服务发生超时时,应该及时返回,而不是阻塞在那个地方,从而影响其他用户的交易。返回默认的基础数据。当一个服务发现被调用的服务太忙,线程池满,连接池满,或者一直有错误时,应该及时断开连接,防止因为错误或者繁忙导致服务异常接下来的服务,从而逐渐向前进行,造成整个应用的雪崩。当发现整个系统的负载确实过高时,可以选择降级某些功能或某些调用,以保证最重要的交易流程的通过,将最重要的资源全部用于保证核心流程.另一种方法是限流。当熔断策略和降级策略都设置好后,通过全链路的压测应该可以知道整个系统的支撑能力。因此,需要制定限流策略,保证系统在测试的支持能力范围内提供服务,超过支持能力的服务可以拒绝。下单时,系统弹出对话框说“系统忙,请重试”,这并不是说系统挂了,而是系统正常工作,只是限流策略起到了一定的作用角色。全方位监控当系统非常复杂的时候,统一监控主要有两个方面,一个是它是否健康,另一个是性能瓶颈在哪里。当系统出现异常时,监控系统可以配合报警系统及时发现、通知和干预,确保系统的平稳运行。压测时经常会遇到瓶颈,需要全方位监控发现瓶颈,同时可以保留现场,便于追溯分析,全方位优化.作者:刘超简介:毕业于上海交通大学,拥有15年云计算研发和架构经验,曾在EMC、央视证券资讯频道、惠普、华为、网易从事云计算和大数据架构工作。
