IT技术博客大学习 共学习 共进步

系统架构

共 731 篇文章

IT 2013-06-02 20:22:17 / 累计浏览 3,006

网站优化 更小的静态资源

这篇文章解决一个实际问题:如何通过压缩构建静态资源来加快网站加载。作者团队发现,更小的JS、CSS和图片文件意味着更少的网络传输时间,因此在构建阶段对它们进行优化至关重要。 核心方案是根据资源类型,选择不同工具进行深度压缩。对于JavaScript,他们对比了UglifyJS、Google Closure Compiler等工具,最终因稳定性考量,采用了Google Closure Compiler;对于CSS,则沿用了熟悉的YUI Compressor;而对于PNG和GIF图片,他们组合使用OptiPNG、AdvPNG和AdvDef三个工具,以实现最大化的压缩率。文章详细解释了每个选择背后的权衡与理由。 为了将这些工具集成到发布流程中,他们编写了一个简版的Bash构建脚本。这个脚本实现了自动化的压缩、复制和输出,避免了人工介入。从脚本执行结果的日志可以看到,多数文件的大小都得到了显著缩减,例如一个近50KB的JS文件被压缩到了约17KB,充分验证了方案的效果。 总的来说,这是一份非常扎实的前端工程化实践记录。它没有停留在工具介绍层面,而是完整展现了从工具选型到构建集成的决策与实现过程,其中对PNG图片“优先选用png8格式,并结合CSS Sprites”的建议,以及具体的脚本实现,对同类项目的优化工作都有直接的参考价值。

IT 2013-05-29 22:35:23 / 累计浏览 5,679

基于用户行为分析的搜索引擎自动性能评价

搜索引擎性能评价一直是个难题。传统Cranfield方法需要人工标注标准答案,面对数十亿网页的搜索结果池,这项工作变得耗时耗力,难以满足算法快速迭代的需求。 作者从信息检索评价的核心困境出发,梳理了各种自动评价方案的探索与局限。无论是基于搜索结果反馈的“伪相关”标注,还是利用外部目录资源,其可靠性都存疑。文章进而聚焦于用户点击行为这一天然存在的行为日志,分析其作为自动化评价依据的潜力。作者通过对比不同搜索引擎上“电影”这一查询的点击分布,发现信息类、事务类查询的答案多元且用户行为差异大,难以跨系统评价。 因此,文章将自动评价的可行范围明确限定于“导航类查询”——这类查询通常只有一个明确的目标网站,用户点击行为高度一致且可靠。作者详细阐述了如何从海量日志中筛选导航类查询,并利用群体点击行为自动标注唯一正确答案,从而实现基于“首现正确结果排序倒数”等指标的全自动性能评测。这为搜索引擎在保持评价科学性的同时,大幅提升迭代效率提供了一条切实路径。

IT 2013-05-29 22:19:50 / 累计浏览 7,591

Yupoo(又拍网)的系统架构

这篇讲的是国内最大图片服务商Yupoo又拍网的系统架构。文章没有空谈理论,而是直接列出其生产环境中使用到的具体技术栈,为读者提供了一个真实、可参考的大型互联网服务构建蓝图。 核心方案体现在对开源软件的组合运用上。操作系统层采用CentOS、Ubuntu等,服务器由Nginx、Apache、Squid共同处理请求;数据存储与缓存依赖MySQL、Memcached、Redis乃至Riak等多种方案;业务逻辑则由PHP、Python、Erlang等多语言实现。值得注意的是,其架构中还包含了Hadoop、Mogilefs用于分布式存储与计算,RabbitMQ处理消息队列,以及完善的监控(Nagios、Cacti)和任务管理(Redmine)体系。 这种“搭积木”式的架构,其效果在于通过成熟开源组件的高效组合,支撑起海量图片的上传、处理、存储与分发需求。对于技术团队而言,这份清单的价值在于它展示了一个经过实践验证的技术选型思路,而非单一工具的介绍。

IT 2013-05-21 22:56:28 / 累计浏览 3,828

SNS 背后的技术: 消息流的推拉模式选择

