今天我们就来说说微服务架构下的高可用设计。对于高可用,其实应该包括高可靠性、高性能和高扩展性。因此,在谈到微服务架构的高可用时,我们首先需要梳理一下三者的关系。高可用性的三个维度及其相互关系业务系统的高可用性实际上包括三个方面:高可靠性、高性能和高扩展性。而且,这三个方面之间还相互依存、相互影响。对于三者的关系,我们可以用下图来描述。上图展示了高可靠性、高性能和高扩展性之间的关系。对于高可靠性,传统的HA架构和冗余设计可以满足高可靠性要求,但并不意味着系统具有高性能和扩展能力。反之,当系统具有很高的可扩展性时,我们在设计可扩展性时一般会同时考虑冗余和高可靠性,比如我们常说的集群技术。对于高性能和高扩展性,高扩展性是高性能的必要条件,但不是充分条件。一个业务系统的高性能并不是简单的具备扩展能力,而是需要业务系统本身的软件架构设计,代码编写的方方面面都满足高性能的设计要求。对于高可靠性和高性能,两者呈现出一种相互制约的关系,即在高性能支持的状态下,往往对系统的高可靠性提出严峻的挑战。也正是因为这个原因,我们才会看到类似限流熔断、SLA服务降级等各种措施来控制异常情况下的大并发访问和调用。刚才讲微服务架构的时候提到了数据库的高可用。微服务架构下,传统单体应用需要拆分。这种拆分不仅是应用层组件的拆分,也是数据库本身的拆分。分裂。如果将一个传统的单体应用规划为10个微服务,则可能会垂直拆分为10个独立的数据库。这实际上减少了每个数据库本身所面临的性能负载,同时提高了数据库的整体处理能力。同时,虽然拆分后引入了各种跨库查询和分布式事务,但是很多跨库操作和复制数据处理计算并不是在数据库中完成的。数据库提供更简单的类CRUD操作界面,这本身就是提高数据库性能的关键。如果你使用Mysql数据库。为满足高可靠性,可以采用Dual-Master双主架构,即两个Master节点双活,但只有一个节点提供数据库接口能力,另一个节点实时同步数据库日志作为备用节点。当主节点出现故障时,备份节点将自动充当主节点。简单双主架构的两个节点之间安装agent,复制Binlog日志。上层通过类似Haproxy+Keepalive的东西实现VIP浮动IP提供和心跳监控。可见双主架构更多的是为了高可靠的服务。如果要满足高性能,往往会使用读写分离集群。即一个主节点进行读写操作,多个从节点进行读操作。从节点仍然通过Binlog日志同步主节点的信息。当有数据访问请求进来时,前端Proxy可以自动分析是CUD请求还是R读请求,从而对请求进行路由转发。当我们添加订单时,当添加成功后,我们需要快速刷新当前订单列表界面。第二次刷新本身就是读操作,但是和前面的写紧紧绑定在一起,其实是不合适的。从Slave节点读取数据。这时候可以明确指定调用Sql时是否仍然从master节点获取数据。当然,大多数时候,可能需要两者结合才能提供足够的高可靠性和高性能。所以在搭建Mysql集群时,既需要双主设置,也需要多从节点设置。在上图所示的逻辑部署架构下,基本上可以同时满足高可靠性和高性能的要求。但是从上面的架构部署可以看出,备节点的主从节点处于双机热备无法实际提供容量的状态。有没有可能把所有的Slave都挂在一个Master上?如果这样设计,当主Master失效时,需要多个Slave节点自动漂移。一方面整体实现比较复杂,另一方面可靠性不如上述架构。思考数据库性能扩展首先看之前架构本身存在的一些潜在问题:首先是CUD操作仍然由单节点提供。对于读操作占大部分时间的场景,通过双主+读写分离集群基本可以实现很好的性能扩展。但是如果CUD操作频繁,还是会出现性能问题。其次,数据库性能问题一般分为两个层次。一是大并发请求下的性能,可以通过集群负载均衡来解决。另一个是单个请求访问大型数据库表的模糊查询性能。固定的。也就是说,上述设计在大并发的CUD操作、关联查询或大数据表的模糊查询操作中,仍然可能存在明显的性能问题。如何解决这个问题呢?简单的说就是写成通过消息中间件将同步转为异步,进行前端调峰。对于查询,进行内容缓存或创建二级索引,提高查询效率。对于查询本身,还包括部分结构化数据的查询和处理,类似于使用Redis库或者Memcached做缓存;对于消息消息、日志等非结构化数据,使用Solr或ElasticSearch构建二级索引,实现全文检索能力。当面对大量的数据写入操作时,单个Master节点的性能往往难以支撑。这时候就需要使用RabbitMQ、RocketMQ、Kafka等消息中间件来处理异步高峰销售。这个异步其实涉及到两个层次的异步。一是发送短信、记录日志、启动进程等接口服务是异步的。第二种是异步的,对于耗时较长的写操作,先反馈收到的用户请求,处理后通知用户获取结果。对于查询操作,上面提到的并发查询可以进行集群负载。但是对于大数据量的表,比如上亿条记录的大表的模糊查询,就需要对这个块进行二级索引。这么大的数据表即使没有并发查询,如果没有二级索引,查询效率和响应速度还是很慢的。为半结构化信息启用分布式存储对于日志、接口服务调用日志等半结构化信息,其数据量本身就很大。如果全部存储在结构化数据库中,存储空间需求大,难以扩展。尤其是在之前的Mysql集群方案本身还是使用本地磁盘进行存储的情况下。因此,需要清除历史日志,同时将历史日志迁移到分布式存储库,如Hdfs或Hbase库,再基于分布式存储构建二级缓存能力。构建横向扩展的DaaS数据层。前面说到,微服务拆分后进行了纵向扩展。例如,一个资产管理系统可以分为资产新增、资产配置、资产折旧、资产盘点等10个微服务模块。.但是拆分之后,还是发现资产数据量巨大。比如在集团大集中这样的大型项目中,可以看到一个省的资产数据表接近上亿条记录。此时,将所有省级数据集中在一个数据库中进行管理是不现实的。因此,需要按省或组织域进一步横向拆分。水平拆分后,在上层构建DaaS层,对外提供统一的访问能力。应用集群扩容其实比数据库层的应用集群扩容简单。应用中间件层可以方便地与集群管理节点或独立的负载均衡硬件或软件相结合,扩展集群能力。对于应用集群的扩展,是提高整体性能的关键途径。在集群扩容过程中,还有一些问题需要进一步探讨。集群是完全无状态的。如果集群是完全无状态的,集群可以结合负载均衡设备或软件来实现负载均衡的可扩展性。比如硬件上常用的F5或者radware,软件上比如HAProxy、Nginx等,session信息如何处理?session本身是有状态的,所以session信息可以保存在数据库或者Redis缓存库中。集群节点在启动时经常需要读取一些全局变量或者配置文件信息。如果这些信息只是存在于本地磁盘上,通常很难集中管理。所以目前主流的思路是让全局的配置中心统一管理配置。如果在应用功能的实现中有文件上传和存储,那么这些文件在磁盘本地存储时也是有状态的。因此,这些文件本身也需要通过文件服务能力或者分布式对象存储服务能力来实现。在微服务架构下,微服务之间存在接口交互和协作。接口调用的具体地址信息也需要通过服务注册中心获取。获取后可以缓存在本地,但是变化后要有实时更新的机制。四层负载和七层负载首先我们看一下最简单的四层负载和七层负载的解释:四层负载:工作在OSI的第四层,也就是TCP层,可以根据IP+端口进行负载均衡。这种LoadBalance不理解应用协议(如HTTP/FTP/MySQL等)。七层负载:工作在OSI的最高层,即应用层,可以基于Http协议和URL内容进行负载均衡。此时,负载均衡器可以理解应用程序协议。目前可以看到F5、Array等硬件负载均衡设备也支持七层负载均衡。同时我们还可以设置四层负载均衡时是否保持会话等高级特性。需要了解的是,第4层负载均衡的本质是转发,而第7层负载均衡的本质是内容交换和代理。也就是说,当不需要状态保存和基于内容的路由时,我们可以启用四层负载均衡以获得更好的性能。微服务架构的前后端分离开发之后。后端微服务组件可以完全提供RestAPI接口服务能力,因此是无状态的。前端微服务组件直接面向终端用户访问,需要维护Session状态。这种情况下,可以进行二层负载均衡设计,即前端采用七层负载,后端采用四层负载均衡。前端缓存前端缓存主要分为HTTP缓存和浏览器缓存。其中,HTTP缓存是HTTP请求传输过程中使用的缓存,主要设置在服务端代码上;而浏览器缓存主要是前端开发在前端js上设置的。缓存可以说是性能优化中一种简单高效的优化方法。优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复使用,还可以降低带宽和网络负载。详见:https://www.jianshu.com/p/256d0873c398软件性能问题分析与诊断对于业务系统性能诊断,从静态的角度,我们可以从以下三个方面来对操作系统进行分类和存储层中间件层(包括数据库、应用服务器中间件)软件层(包括数据库SQL和存储过程、逻辑层、前端表现层等)那么一个业务系统应用功能有问题,当然我们也可以看看从动态层面的实际情况来看,一个应用请求从调用开始,经过了哪些代码和硬件基础设施,通过切分的方式定位和查询问题。比如我们经常看到的是,如果某个查询函数出现问题,首先要找的是这个查询函数对应的SQL语句在后台查询是不是很慢。如果SQL本身很慢,那么就需要对SQL语句进行优化。如果SQL本身很快但是查询很慢,那要看是前端性能问题还是集群问题。软件代码的问题往往是最不容忽视的性能问题。对于业务系统性能问题,我们往往想到的是扩展数据库的硬件性能,比如扩展CPU和内存,扩展集群。但实际上,我们可以看到很多应用。性能问题不是由硬件性能引起的,而是由软件代码性能引起的。我在之前的博文中也谈到了软件代码常见的性能问题,典型的都包含在内。大结构对象在循环中初始化,数据库连接等资源未释放导致的内存泄漏等未根据场景需求通过缓存等方式进行适当改善。长时间的事务处理会消耗资源。在处理某个业务场景或问题时,别无选择优秀的数据结构或算法以上是一些常见的软件代码性能问题,而这些往往需要通过我们的CodeReview或codereview来发现。因此,要想做全面的性能优化,就必须排查软件代码的性能问题。二是可以通过APM性能监控工具发现性能问题。在传统模式下,当CPU或内存满载时,往往不容易找出是哪个应用程序、哪个进程或具体的业务功能、哪条SQL语句导致了问题。在实际的性能问题优化中,往往需要做大量的日志分析和问题定位,才能最终找到问题点。而APM可以很好的解决这个问题。比如我们在最近的项目实施中,结合APM和服务链监控,可以快速找出是哪个服务调用出现了性能问题,或者是快速定位到是哪个SQL语句出现了校验性能问题。这可以帮助我们快速分析和诊断性能问题。资源承载应用,应用本身包括数据库、应用中间件容器、前端;应用程序对应特定的业务功能。因此,APM的一个核心就是整合、分析和连接资源-“应用-”功能。使用APM发现并解决应用程序运行过程中的性能问题。
