我的架构经验系列文章 - 后端架构 - 架构层面

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云数据库 Tair(兼容Redis),内存型 2GB
简介: 回到索引 http://www.cnblogs.com/lovecindywang/archive/2012/12/23/2829828.html   架构层面:   日志集中 所谓日志集中就是把程序的所有日志和异常信息的记录都汇总到一起,在只有一台服务器的时候我们记录本地文件问题也不是最大,但是在负载均衡环境下再记录本地日志的话就出现问题了。

回到索引 http://www.cnblogs.com/lovecindywang/archive/2012/12/23/2829828.html

 

架构层面:

 

  • 日志集中

所谓日志集中就是把程序的所有日志和异常信息的记录都汇总到一起,在只有一台服务器的时候我们记录本地文件问题也不是最大,但是在负载均衡环境下再记录本地日志的话就出现问题了。在想查看网站日志的时候到哪台机器去查都不知道,难道有100台机器就100台机器逐一远程连上去看?因此,把这些数据汇总在一起保存对于大型网站系统来说是很必要的,这样我们就可以直接进行查看、搜索,也很明确可以知道是哪台机器的业务出了问题。至于这种日志数据是写到RDBMS还是NOSQL甚至是搜索引擎这就看需要了,总之避免写本地的文本文件,否则真的是灾难。当然写一个日志远远没有想的这么简单:

  1. 为了达到比较好的性能,日志是否先写本地内存队列然后定时刷到数据库中去?
  2. 各种日志混在一起也难以搜索,是否要添加一些搜索字段?比如分模块?
  3. 如果数据库不可用的话是不是先写本地日志以后再汇总过去?
  4. 日志是否易于辨明问题还是看日志怎么记录,如果日志中只写错误那么记录了也白记录,一定要写清楚这是哪个模块哪里出现了问题,有条件的话还可以写上一些参数信息和当前的状态。
  5. 对于未处理的异常信息不太可能手动去记录,一般而言很多框架或服务器都会提供一个接口点可以回调我们自己的代码,在这里我们就可以收集这些未处理异常然后统一记录,最后把用户带到友好的错误页面。不记录任何一个未处理异常都是可怕的事情,想象一下用户已经看到了色彩斑斓的页面,而开发还一无所知,这样的话这个问题始终会存在,即使用户投诉了反馈了我们也很难重现。

 

  • 配置集中

配置集中和日志集中的道理是一样的,就是统一管理。任何一个系统其实或多或少都会有一些不能在程序中写死的参数(比如至少的数据库连接字符串和外部服务地址),一般情况下会写到配置文件中,这样存在几个问题,第一就是在多服务器的负载集群情况下要修改配置需要逐一修改每一台服务器的配置,第二就是在修改配置还可以需要重启服务或网站才会生效,第三无法统一管理也无法知道是否所有网站都统一配置了相同参数。解决的办法还是一样的就是汇总保存在统一的地方比如保存在数据库中,然后每一个网站都从数据库中获取配置的值,在实现的时候简单有简单的做法,复杂有复杂的做法,比如要考虑以下问题:

  1. 参数的值是直接保存强类型的那还是保存字符串在使用的时候转?甚至说值是支持对象和数组的,而不是简单类型。
  2. 参数的值不可能每一次获取都从数据库取,怎么做缓存,缓存多长时间,值修改了怎么同步回来?
  3. 程序是否允许修改值?还是说程序只是读取,不允许修改,修改参数的值只能通过数据库或后台进行。
  4. 是否是需要根据不同的部署环境、用户的语言、服务器的IP来设置不同的值。

不管怎么样,至少一个最简单的配置服务,从数据库中读取参数值,哪怕读取后永远缓存只有重启服务才能生效,也会比直接从本地配置文件中读要好很多。

 

  • 缓存