这篇文章深入对比了SNS消息分发的推模式与拉模式,从技术实现、资源消耗到用户体验进行了全面剖析。 作者从传统通信的推模式(如短信)在SNS场景下遇到的挑战切入,引出了拉模式作为更节省存储的替代方案。文章的核心在于辩证地分析了两种模式的优劣:拉模式在存储效率上能实现百倍级节省,并更有利于处理垃圾信息、好友关系变更、隐私权限修改等复杂的“删除与修改”操作;而推模式在保证信息即时性、减少登录后延迟方面有理论优势,但面临巨大的缓存维护成本和一致性挑战。 文章并未止于理论推演,而是结合了对Twitter、Facebook、新浪微博、QQ空间等主流平台的公开信息与现象观察,指出了各平台在推拉选择上的实际权衡。例如,新浪微博的拉模式有助于快速应对大规模删帖需求,而Facebook对离线用户采用拉模式则体现在登录时News Feed的短暂加载上。 最后,文章通过具体的数据模型计算,直观展示了在不同用户规模和行为模式下,推拉模式对缓存资源和网络开销产生的巨大影响。作者犀利指出,推模式下频繁的缓存修改操作会“让cache痛不欲生”,而一个设计良好的拉模式配合临时缓存,往往能在性能、成本与灵活性上取得更好的平衡。

IT 2013-05-20 23:20:22 / 累计浏览 3,892

Ceph的现状

这篇详细拆解了Ceph这个统一分布式存储系统,它告诉我们,Ceph卓越的性能、可靠性和扩展性,都建立在一个名为RADOS的底层对象存储系统之上。而RADOS的核心,正是那个巧妙的CRUSH伪随机数据分布算法。这个算法是解决大规模集群中数据如何高效、均匀分布到成百上千节点的关键,它能在节点增减时最小化数据迁移,平衡了效率与扩展性这一对矛盾。 在RADOS基础之上,Ceph通过不同组件提供了三种存储接口:LIBRADOS提供了直接的对象操作API,RADOS Gateway兼容了S3和Swift,让对象存储更易用;RBD则将存储抽象为块设备,支持精简配置、快照等企业级特性;Ceph File System则直接提供POSIX接口,无缝对接传统文件应用。这真正体现了“统一”的价值。 文章同样关注了Ceph的“人”的生态。项目源于Sage Weil的博士论文,至今已积累24万行代码,近期开发活动依然活跃。更值得关注的是其完善的社区设施,从邮件列表、项目管理到详尽的文档和路线图,构成了一套健康、开放的运作体系,这为Ceph的长期发展和质量提供了坚实保障。

IT 2013-05-14 22:24:35 / 累计浏览 5,796

解析Google集群资源管理系统Omega

这篇文章梳理了 Google 内部三代集群资源调度系统的演进,清晰地勾勒出从单体到分布式、从集中控制到共享状态的设计变迁。 文章首先回顾了早期“中央式调度器”的局限,即所有调度逻辑和资源管理都耦合在一个进程中,导致扩展性和新策略集成困难。为解决这一问题,以 Mesos 和 YARN 为代表的“双层调度器”被提出,它将调度策略下放到各个应用框架,中央调度器只负责资源推送。但这又带来了两个核心痛点:应用框架无法获知全局资源视图,从而无法做出更优决策;以及因为使用全局锁(悲观锁),并发调度效率受限。 为突破这两个瓶颈,Google 推出了 Omega 系统。它的核心创新是“共享状态调度器”:将全局资源状态作为共享数据,并采用数据库领域的“多版本并发控制”(乐观锁)来处理并发访问。这使得应用框架能主动查看全局状态并竞争资源,极大提升了调度灵活性和并发度。文章还具体对比了 Mesos 的“全有或全无”与 YARN 的“增量分配”两种资源授予模式在不同场景下的利弊。 最后,作者点明了一个对业界极具参考价值的观点:由于 Omega 与 Mesos/YARN 的主要差异集中在资源管理模块,因此可以通过改造开源系统的“Resource Master”部分来快速构建类似 Omega 的调度器,这对人力有限的公司来说是一条务实的技术路径。

