- 架构 秒杀系统优化思路
- 架构 细聊分布式 ID 生成方法
- 互联网架构,如何进行容量设计?
- 线程数究竟设多少合理
- 单点系统架构的可用性与性能优化
- 一分钟了解负载均衡的一切
- lvs 为何不能完全替代 DNS 轮询
- 如何实施异构服务器的负载均衡及过载保护?
- 究竟啥才是互联网架构 高并发
- 究竟啥才是互联网架构 高可用
- 100 亿数据 1 万属性数据架构设计
- TCP 接入层的负载均衡、高可用、扩展性架构
- 架构师 数据库与缓存
- 数据库软件架构设计些什么
- 细聊冗余表数据一致性
- 缓存架构设计细节二三事
- 缓存与数据库一致性优化
- 主从 DB 与 cache 一致性优化
- DB 主从一致性架构优化 4 种方法
- 多库多事务降低数据不一致概率
- mysql 并行复制降低主从同步延时的思路与启示
- 互联网公司为啥不使用 mysql 分区表?
- 即使删了全库,保证半小时恢复
- 啥,又要为表增加一列属性?
- 这才是真正的表扩展方案
- 一分钟掌握数据库垂直拆分
- 数据库秒级平滑扩容架构方案
- 100 亿数据平滑数据迁移,不影响服务
- 58 到家数据库 30 条军规解读
- 再议 58 到家数据库军规
- 业界难题 跨库分页 的四种方案
- 架构师 服务化与微服务
- 互联网架构为什么要做服务化?
- 微服务架构多 微 才合适?
- 为什么说要搞定微服务架构,先搞定 RPC 框架?
- 微服务架构之 RPC-client 序列化细节
- RPC-client 异步收发核心细节
- 架构师 消息系统
- http 如何像 tcp 一样实时的收消息?
- 微信为什么不丢消息?
- 微信为啥不丢 离线消息?
- 群消息这么复杂,怎么能做到不丢不重?
- QQ 状态同步究竟是推还是拉?
- 微信多点登录与 QQ 消息漫游架构随想
- 消息 时序 与 一致性 为何这么难?
- 58 到家通用实时消息平台架构细节(Qcon2016)
- 微信为啥这么省流量?
- 应用层/安全层/传输层如何进行协议选型?
- 架构师 消息总线架构
- 10w 定时任务,如何高效触发超时
- 1 分钟实现 延迟消息 功能
- 消息总线能否实现消息必达?
- 架构师 搜索架构
- 深入浅出搜索架构引擎、方案与细节(上)
- 如何迅猛的实现搜索需求
- 百度如何能实时检索到 15 分钟前新生成的网页?
- 架构师 架构实践
- 好架构是进化来的,不是设计来的(58 架构演进)
- 58 同城推荐系统架构设计与实现
- 从 0 开始做互联网推荐-以 58 转转为例
- 从 0 开始做垂直 O2O 个性化推荐-以 58 到家美甲为例
- 58 到家入驻微信钱包的技术优化
- 创业公司快速搭建立体化监控之路(WOT2016)
- 巧用 CAS 解决数据一致性问题
- 百度咋做长文本去重
- 如何快速实现高并发短文检索
- 如何实现超高并发的无锁缓存?
- id 串行化 到底是怎么实现的?
- 从 IDC 到云端架构迁移之路(GITC2016)
- 架构师 一分钟系列
- 一张 神图 看懂单机/集群/热备/磁盘阵列(RAID)
- 一分钟学 awk 够用(产品经理都懂了)
- 十分钟学 perl 够用(客服 MM 都懂了)
- 一分钟 sed 入门(一分钟系列)
- 一分钟了解两阶段提交 2PC(运营 MM 也懂了)
- 30 秒懂 SQL 中的 join(2 幅图+30 秒)
- 连接池原来这么简单(一分钟系列)
- 一分钟实现分布式锁
- 这才是真正的分布式锁
- 一分钟一幅图 TCP/IP 搞定
- 一分钟理解负载 LoadAverage
- 1 分钟了解 Leader-Follower 线程模型
- 架构师 通用素质
- 心态:晋升的为什么不是你
- 你的收入取决于你的努力程度
- 老公,我穿这衣服好看吗 终于破解了
- 一分钟经理人
- 架构师到底该不该写代码
- 如何做一场 B 格满满的技术大会演讲
好架构是进化来的,不是设计来的(58 架构演进)
好的架构化是进化而来的,不是设计出来的 ----58 沈剑
核心内容 :58 同城流量从小到大过程中,架构是如何演进的?遇到了哪些问题?以及如何解决这些问题?
核心观点 :好的架构不是设计出来的,而是进化而来的。
如何演进 :站点流量在不同阶段,会遇到不同的问题,找到对应阶段站点架构所面临的主要问题,在不断解决这些问题的过程中,整个系统的架构就不断的演进了。
如何演进,简言之:找到主要矛盾,并解决主要矛盾。
第一章:建站之初
建站之初,站点流量非常小,可能低于十万级别。这意味着,平均每秒钟也就几次访问。请求量比较低,数据量比较小,代码量也比较小,几个工程师,很短的时间搭起这样的系统,甚至没有考虑“架构”的问题。
和许多创业公司初期一样,最初 58 同城的站点架构特点是“ALL-IN-ONE”:
这是一个单机系统,所有的站点、数据库、文件都部署在一台服务器上。工程师每天的核心工作是 CURD,浏览器端传过来一些数据,解析 GET/POST/COOKIE 中传过来的数据,拼装成一些 CURD 的 sql 语句访问数据库,数据库返回数据,拼装成页面,返回浏览器。相信很多创业团队的工程师,初期做的也是类似的工作。
58 同城最初选择的是微软技术体系这条路:Windows、iis、SQL-Sever、C#
如果重新再来,我们可能会选择 LAMP 体系。
为什么选择 LAMP?
LAMP 无须编译,发布快速,功能强大,社区活跃,从前端+后端+数据库访问+业务逻辑处理全部可以搞定,并且开源免费,公司做大了也不会有人上门收钱(不少公司吃过亏)。现在大家如果再创业,强烈建议使用 LAMP。
初创阶段,工程师面临的 主要问题 :写 CURD 的 sql 语句很容易出错。
我们在这个阶段 引进 DAO 和 ORM ,让工程师们不再直接面对 CURD 的 sql 语句,而是面对他们比较擅长的面向对象开发,极大的提高了编码效率,降低了出错率。
第二章:流量增加,数据库成为瓶颈
随着流量越来越大,老板不只要求“有一个可以看见的站点”,他希望网站能够正常访问,当然速度快点就更好了。
而此时系统面临问题是:流量的高峰期容易宕机,大量的请求会压到数据库上,数据库成为新的瓶颈,人多并行访问时站点非常卡。这时,我们的机器数量也从一台变成了多台,我们的系统成了所谓的(伪)“ 分布式架构 ”:
我们使用了一些常见优化手段:
(1)动静分离,动态的页面通过 Web-Server 访问,静态的文件例如图片就放到单独的文件服务器上;
(2)读写分离,将落到数据库上的读写请求分派到不同的数据库服务器上;
互联网绝大部分的业务场景,都是读多写少。对 58 同城来说,绝大部分用户的需求是访问信息,搜索信息,只有少数的用户发贴。此时读取性能容易成为瓶颈,那么 如何扩展整个站点架构的读性能呢?常用的方法是主从同步,增加从库 。我们原来只有一个读数据库,现在有多个读数据库,就提高了读性能。
在这个阶段,系统的 主要矛盾为“站点耦合+读写延时” ,58 同城是如何解决这两个问题的呢?
第一个问题是站点耦合。对 58 同城而言,典型业务场景是:类别聚合的主页,发布信息的发布页,信息聚合的列表页,帖子内容的详细页,原来这些系统都耦合在一个站点中,出现问题的时候,整个系统都会受到影响。
第二个问题是读写延时。数据库做了主从同步和读写分离之后,读写库之间数据的同步有一个延时,数据库数据量越大,从库越多时,延时越明显。对应到业务,有用户发帖子,马上去搜索可能搜索不到(着急的用户会再次发布相同的帖子)。
要解决耦合的问题,最先想到的是针对核心业务做切分,工程师根据业务切分对系统也进行切分:我们将业务垂直拆分成了 首页、发布页、列表页和详情页 。
另外,我们在数据库层面也进行了垂直拆分,将单库数据量降下来,让读写延时得到缓解。
同时,还使用了这些技术来优化系统和提高研发效率:
(1)对动态资源和静态资源进行拆分。对静态资源我们使用了 CDN 服务,用户就近访问,静态资源的访问速度得到很明显的提升;
(2)除此之外,我们还使用了 MVC 模式,擅长前端的工程师去做展示层,擅长业务逻辑的工程师就做控制层,擅长数据的工程师就做数据层,专人专用,研发效率和质量又进一步提高。
第三章:全面转型开源技术体系
流量越来越大,当流量达到百万甚至千万时,站点面临一个很大的问题就是 性能和成本的折衷 。上文提到 58 同城最初的技术选型是 Windows,我们在这个阶段做了一次脱胎换骨的技术转型,全面转向开源技术:
(1)操作系统转型 Linux
(2)数据库转型 Mysql
(3)web 服务器转型 Tomcat
(4)开发语言转向了 Java
其实,很多互联网公司在流量从小到大的过程中都经历过类似的转型,例如京东和淘宝。
随着用户量的增加,对站点 可用性要求也越来越高 ,机器数也从最开始的几台上升到几百台。那么如何提供保证整个系统的可用性呢?首先,我们在业务层做了进一步的垂直拆分,同时引入了 Cache,如下图所示:
在架构上,我们抽象了一个相对独立的服务层,所有数据的访问都通过这个服务层统一来管理,上游业务线就像调用本地函数一样,通过 RPC 的框架来调用这个服务获取数据,服务层对上游屏蔽底层数据库与缓存的复杂性。
除此之外,为了保证站点的高可用,我们使用了反向代理。
什么是代理? 代理就是代表用户访问 xxoo 站点。
什么是反向代理? 反向代理代表的是 58 网站,用户不用关注访问是 58 同城的哪台服务器,由反向代理来代表 58 同城。58 同城通过反向代理,DNS 轮询, LVS 等技术,来保证接入层的高可用性。
另外,为了保证服务层和数据层的高可用,我们采用了冗余的方法,单点服务不可用,我们就冗余服务,单点数据不可用,我们就冗余数据。
这个阶段 58 同城进入了一个 业务高速爆发期 ,短期内衍生出非常多的业务站点和服务。新增站点、新增服务每次都会做一些重复的事情,例如线程模型,消息队列,参数解析等等,于是,58 同城就研发了自己的站点框架和服务框架,现在这两个框架也都已经开源:
(1)站点框架 Argo:https://github.com/58code/Argo
(2)服务框架 Gaea:https://github.com/58code/Gaea
这个阶段,为了进一步解耦系统,我们引入了配置中心、柔性服务和消息总线。
引入 配置中心 ,业务要访问任何一个服务,不需要在本地的配置文件中配置服务的 ip list,而只需要访问配置中心。这种方式的扩展性非常好,如果有机器要下线,配置中心会反向通知上游订阅方,而不需要更新本地配置文件。
柔性服务 是指当流量增加的时候,自动的扩展服务和站点。
消息总线 也是一种解耦上下游“调用”关系常见的技术手段。
机器越来越多,此时很多系统层面的问题,靠“人肉”已经很难搞定,于是自动化变得越来越重要:自动化回归、自动化测试、自动化运维、自动化监控等等等等。
最后补充一点,这个阶段我们引入了不少智能化产品,比如智能推荐,主动推荐一些相关的数据,以增加 58 同城的 PV;智能广告,通过一些智能的策略,让用户对广告的点击更多,增加同城的收入;智能搜索,在搜索的过程中加入一些智能的策略,提高用户的点击率,以增加 58 同城的 PV。这些智能化产品的背后都由技术驱动。
第四章、进一步的挑战
现在,58 同城的流量已经达到 10 亿的量级,架构上我们规划做一些什么样的事情呢,几个方向:
(1)业务服务化
(2)多架构模式
(3)平台化
(4)...
第五章:小结
最后做一个简单的总结,网站在不同的阶段遇到的问题不一样,而解决这些问题使用的技术也不一样:
(1) 流量小 的时候,我们要提高开发效率,可以在早期要引入 ORM,DAO;
(2) 流量变大 ,可以使用动静分离、读写分离、主从同步、垂直拆分、CDN、MVC 等方式不断提升网站的性能和研发效率;
(3)面对 更大的流量 时,通过垂直拆分、服务化、反向代理、开发框架(站点/服务)等等手段,可以不断提升高可用(研发效率);
(4)在面对 上亿级的流量 时,通过配置中心、柔性服务、消息总线、自动化(回归,测试,运维,监控)来迎接新的挑战;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论