缓存这个架构手段实在是太常用了,几乎所有的人都知道缓存这个设计和性能优化手段。对于一个网站系统来说又有太多的地方可以做缓存,真正能把缓存用好,在合理的地方用缓存,监控缓存的命中率,想办法提高缓存的命中率其实不是这么容易的,一般来说有这些地方可以做缓存,从上到下:

  1. 浏览器和CDN缓存:通过这两种整页的缓存可以尽量减少请求打到网站服务器的机会,也就提高了网站服务器的负载能力,当然一般来说静态的资源比较容易走这种缓存,动态的资源其实也可以走,只不过要能根据访问的条件做出合适的Key,对于和每一个用户都独立的页面可能要直接进行页面缓存比较难一点。
  2. 反向代理的缓存:反向代理作为服务器的代理可以进行整页或是片段页面的缓存,可以提高直接把请求达到网站服务器的机会提高性能。
  3. 数据的缓存:如果请求真正到了网站服务器,那么我们也不一定要所有的数据都从数据库中取,可以尝试把部分数据保存在分布式缓存中。只要Key合理,并且请求有规律那么可以保证比较高的命中率,从而减轻数据库的压力,也减轻网站服务器的压力。
  4. 大块数据的内存中缓存:对于有一些大块的数据是无法保存在分布式缓存中的,那么可以直接在网站启动的时候把这种不太会改变的大块数据全部加到内存中来,这样这快数据的访问效率和计算效率就很高了。

对于缓存的更多内容可以参考我之前做的一个分享:http://www.cnblogs.com/lovecindywang/archive/2010/07/19/1780589.html

 

  • 分布式缓存

所谓分布式缓存就是缓存的数据是分布在多个节点上的,好处是一来可以尽量利用服务器的资源,比如一台服务器可以有1GB内存空闲,找50台服务器就是50GB了,如果不用这50台服务器其实也就是这么多内存空着(一般来说网站服务器使用的内存是相对固定的,主要业务不怎么变化的话,而且诸如Memcached之类分布式缓存对CPU的使用是很低的,完全可以把Memcached寄居在大内存的Web服务器或是应用服务器上,实现神不知鬼不觉的分布式缓存);第二个好处就是可以减少单点故障带来的影响,一般来说分布式缓存都有类似于一致性哈希的算法,即使有单点故障的话也只是少部分缓存数据会不命中,损失不是太大。在使用分布式缓存的时候要牢记下面几点:

  1. 缓存就是缓存,数据是允许排出和丢失的,当成文件系统用的话就错了。
  2. 分布式缓存的数据是通过网络存取的,数据传输走网络和本机内存中效率不能比,而且数据需要序列化和反序列化要考虑到性能开销。
  3. 缓存的Key生成的策略是很关键的,Key生成的参数过多的话很可能命中率会几乎为0,这种缓存做了也白做,因此需要针对分布式缓存的命中率有监控。

 

  • 队列

队列也是实现高性能架构的一个必不可少的利器,通过把执行时间比较长的任务在队列中进行排队,通过限制队列的最大容纳项目数,实现一个抗高压的能力,并且队列后端的点也能有一个比较平稳的压力。队列说到底也只是一个容器,如果前端的压力永远比后端处理能力大的话,队列总是要爆的,因此队列也不是万能。往往对于网站系统即使后端的业务有队列,前端的页面如果扛不住高压力,甚至是验证码之类的都刷不出来的话也是没用的,架构上就是这样系统中任何一个点都会拖累整站的架构,架构优化针对最薄弱的地方而不是最强的地方。形式上来说队列有两种:

  1. 生产者和消费者:生产者生产出来的数据只能被一个消费者消费,也就是任务只能执行一次的。往往这种形式的数据是需要持久化的。
  2. 发布和订阅:任何一个事件都允许有多个发布者和多个订阅者,订阅者订阅自己感兴趣的东西,只要发布者发布了订阅者感兴趣的内容就会传播到所有的订阅者。一般来说这种形式的数据可以是允许丢失的不需要持久化的。

 

  • 池技术

所谓的数据库连接池,线程池都是池技术的一个应用。池技术说到底就是把创建开销比较大的对象缓存在池中避免重复创建和销毁,对象用的时候从池拿出来用,用好了重置后还到池里面别人还可以接着用。比如说数据库连接池就是避免了频繁创建代价高的TCP连接,线程池就是避免了频繁创建代价高的线程。虽然说原理上是这样,但池其实也有一些算法需要考虑的:

  1. 创建的富裕的对象的回收策略怎么做?
  2. 对象损坏怎么处理?

一般来说可以参考网上的池实现方式来实现一个通用的池,这样各种对象都可以进行管理了。

 

  • 分布式文件系统