IT 2013-05-13 14:03:01 / 累计浏览 3,430

对.net系统架构改造的一点经验和教训

这篇文章从作者在CSDN的亲身经历出发,探讨了从Windows .NET架构迁移到Linux平台的实战经验与教训。作者首先指出了一个普遍困境:许多依赖.NET的大型网站面临扩展瓶颈,但“去.NET化”的迁移风险极高,常因技术复杂性和内部团队政治斗争而失败。他以5173网站的失败案例为例,新旧团队并行、利益冲突导致迁移流产。 作者接手CSDN时,也面临.NET团队流失、系统脆弱的两难局面。他的核心方案是采取折衷策略:并非完全抛弃.NET,而是“去Windows化”。具体做法是保留.NET作为应用层,但将数据层、缓存、文件系统等全面迁移至Linux开源方案(如MySQL、Redis、Nginx),并用LVS实现负载均衡。这样既利用了.NET在应用层的开发效率,又通过Linux生态解决了扩展性和成本问题。 两年后的实践证明,这一策略成功实现了团队稳定、改造平顺、业务无影响且支持增强的多重目标。作者由此总结,架构改造远非单纯技术问题,必须妥善处理团队利益、业务平滑过渡与长期投入之间的关系。技术债务的背后,往往是技术被长期低估的管理文化问题。

IT 2013-05-08 13:49:14 / 累计浏览 6,332

如何设置一个永远无法删除的Cookie

这篇讲的是如何绕过用户删除,实现对浏览器状态的持久化跟踪。作者以“防删除”为切入点,系统梳理了八种客户端存储技术,其核心思路是“灾备机制”——即使主要存储被清除,仍有后备方案可以恢复。 文章从最常见的 HTTP Cookie 讲起,分析了其 4KB 大小限制、明文传输等痛点,指出其被诟病但又不可或缺的矛盾地位。作为主要后备方案的 Flash Cookie (LSO) 能存储 100KB 二进制数据,但依赖插件且易被安全软件清理。作者还详细对比了 Silverlight 独立存储(每应用1MB)、IE专有的 userData(仅限IE且IE9后弃用)等早期技术。 更巧妙的方案在于利用浏览器的“非存储”特性来持久化数据:比如将信息编码为 URL 路径存入浏览器历史记录(但性能极差),或将数据拆分为 RGB 值藏入一张长期缓存的 PNG 图片像素中(需 HTML5 Canvas),亦或是利用 `window.name` 属性跨域跨页面持久保存高达 2MB 的数据(需注意 iframe 安全处置)。 这些方案本质上是在不同技术时代,对“如何在用户控制下保持身份识别”这一难题的持续探索。它们各自在存储容量、安全性、兼容性和实现复杂度间权衡,也从侧面推动了 localStorage 等现代 Web Storage API 的诞生。

IT 2013-05-01 22:37:49 / 累计浏览 4,073

在线协同编辑的实现

这篇讲的是如何自己动手实现一个类似Google Doc的多人实时协同编辑器。文章从多人编辑同一文档必然面临的“冲突”问题切入,拆解出四个核心步骤:计算修改、服务器合并、同步状态和移动光标。 作者重点介绍了核心的冲突解决方案——**操作转换(Operational Transformation,OT)算法**。比如用户A插入文本、用户B删除文本时,服务器会动态调整后续操作的位置,确保所有人的视图最终一致。计算文本差异的部分,则借鉴了经典的动态规划算法,并推荐了Google开源的diff-match-patch库。 文章不仅梳理了理论路径,还给出了一个完整的实现范例:作者已将自己写的编辑器部署到SAE上,并开源了全部代码。对于想理解实时协作背后技术细节的开发者来说,这是一份从原理到实践的清晰指南。

IT 2013-05-01 17:44:21 / 累计浏览 5,758

whatsapp深度使用Erlang有感

