本文主要讲解“如何理解微服务架构下的高可用性和高性能设计”。本文的讲解内容简单明了,易学易懂。请跟随边肖的思路,学习和学习“如何理解微服务架构下的高可用性和高性能设计”。
高可用性三个维度和相互关系
对于业务系统的高可用性,其实包括三个方面:高可靠性、高性能和高扩展性。而且,这三个方面还是有相互依赖和影响的。
对于三者之间的关系,我们可以用下图来描述。
上图展示了高可靠性、高性能和高扩展性之间的关系。
对于高可靠性,传统的HA架构和冗余设计可以满足高可靠性的要求,但并不意味着系统具有高性能和可扩展性。另一方面,当系统具有高扩展性时,我们在设计可扩展性时通常会同时考虑冗余和高可靠性,比如我们常说的集群技术。
对于高性能和高可扩展性来说,高可扩展性是高性能的必要条件,但不是充分条件。一个业务系统的高性能不是简单的扩展能力,而是业务系统本身的软件架构设计,代码编写的各个方面都符合高性能设计的要求。
对于高可靠性和高性能来说,它们呈现出相互制约的关系,即在高性能支持的状态下,往往会对系统的高可靠性提出严峻的挑战。为此,我们将看到各种措施,如限流保险丝和SLA服务降级,以控制异常状态下的大并发访问和调用。
数据库的高可用性
我之前讲微服务架构的时候说过,传统的单一应用应该在微服务架构下拆分,这不仅仅是应用层组件的拆分,也是数据库本身的拆分。
如果一个传统的单一应用程序被规划为10个微服务,它可能会被垂直拆分为10个独立的数据库。这实际上减少了每个数据库本身面临的性能负载,同时提高了数据库的整体处理能力。
同时,虽然拆分后引入了各种跨数据库查询和分布式事务,但实际上很多跨数据库操作和复制的数据处理计算并不是在数据库中完成的,数据库提供了更简单的CRUD操作接口,这也是提高数据库性能的关键。
用Mysql数据库。
为了满足高可靠性,可以采用Dual-Master双主架构,即两个主节点处于活动状态,但只有一个节点提供数据库接口能力,另一个节点作为备用节点实时同步数据库日志。当主节点出现故障时,备用节点会自动改变以服务于主节点。
在简单的双主架构中,代理安装在两个节点之间,由Binlog日志复制,上层由类似的Haproxy Keepalive提供VIP浮动IP和心跳监控。
可以看出,双主控架构更服务于高可靠性。
如果要达到高性能,通常使用读写分离集群。即一个主节点承担读写操作,多个从节点承担读操作。从节点仍然通过Binlog日志同步主节点信息。当有数据访问请求进来时,前端Proxy可以自动分析是CUD请求还是R读请求,从而对请求进行路由转发。
添加订单时,需要在添加成功后快速刷新当前订单列表的界面。第二次刷新本身是读取操作,但与前一次写入绑定紧密,因此实际上不适合从Slave节点读取数据。此时,您可以显式指定在调用Sql时是否仍然从主节点获取数据。
当然,大多数情况下,可能有必要将两者结合起来,这不仅提供了足够高的可靠性,还提供了足够高的性能。因此,在构建Mysql集群时,需要双主节点设置和多从节点设置。
在上面展示的逻辑部署架构下,基本可以同时满足高可靠性和高性能的需求。然而,从上面的架构部署可以看出,备用节点的主节点和从节点都处于热备用实际上不能提供能力的状态。
有没有可能把所有的奴隶挂在一个主人身上?
如果以这种方式设计,当主节点出现故障时,需要自动漂移多个从节点。一方面整体实现复杂,另一方面可靠性不如上述架构。
对数据库性能扩展的思考
首先,看看以前的体系结构本身的一些潜在问题:
首先,CUD操作仍然是提供能力的单个节点。对于读操作占大多数的场景,基本上可以通过双主读写分离集群实现良好的性能扩展。但是,如果CUD经常运行,性能问题仍然可能出现。
其次,数据库性能问题一般分为两个层次,一个是大并发请求下的性能,可以通过集群负载均衡来解决,另一个是单个请求访问大数据库表的模糊查询性能,可以通过服务负载来解决。
也就是说,在上面的设计中,在大并发CUD操作中,大数据表的联查或模糊查询操作可能还是存在明显的性能问题。
如何解决这个问题?
tion/20210521/371/473961.png" alt="如何理解微服务架构下的高可用和高性能设计">
简单来说就是写入通过消息中间件来将同步转异步,进行前端削峰。而对于查询则进行内容缓存或创建二级索引,提升查询效率。
对于查询本身又包括了偏结构化数据查询和处理,类似采用Redis库或Memcached进行缓存;而对于非结构化数据,类似消息报文,日志等采用Solr或ElasticSearch构建二级索引并实现全文检索能力。
当面临大量的数据写入操作类操作的时候,单个Master节点往往性能很难支撑住,这个时候采用类似RabbitMQ,RocketMQ,Kafka等消息中间件来进行异步销峰处理就是必要的。这个异步实际上涉及到两个层面的异步。
其一是对于发短信,记录日志,启流程等接口服务异步。其二是对长耗时写入操作异步,先反馈用户请求收到,处理完再通知用户拿结果。
而对于查询操作,前面谈到的并发查询可以进行集群负载。
但是对于大数据量表,比如上亿记录的大表模糊查询,这块就必须进行二级索引。对这种大的数据表的查询即使没有并发查询,如果不进行二级索引,查询效率和响应速度仍然很慢。
对半结构化信息启用分布式存储
对于类似日志,接口服务调用日志等半结构化信息,本身数据量很大,如果全部存储在结构化数据库中,那么对存储空间需求很大,而且很难扩展。特别是前面的Mysql集群方案本身还是采用本地磁盘进行存储的情况下。
因此需要对历史日志进行清除,同时将历史日志迁移到分布式存储库,比如Hdfs或Hbase库,然后基于分布式存储再构建二级缓存能力。
构建DaaS数据层进行水平扩展
前面谈到在拆分了微服务后已经进行了垂直扩展,比如一个资产管理系统可以拆分为资产新增,资产调拨,资产折旧,资产盘点等10个微服务模块。
但是在拆分后仍然发现资产数据量极大,比如在集团集中化这种大型项目可以看到,一个省的资产数据表就接近上亿条记录。这种时候将所有省数据全部集中化在一个数据库管理不现实。因此需要进一步按省份或组织域进行水平拆分。
在水平拆分后,在上层构建DaaS层提供统一对外访问能力。
应用集群扩展
对于应用集群扩展实际比数据库层要简单,应用中间件层可以很方便的结合集群管理节点或者独立的负载均衡硬件或软件进行集群能力扩展。对于应用集群扩展,本身就是提升整个性能的关键方式。在集群的扩展过程中还是有些问题需要进一步讨论。
集群做到完全的无状态化
如果集群做到完全的无状态化,那么集群就可以做到和负载均衡设备或软件结合来实现负载均衡扩展能力。比如硬件常用的F5或radware等,软件如HAProxy,Nginx等。
Session会话信息如何处理?对于Session本身是有状态的,因此对于Session信息可以考虑存储到数据库或Redis缓存库中。
集群节点在启动的时候往往需要读取一些全局变量或配置文件信息,这些信息如果简单的存在在本地磁盘往往难以集中化管理。因此当前主流思路是启用全局的配置中心来统一管理配置。
如果应用功能实现中存在文件的上传和存储,那么这些文件存储在磁盘本地本身也是有状态的,因此对于这些文件本身也需要通过文件服务能力或分布式对象存储服务能力来实现。
微服务架构下各个微服务间本身存在接口交互和协同,对于接口调用的具体地址信息也需要通过服务注册中心获取,获取后可以缓存在本地,但是必须有变更后实时更新机制。
四层负载和七层负载
首先看下最简单的四层负载和七层负载的一个说明:
-
四层负载:即在OSI第4层工作,就是TCP层,可以根据IP+端口进行负载均衡。此种Load Balance不理解应用协议(如HTTP/FTP/MySQL等等)。
-
七层负载:工作在OSI的最高层,应用层,可以基于Http协议和URL内容进行负载均衡。此时负载均衡能理解应用协议。
当前可以看到对于F5,Array等硬件负载均衡设备本身也是支持7层负载均衡的,同时在四层负载均衡的时候我们还可以设置是否进行会话保持等高级特性。要明白四层负载均衡本质是转发,而七层负载本质是内容交换和代理。
也就是说在不需要进行状态保留和基于内容的路由的时候,我们完全可以启用四层负载均衡来获取更好的性能。
在微服务架构前后端分离开发后。
后端微服务组件可以完全提供Rest API接口服务能力,那么本身就无状态。而对于前端微服务组件直接面对最终用户访问,需要保持Session状态。在这种情况下就可以进行两层负载均衡设计,即前端采用七层负载,而后端采用四层负载均衡。
前端缓存
前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端js上进行设置。缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
具体可以参考:
https://www.jianshu.com/p/256d0873c398
软件性能问题分析和诊断
对于业务系统性能诊断,如果从静态角度我们可以考虑从以下三个方面进行分类
-
鸿蒙官方战略合作共建——HarmonyOS技术社区
-
操作系统和存储层面
-
中间件层面(包括了数据库,应用服务器中间件)
-
软件层面(包括了数据库SQL和存储过程,逻辑层,前端展现层等)
那么一个业务系统应用功能出现问题了,我们当然也可以从动态层面来看实际一个应用请求从调用开始究竟经过了哪些代码和硬件基础设施,通过分段方法来定位和查询问题。
比如我们常见的就是一个查询功能如果出现问题了,首先就是找到这个查询功能对应的SQL语句在后台查询是否很慢,如果这个SQL本身就慢,那么就要优化优化SQL语句。如果SQL本身快但是查询慢,那就要看下是否是前端性能问题或者集群问题等。
软件代码的问题往往是最不能忽视的一个性能问题点
对于业务系统性能问题,我们经常想到的就是要扩展数据库的硬件性能,比如扩展CPU和内存,扩展集群,但是实际上可以看到很多应用的性能问题并不是硬件性能导致的,而是由于软件代码性能引起的。对于软件代码常见的性能问题我在以往的博客文章里面也谈过到,比较典型的包括了。
-
鸿蒙官方战略合作共建——HarmonyOS技术社区
-
循环中初始化大的结构对象,数据库连接等
-
资源不释放导致的内存泄露等
-
没有基于场景需求来适度通过缓存等方式提升性能
-
长周期事务处理耗费资源
-
处理某一个业务场景或问题的时候,没有选择最优的数据结构或算法
以上都是常见的一些软件代码性能问题点,而这些往往需要通过我们进行Code Review或代码评审的方式才能够发现出来。因此如果要做全面的性能优化,对于软件代码的性能问题排查是必须的。
其次就是可以通过APM性能监控工具来发现性能问题。
传统模式下,当出现CPU或内存满负荷的时候,如果要查找到具体是哪个应用,哪个进程或者具体哪个业务功能,哪个sql语句导致的往往并不是容易的事情。在实际的性能问题优化中往往也需要做大量的日志分析和问题定位,最终才可能找到问题点。
而通过APM可以很好的解决这个问题。
比如在我们最近的项目实施中,结合APM和服务链监控,我们可以快速的发现究竟是哪个服务调用出现了性能问题,或者快速的定位出哪个SQL语句有验证的性能问题。这个都可以帮助我们快速的进行性能问题分析和诊断。
资源上承载的是应用,应用本身又包括了数据库和应用中间件容器,同时也包括了前端;在应用之上则是对应到具体的业务功能。因此APM一个核心就是要将资源-》应用-》功能之间进行整合分析和衔接。通过APM来发现应用运行中的性能问题并解决。
感谢各位的阅读,以上就是“如何理解微服务架构下的高可用和高性能设计”的内容了,经过本文的学习后,相信大家对如何理解微服务架构下的高可用和高性能设计这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/41727.html