分布式文件系统并不是所有网站都必须的,一般小网站会把用户上传的图片直接保存在Web服务器本地,这么做是可以的,但量大了之后会有问题,首先一台服务器保存不下怎么办,怎么知道哪个图片在哪个服务器上?其次读的请求怎么进行分离,怎么把图片同步到其它服务器上去。分布式文件系统就是来解决这个问题的,通过把一组服务器当做一个文件系统使得我们的文件资源可以分散保存在多个服务器上并且确保有一定的数据备份。在网站规模不是很大的时候其实可以保存在单台服务器上,然后使用文件同步工具同步到另一台服务器,之前再架反向代理解决,数据量再大一定要分布式的话就要上分布式文件系统了。从原理上来说分布式文件系统其实不是很复杂的,但选型的时候也要进行稳定性和性能的考量。有的人是把数据库保存在数据库中的,虽然这样可以实现单点虽然这样可以实现备份,但这显然不是很合理的,会极大增加数据库的压力。

 

  • 分布式搜索引擎

如果有站内搜索需求的话就要上搜索引擎了,现在开源的搜索引擎非常多,不过很多都是Lucene的封装,在选型的时候要根据自己的需求进行选型。所谓分布式也就是如果单点的索引和查询不能满足性能容量需求的话就需要分布到多点了。从原理上来说搜索引擎主要还是一个分词和倒排索引,但是搜索引擎在内容的排序等细节上点还是有很多算法的,除非必要不推荐自己去实现搜索引擎,可以直接针对开源组件进行封装和改良。搜索引擎做的好其实远远不止全文搜索这么简单,甚至可以根据用户搜索的内容给予搜索的建议,可以根据用户搜索的内容进行索引的自完善,还可以根据用户的搜索结果进行大量的用户行为分析,为网站的产品进行改良,如果站点具有自己的搜索模块的话其实有很多事情可以做的。

 

  • NOSQL

NOSQL就是非关系型的数据库,NOSQL不是用来取代关系型数据库的,之所以NOSQL这么火是因为其性能。从本质上来说,程序就是一组代码,对于相同的硬件配置来说,程序性能的高低也就取决于实现相同的操作要有多少代码在CPU中执行一遍,要有多少IO操作要在磁盘上过一遍,往往通用性的东西就会有比较多的计算和IO,往往定制化的东西性能就会比较高。我们说RDBMS性能不高,但是我们也应该看到RDBMS要确保数据的完整性,持久性,要实现通用的功能,要把它的性能和IO达到内存中然后定期刷磁盘的组件来比就不合理了,因此我们要根据业务在合理的地方使用合理的NOSQL,对于资金相关的业务需要事务的业务不太适合NOSQL,对于允许延迟允许数据丢失需要大访问量的业务比较适合NOSQL。任何一种NOSQL往往都是某个大型公司针对自己的需要定制出来的产品,只有这样定制化的东西才可能实现高性能,因此市面上才会有这么多NOSQL,那么我们在选择的时候也要看这个NOSQL针对的应用场景是否就是符合我们业务需要的。另外,NOSQL逼近是一个新新事物,其用户群不可能有MYSQL或ORACLE这么多,因此我们也不能期望其稳定性能达到非常高的标准,而且NOSQL由于其定制化的特点,在使用的时候不一定都可以通过标准SQL来使用对于学习成本也是我们需要考虑的因素。不管怎么样在该需要用的时候还是要用,有的应用单靠RDBMS是没有可能实现这么高性能的,不用NOSQL就是死路一条,用了即使它不稳定还有可能活。

 

  • NOSQL之Mongodb

Mongodb是一款性能超高的文档型数据库,之所以它这么火不仅仅是因为性能高,而且它功能也很全,相比其它NOSQL它几乎可以实现90%以上的SQL操作,并且也有丰富的高可用性的配置方式。总结下来Mongodb是一款性能几倍于传统RDBMS的最接近于RDBMS功能的NOSQL。对于对性能要求很高,特别是写数据并发要求很高的应用来说使用Mongodb是比较适合的,比如存业务日志或系统日志。值得一提的是:

  1. Mongodb也不是万能的,对于超大级别的数据量如果不进行数据分区,那么Mongodb也救不了你,并且不要期望Mongodb的自动Sharding功能能有多好,自动的毕竟没有手动这么准确,如果你能想到怎么进行数据分片的话还是推荐手动进行。
  2. Mongodb的性能是很好的,但这也是有限度的。只要拥有比较大的内存,那么热数据可以在内存中保存,读取性能不会太差,但是数据量达到一定的限度之后,如果你的索引数据都在内存中放不下的话,那么其性能会很差的,其实我们也很容易想到为什么,举个例子,我们在查字典的时候需要翻索引的,至于字典真正的内容在哪里其实问题不大的,如果一本百科全书即使由100本书构成,只要索引在手里查到了哪一本再去取问题不大,如果这个索引也是由100本书构成,查索引就不能一次性在手里查完还需要翻不同书的话这个性能就会非常差。

 

  • NOSQL之Redis