当很多人还在争论Erlang是否过于小众、能否胜任大规模商业系统时,WhatsApp用事实给出了响亮的回答。这篇文章分享了作者对WhatsApp深度使用Erlang技术栈的观察与思考。 文章的核心是一个极具说服力的案例:一个以Erlang为主的后台架构,支撑了数亿用户。作者通过引用WhatsApp主要开发者Rick Reed的分享,揭示了一个有趣的成长故事——这位有深厚系统性能背景的工程师,在2011年加入WhatsApp时竟是一位Erlang新手,但短短两三年后,他已能将Erlang的虚拟机、集群、Mnesia数据库等特性运用到极致。 文中列举的数据令人印象深刻:仅用两台服务器承载百万级的长连接、Mnesia数据库支撑起巨大的数据集,以及背后惊人的消息吞吐量。作者指出,Rick Reed的工作并非创造了全新的魔法,而是将Erlang已知的特性进行了系统化整理并坚决落地于商业系统,这是从理论到实践的巨大飞跃。 文章最终的结论很直接:任何系统开发到最后,都是在操作系统和硬件能力的边界内解决同类问题,Erlang为解决高并发、高可用等特定规模问题提供了坚实的基础。作者鼓励读者停止对它的怀疑,因为它在正确的场景下确实能带来巨大的价值。

IT 2013-03-11 13:27:14 / 累计浏览 7,348

Web应用的缓存设计模式

这篇讲的是,作者如何通过一套“反直觉”的缓存设计,让一个日均300万访问的老产品重写后性能飙升。传统思路依赖动态页面静态化和数据库分库分表,但代码复杂度高,维护困难。作者的方案则彻底反转:完全放弃这些,转而深度应用ORM对象缓存。 核心在于改变对数据库性能瓶颈的认知——瓶颈往往在磁盘IO,而非SQL条数。因此,ORM缓存的设计哲学是:目标是减少数据库磁盘IO,而非减少SQL。这需要配合细颗粒度的表设计,故意拆分多表关联为多条主键查询(拥抱“n+1”问题),以便高效利用缓存。 文章通过一个实际案例(将千万级大表的项目迁移到单台MySQL)证明,这套方案能将数据库服务器的IO Wait降至5%以下,且代码复杂度并未显著增加。作者还具体演示了两种实现模式:利用表关联实现透明缓存,以及按列拆表实现大字段的细粒度缓存,后者本质上是SQL与NoSQL的混合架构。 对于追求高性能且希望保持代码可维护性的Web应用,尤其是内容频繁更新的场景,这种以缓存为中心的设计提供了一个极具说服力的替代路径。

IT 2013-03-11 13:24:36 / 累计浏览 5,097

多核与异步并行

这篇讲的是如何通过异步并行编程技术来充分利用多核CPU,解决现代应用程序面临的延迟、吞吐量和响应度问题。 作者从一个经典矛盾切入:当程序调用耗时的I/O操作(如写文件)时,同步等待会让宝贵的CPU资源闲置。而异步调用允许调用线程立即返回继续工作,让耗时的任务在后台完成,从而“掩盖”了I/O延迟。 文章重点分析了GUI线程的异步并行设计,这是一个对响应度要求极高的场景。作者对比了三种将耗时操作(如保存、打印)从GUI线程转移出去的方式:使用一个专用工作线程顺序处理、为每个请求启动新线程并行处理,以及使用线程池来平衡资源利用与并行度。每种方式都附有清晰的示意图和伪代码,直观展示了其工作原理与权衡。 最后,文章以苹果的Grand Central Dispatch (GCD) 为例,说明了这一理念在现代平台上的成熟应用——开发者只需将任务块投入队列,系统便能自动利用多核资源进行高效调度。整体而言,这是一篇从原理到实践、讲解异步并行如何化阻塞为并发的技术入门好文。

IT 2013-03-07 13:54:53 / 累计浏览 3,915

实践中的重构