Redis于其说是一款NOSQL还不如说是一款缓存组件,在大多数时候把NOSQL当成一个服务端可以做计算的,存储复杂类型的,又具有一些诸如队列、管道等小功能的升级版本的Memcached是不错的。我个人使用Redis的心得是:

  1. Redis不像Memcached,它可以保存多种形式的数据,而不仅仅是一个字符串,这是很有亮点的,意味着我们直接可以在服务端针对大量数据进行一个计算,然后服务端直接返回计算结果,而不是要从缓存中把所有数据都取出来在客户端进行一番计算然后再保存回缓存中的(这里的客户端是指使用NOSQL的客户端,不是浏览器),也就是说要用好Redis是要写一些定制性的代码的,把我们真正的业务逻辑嵌入到Redis中去,如果只是存KeyValue的话性能不一定比Memcached高多少的。
  2. 一般情况下不建议过多依赖Redis的磁盘VM的,有16GB内存保存32GB的数据是可以的,有16GB的内存用Redis保存1TB的数据那就是用错Redis了。NOSQL的产品其实原理上来说都不是特别复杂的,使用NOSQL之前最好熟悉一下它的原理,这样我们更容易用好NOSQL产品。总之我的观点还是这样,由于内存和磁盘性能的巨大差异,如果说能在内存中做大部分事情的话,这个性能就会比较好,如果要来回在内存和磁盘上翻腾的话这个性能也好不到哪里去。

 

  • NOSQL之HBase

HBase、Hadoop适合的是超大数据量的存储和计算,它其实是真正的一个分布式的概念,数据不再能在一个单点上保存了,需要分散到很多机器上,然后计算结果也是分别计算后汇总在一起。对于这套东西我的体会是不要轻易引入:

  1. 除非是亿级以上的数据量并且数据的格式比较简单,否则要考虑是否适合引入,HBase的学习曲线不低的,而且最好是在社区熟悉过一段时间的,否则连用哪套版本的Hadoop什么的都搞不清楚,版本没用对要么有很多难以解决的BUG要么就是连基本的连通性都搞不起来。
  2. 要想有很好的性能,至少有20台以上的服务器再来搞HBase,一两台机器就算了,还没到分布式的这个需求。想想也知道所谓通过并行来提高效率首先是你有这么多资源可以把数据并行分散出去,然后同时进行计算汇总才能节约时间,如果根本数据都没分出去怎么可能节省时间。

 

 

作者: lovecindywang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
21天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
8天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
37 3
|
27天前
|
弹性计算 持续交付 API
构建高效后端服务:微服务架构的深度解析与实践
在当今快速发展的软件行业中,构建高效、可扩展且易于维护的后端服务是每个技术团队的追求。本文将深入探讨微服务架构的核心概念、设计原则及其在实际项目中的应用,通过具体案例分析,展示如何利用微服务架构解决传统单体应用面临的挑战,提升系统的灵活性和响应速度。我们将从微服务的拆分策略、通信机制、服务发现、配置管理、以及持续集成/持续部署(CI/CD)等方面进行全面剖析,旨在为读者提供一套实用的微服务实施指南。
|
22天前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
21天前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
33 1
|
22天前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
41 1
|
23天前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。
|
23天前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####
|
27天前
|
消息中间件 监控 API
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,分析了其优势、实施过程中的关键考虑因素及面临的挑战。不同于传统的单体应用,微服务通过拆分功能模块为独立服务,提升了系统的灵活性和可维护性。我们将从微服务的基本概念入手,逐步剖析其在真实场景下的应用案例,并讨论如何有效应对服务间通信、数据一致性等复杂问题,旨在为开发者提供一套实用的微服务落地指南。 ####
22 0
|
1月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
43 3