这篇讲的是,许多程序员对“重构”这件事怀有误解,而作者的核心观点是:重构绝非特殊阶段的“大工程”,而是贯穿日常编码的微习惯。 作者从日常工作切入,指出重构应和写代码、测试一样,是每个开发者的常规动作。他特别澄清了“重构”与“重写”的混淆——调整模块设计可能需要沟通技术债,但执行时仍需遵循重构原则。一个关键的前提是:“没有测试的重构就是耍流氓”,必须先为代码补足测试保障。 那么如何安全地重构?文章给出的标准是:能够“随时随地停下来,且不破坏任何测试”。这依赖于“小步重构”的实践——将大刀阔斧的修改拆解为一系列可验证的微小步骤。作者坦言,这需要刻意练习,与内心急于“一路劈杀”的冲动对抗。 重构易知难行,其精髓正在于将这种小步快跑的纪律,内化为肌肉记忆般的编码习惯。

IT 2013-03-04 14:42:06 / 累计浏览 4,472

代码审查:ThoughtBot官方给出的代码审查指导原则

这篇讲的是如何让代码审查变得更高效、更友好。作者从 ThoughtBot 的官方指南出发,总结了在 GitHub 上进行代码审查时,审查者和被审查者双方都应遵循的一系列核心原则。 文章为审查者提供了具体的沟通心法:要记住编程主张常是个人观点,因此应多提问少命令、请求说明而非指责、避免代码归属之争,并且绝不能人身攻击。审查评论应清晰谦逊,避免使用“总是”“从不”等夸张修辞。如果讨论过于深入,可以转到线下进行。 而对于被审查的代码作者,文章建议要主动感谢建议、理解对事不对人、解释代码背后的思考,并在一个独立的 push 提交中集中处理反馈。关键流程包括:基于反馈更新代码、注明审查链接、等待所有审查者退出后再合并,并确保持续集成测试通过。 此外,文章还提倡建立统一的代码风格指南。当出现分歧时,应在指南仓库中发起讨论,而非在审查评论中争论。这些具体而微的实践,旨在将代码审查从一场潜在的技术辩论,转变为一次促进团队学习和代码质量提升的协作。

IT 2013-03-04 14:22:02 / 累计浏览 6,676

并发框架Disruptor译文

这篇讲的是Martin Fowler撰文推荐的高性能并发框架Disruptor,它正是LMAX交易系统能实现每秒600万订单的核心引擎。作者从“为什么会这么快”切入,剖析了传统锁机制的缺点,然后详细拆解了Disruptor的几大“魔法”:通过精心的缓存行填充避免伪共享、利用内存屏障保证无锁操作的正确性,并深入讲解了RingBuffer这个核心数据结构如何实现高效的读写。 文章不仅解释了原理,还提供了具体的使用指南,涵盖了从RingBuffer读取、写入到版本演进的完整路径。最后,通过LMAX架构和实际处理百万TPS的案例,展示了它在解决高并发、低延迟场景下的巨大价值。对于想理解无锁编程和设计高性能内存队列的开发者,这组系统性的译文提供了从理论到实践的清晰线索。

IT 2013-03-03 23:35:46 / 累计浏览 3,370

发布及其检查的自动化实践

这篇讲的是,一个服务实例超过35K的大型Dubbo注册中心,在频繁发布中遇到的棘手挑战及其实战解决方案。作者从一次因人工配置错误导致的严重事故出发,分享了如何通过持续的自动化改进,让发布过程从“危险重重”变得可靠。 文章聚焦四个具体痛点:数据库配置错乱、发布前后服务数据一致性核对、运行时状态报告集成,以及重启引发的动态数据风暴。针对每个问题,都给出了清晰的“解决方法”和提炼出的“原则”。例如,通过监控配置文件的值来防止环境错配;在发布脚本中集成数据Dump和Diff,实现Provider列表的自动核对;将关键状态汇总到一个URL,方便监控;并设计了“warm-up”机制来平滑重启过程。 作者强调,核心思路是将“人操作可能出错”的环节,逐步转化为可监控、可自动执行的脚本。最终目标是让发布回归极简,理想情况下仅需运行一条命令,而把异常情况下的排查留给必要的时候。整个过程体现了从发现问题、分析根因到工具化、自动化解决的工程化实践闭环。

IT 2013-01-22 14:00:40 / 累计浏览 6,758

web前端性能优化进阶路

这篇文章详细记录了阿里团队对一个高流量搜索页面长达两年多的前端性能优化实战历程。他们从页面完全加载需要16秒的“病危”状态起步,通过三个清晰阶段的持续努力,最终将时间稳定在4秒左右。 初探期,团队对照雅虎性能黄金法则,通过图片合并(CSS Sprite)、懒加载、资源异步加载等经典手段,实现了从16秒到7秒的突破。立规期,工作重心转向“防守”,通过建立代码规范和跨部门的“性能联盟”,将性能意识植入开发流程,确保了优化成果的稳定。进入创新期,团队选择彻底重写前端框架,开发出jEngine,通过“懒注册”模块机制、BigRender等架构级优化,实现了“fast by default”,使性能优化变得更低成本、更可持续。 文章不仅分享了具体的技术点,更强调了设立可量化目标、建立规范、争取跨职能支持等方法论的重要性。对于任何面临存量系统性能优化难题的技术同学来说,这套从救火到制度化,再到架构驱动的进阶思路,都提供了非常扎实的参考路径。

IT 2013-01-18 14:04:46 / 累计浏览 3,628

数据开发技术概述

这篇讲的是面向海量数据计算入门者的数据开发技术全景。作者冷川从淘宝数据平台及开发技术的演进过程出发,系统梳理了当前主流的数据开发技术栈。 文章的核心在于为我们呈现了一幅清晰的“目前主要的数据开发技术框架图”。它不仅仅罗列技术点,而是结合平台实际场景,讲解了这些技术如何被组织和应用。这对于想建立系统性认知、而非零散了解的同学非常有帮助。 在当前超海量数据的背景下,文章最后抛出了一个关键思路:数据同学不应被动使用技术,而要主动结合系统痛点去思考和推动技术应用。这从单纯的“技术介绍”提升到了“工程思维”的层面,给读者留下了具体的行动方向。

IT 2013-01-16 14:02:20 / 累计浏览 4,309

Pixel light 中的场景管理

这篇文章从Pixel Light引擎的源码出发,聚焦其场景管理模块的设计。作者指出,Pixel Light将场景元素(如Mesh、Light)设计为场景节点的继承类而非附加组件,这意味着所有实际渲染对象都位于叶节点,而容器节点仅用于组织和查询。 其场景管理的核心精巧之处在于“场景查询”机制。为实现高效的空间剔除与交互,引擎为每个容器引入独立的“场景层级”(如K-D树),并通过SQ系列查询类(如视锥剔除)遍历并激活可见节点。这与直觉相反——容器内的对象不强调严格的空间从属关系(例如摄像机与角色位于同一容器),而是通过“场景节点修改器”来动态建立关联,如使用SNMAnchor实现摄像机跟随或武器绑定。这种设计解耦了组织结构与行为逻辑,依赖简洁的事件机制驱动,避免了复杂的循环引用。 总体来看,Pixel Light的场景管理架构清晰地区分了静态空间组织与动态行为控制,其模块化与解耦的思路为理解3D引擎设计提供了有价值的参考。

IT 2013-01-10 22:40:13 / 累计浏览 3,997

微观架构及宏观架构

这篇文章从工程师的成长路径出发,探讨了软件架构设计中两个相辅相成但思维模式迥异的层面。作者指出,许多工程师从解决排序算法效率、提升代码可读性这类“微观架构”问题起步,这些成果直观且易于度量。然而,随着系统规模扩大,“宏观架构”——即关乎全局效率与成本的顶层策略设计——的价值便凸显出来。 文中用一个形象的对比阐释了这种思维转换:追求缓存命中率最大化是微观视角,而从全局出发,接受长尾数据的访问延迟,可能使整体成本下降一个数量级且性能影响甚微。作者进一步分析,从专注细节的微观思维转向宏观架构时,成果往往不如提升单个模块QPS那样立竿见影,更像是一种“虚”但至关重要的战略能力。 文章的核心观点在于,微观与宏观如同战术与战略,缺一不可。优秀的工程师团队需要合理的微观与宏观人员配比,架构师也需具备对代码细节的理解,才能做出正确的技术判断。文末列举的如C10k问题、SPDY协议、事件模型等断言,也邀请读者一起实践这种从微观细节到宏观影响的思考视角。