大型分布式 Web 系统的架构演进

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Java Web","attrs":{}}],"attrs":{}},{"type":"text","text":" 为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"该系统具备的功能:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用户模块:用户注册和管理","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"商品模块:商品展示和管理","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"交易模块:创建交易和管理","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"正文","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段一、单机构建网站","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"网站的初期,我们经常会在单机上跑我们所有的程序和软件。此时我们使用一个容器,如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Tomcat","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Jetty","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Jboss","attrs":{}}],"attrs":{}},{"type":"text","text":",然后直接使用JSP/Servlet技术,或者使用一些开源的框架如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Maven + Spring + Struts + Hibernate","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Maven + Spring + Spring MVC + Mybatis","attrs":{}}],"attrs":{}},{"type":"text","text":"。最后再选择一个数据库管理系统来存储数据,如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MySQL","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SqlServer","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Oracle","attrs":{}}],"attrs":{}},{"type":"text","text":",然后通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"JDBC","attrs":{}}],"attrs":{}},{"type":"text","text":"进行数据库的连接和操作。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"把以上的所有软件包括数据库、应用程序都装载同一台机器上,应用跑起来了,也算是一个小系统了。此时系统结果如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cb/cbfaece1de17183f2384e6920ce3b7fd.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段二、应用服务器与数据库分离","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着网站的上线,访问量逐步上升,服务器的负载慢慢提高,在服务器还没有超载的时候,我们应该就要做好准备,提升网站的负载能力。假如我们","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"代码层面","attrs":{}},{"type":"text","text":" 已难以优化,在不提高单台机器的性能的情况下,采用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"增加机器","attrs":{}},{"type":"text","text":" 是一个不错的方式,不仅可以有效地提高系统的负载能力,而且性价比高。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"增加的机器用来做什么呢?此时我们可以把","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"数据库服务器","attrs":{}},{"type":"text","text":" 和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Web服务器","attrs":{}},{"type":"text","text":" 拆分开来,这样不仅提高了单台机器的负载能力,也提高了容灾能力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"应用服务器与数据库分开后的架构如下图所示:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9a/9a5b09c164f268e8c5e1a7e85de7a2a8.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段三、应用服务器集群","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着访问量继续增加,单台应用服务器已经无法满足需求了。在假设数据库服务器没有压力的情况下,我们可以把应用服务器从","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"一台","attrs":{}},{"type":"text","text":" 变成了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"两台甚至多台","attrs":{}},{"type":"text","text":" ,把用户的请求分散到不同的服务器中,从而提高负载能力。而","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"多台应用服务器","attrs":{}},{"type":"text","text":" 之间没有直接的交互,他们都是依赖数据库各自对外提供服务。著名的做","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"故障切换","attrs":{}},{"type":"text","text":" 的软件有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"KeepAlived","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"KeepAlived","attrs":{}}],"attrs":{}},{"type":"text","text":"是一个类似于Layer3、4、7交换机制的软件,他不是某个具体软件故障切换的专属品,而是可以适用于各种软件的一款产品。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"KeepAlived","attrs":{}}],"attrs":{}},{"type":"text","text":"配合上","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ipvsadm","attrs":{}}],"attrs":{}},{"type":"text","text":"又可以做","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"负载均衡","attrs":{}},{"type":"text","text":" ,可谓是神器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们以增加了一台应用服务器为例,增加后的系统结构图如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f3/f3a0b2e219e9c50fd9f0aa7614ad456c.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系统演变到这里,将会出现下面","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"四个问题","attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"用户的请求由谁来转发到到具体的应用服务器?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"有那些转发的算法和策略可以使用?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"应用服务器如何返回用户的请求?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"用户如果每次访问到的服务器不一样,那么如何维护session的一致性?","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"针对以上问题,常用的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"解决方案","attrs":{}},{"type":"text","text":" 如下:","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"1、负载均衡的问题","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般以下有5种解决方案:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、HTTP重定向","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"HTTP","attrs":{}}],"attrs":{}},{"type":"text","text":"重定向就是应用层的请求转发。用户的请求其实已经到了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"HTTP","attrs":{}}],"attrs":{}},{"type":"text","text":"重定向负载均衡服务器,服务器根据算法要求用户重定向,用户收到重定向请求后,再次请求真正的集群","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:简单易用;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:性能较差。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、DNS域名解析负载均衡","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"DNS","attrs":{}}],"attrs":{}},{"type":"text","text":"域名解析负载均衡就是在用户请求DNS服务器,获取域名对应的IP地址时,DNS服务器直接给出负载均衡后的服务器IP。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:交给","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DNS","attrs":{}}],"attrs":{}},{"type":"text","text":",不用我们去维护负载均衡服务器;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:当一个应用服务器挂了,不能及时通知","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DNS","attrs":{}}],"attrs":{}},{"type":"text","text":",而且","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DNS","attrs":{}}],"attrs":{}},{"type":"text","text":"负载均衡的控制权在域名服务商那里,网站无法做更多的改善和更强大的管理。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、反向代理服务器","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在用户的请求到达反向代理服务器时(已经到达网站机房),由反向代理服务器根据算法转发到具体的服务器。常用的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Apache","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Nginx","attrs":{}}],"attrs":{}},{"type":"text","text":"都可以充当反向代理服务器。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:部署简单;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:代理服务器可能成为性能的瓶颈,特别是一次上传大文件。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、IP层负载均衡","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在请求到达负载均衡器后,负载均衡器通过修改请求的目的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"地址,从而实现请求的转发,做到负载均衡。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:性能更好;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:负载均衡器的宽带成为瓶颈。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5、数据链路层负载均衡","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在请求到达负载均衡器后,负载均衡器通过修改请求的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MAC","attrs":{}}],"attrs":{}},{"type":"text","text":"地址,从而做到负载均衡,与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"负载均衡不一样的是,当请求访问完服务器之后,直接返回客户。而无需再经过负载均衡器。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"2、集群调度转发算法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、rr轮询调度算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顾名思义,轮询分发请求。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:实现简单","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:不考虑每台服务器的处理能力","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、wrr加权调度算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们给每个服务器设置权值","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Weight","attrs":{}}],"attrs":{}},{"type":"text","text":",负载均衡调度器根据权值调度服务器,服务器被调用的次数跟权值成正比。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:考虑了服务器处理能力的不同","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、sh原地址散列算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"提取用户","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":",根据散列函数得出一个","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"key","attrs":{}}],"attrs":{}},{"type":"text","text":",再根据静态映射表,查处对应的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"value","attrs":{}}],"attrs":{}},{"type":"text","text":",即目标服务器","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"。过目标机器超负荷,则返回空。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:实现同一个用户访问同一个服务器。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、dh目标地址散列算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原理同上,只是现在提取的是目标地址的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"来做哈希。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:实现同一个用户访问同一个服务器。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5、lc最少连接算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优先把请求转发给连接数少的服务器。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:使得集群中各个服务器的负载更加均匀。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"6、wlc加权最少连接算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"lc","attrs":{}}],"attrs":{}},{"type":"text","text":"的基础上,为每台服务器加上权值。算法为:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"(活动连接数 * 256 + 非活动连接数) ÷ 权重","attrs":{}}],"attrs":{}},{"type":"text","text":",计算出来的值小的服务器优先被选择。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:可以根据服务器的能力分配请求。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"7、sed最短期望延迟算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实sed跟wlc类似,区别是不考虑非活动连接数。算法为:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"(活动连接数 +1 ) * 256 ÷ 权重","attrs":{}}],"attrs":{}},{"type":"text","text":",同样计算出来的值小的服务器优先被选择。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"8、nq永不排队算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"改进的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sed","attrs":{}}],"attrs":{}},{"type":"text","text":"算法。我们想一下什么情况下才能“永不排队”,那就是服务器的连接数为0的时候,那么假如有服务器连接数为0,均衡器直接把请求转发给它,无需经过sed的计算。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"9、LBLC基于局部性最少连接算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"负载均衡器根据请求的目的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"地址,找出该","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"地址最近被使用的服务器,把请求转发之。若该服务器超载,最采用最少连接数算法。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"10、LBLCR带复制的基于局部性最少连接算法","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"负载均衡器根据请求的目的IP地址,找出该IP地址最近使用的“服务器组”,注意,并不是具体某个服务器,然后采用最少连接数从该组中挑出具体的某台服务器出来,把请求转发之。若该服务器超载,那么根据最少连接数算法,在集群的非本服务器组的服务器中,找出一台服务器出来,加入本服务器组,然后把请求转发。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"3、集群请求返回模式问题","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、NAT","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"负载均衡器接收用户的请求,转发给具体服务器,服务器处理完请求返回给均衡器,均衡器再重新返回给用户。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、DR","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"负载均衡器接收用户的请求,转发给具体服务器,服务器出来玩请求后直接返回给用户。需要系统支持","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP Tunneling","attrs":{}}],"attrs":{}},{"type":"text","text":"协议,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"难以跨平台","attrs":{}},{"type":"text","text":" 。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、TUN","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同上,但无需","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP Tunneling","attrs":{}}],"attrs":{}},{"type":"text","text":"协议,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"跨平台性好","attrs":{}},{"type":"text","text":" ,大部分系统都可以支持。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"4、集群Session一致性问题","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、Session Sticky","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Session sticky","attrs":{}}],"attrs":{}},{"type":"text","text":"就是把同一个用户在某一个会话中的请求,都分配到固定的某一台服务器中,这样我们就不需要解决跨服务器的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"问题了,常见的算法有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ip_hash","attrs":{}}],"attrs":{}},{"type":"text","text":"算法,即上面提到的两种散列算法。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:实现简单;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:应用服务器重启则session消失。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、Session Replication","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Session replication","attrs":{}}],"attrs":{}},{"type":"text","text":"就是在集群中复制","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":",使得每个服务器都保存有全部用户的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"数据。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:减轻负载均衡服务器的压力,不需要要实现ip_hasp算法来转发请求;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:复制时网络带宽开销大,访问量大的话","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Session","attrs":{}}],"attrs":{}},{"type":"text","text":"占用内存大且浪费。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、Session数据集中存储","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Session","attrs":{}}],"attrs":{}},{"type":"text","text":"数据集中存储就是利用数据库来存储","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"数据,实现了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"和应用服务器的解耦。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:相比","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Session replication","attrs":{}}],"attrs":{}},{"type":"text","text":"的方案,集群间对于宽带和内存的压力大幅减少;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:需要维护存储","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Session","attrs":{}}],"attrs":{}},{"type":"text","text":"的数据库。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、Cookie Base","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Cookie base","attrs":{}}],"attrs":{}},{"type":"text","text":"就是把","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Session","attrs":{}}],"attrs":{}},{"type":"text","text":"存在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Cookie","attrs":{}}],"attrs":{}},{"type":"text","text":"中,由浏览器来告诉应用服务器我的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"是什么,同样实现了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"和应用服务器的解耦。","attrs":{}}]}],"attrs":{}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:实现简单,基本免维护。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:cookie长度限制,安全性低,带宽消耗。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"值得一提的是:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Nginx","attrs":{}}],"attrs":{}},{"type":"text","text":"目前支持的负载均衡算法有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"wrr","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sh","attrs":{}}],"attrs":{}},{"type":"text","text":"(支持一致性哈希)、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"fair","attrs":{}}],"attrs":{}},{"type":"text","text":"(lc)。但","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Nginx","attrs":{}}],"attrs":{}},{"type":"text","text":"作为均衡器的话,还可以一同作为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"静态资源服务器","attrs":{}},{"type":"text","text":" 。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Keepalived + ipvsadm","attrs":{}}],"attrs":{}},{"type":"text","text":"比较强大,目前支持的算法有:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"rr","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"wrr","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"lc","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"wlc","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"lblc","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sh","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dh","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Keepalived","attrs":{}}],"attrs":{}},{"type":"text","text":"支持集群模式有:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NAT","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DR","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"TUN","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Nginx","attrs":{}}],"attrs":{}},{"type":"text","text":"本身并没有提供","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"同步的解决方案,而","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Apache","attrs":{}}],"attrs":{}},{"type":"text","text":"则提供了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"session","attrs":{}}],"attrs":{}},{"type":"text","text":"共享的支持。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决了以上的问题之后,系统的结构如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c4/c40b35051a3d03daf1d7dc2e8e03ae80.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段四、数据库读写分离化","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面我们总是假设数据库负载正常,但随着访问量的的提高,数据库的负载也在慢慢增大。那么可能有人马上就想到跟应用服务器一样,把数据库一份为二再负载均衡即可。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但对于数据库来说,并没有那么简单。假如我们简单的把数据库一分为二,然后对于数据库的请求,分别负载到A机器和B机器,那么显而易见会造成两台数据库数据不统一的问题。那么对于这种情况,我们可以先考虑使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"读写分离","attrs":{}},{"type":"text","text":" 和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"主从复制","attrs":{}},{"type":"text","text":" 的方式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"读写分离后的系统结构如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d7/d7ae36e29a9c9f56efe65bca95fbc6ff.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个结构变化后也会带来两个问题:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主从数据库之间数据同步问题。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"应用对于数据源的选择问题。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决方案:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MySQL","attrs":{}}],"attrs":{}},{"type":"text","text":"自带的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Master + Slave","attrs":{}}],"attrs":{}},{"type":"text","text":"的方式实现","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"主从复制","attrs":{}},{"type":"text","text":" 。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"采用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第三方数据库中间件","attrs":{}},{"type":"text","text":" ,例如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"是从","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Cobar","attrs":{}}],"attrs":{}},{"type":"text","text":"发展而来的,而","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Cobar","attrs":{}}],"attrs":{}},{"type":"text","text":"是阿里开源的数据库中间件,后来停止开发。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"是国内比较好的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MySql","attrs":{}}],"attrs":{}},{"type":"text","text":"开源数据库分库分表中间件。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段五、用搜索引擎缓解读库的压力","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据库做读库的话,常常对","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"模糊查找","attrs":{}},{"type":"text","text":" 力不从心,即使做了读写分离,这个问题还未能解决。以我们所举的交易网站为例,发布的商品存储在数据库中,用户最常使用的功能就是查找商品,尤其是根据商品的标题来查找对应的商品。对于这种需求,一般我们都是通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"like","attrs":{}}],"attrs":{}},{"type":"text","text":"功能来实现的,但是这种方式的代价非常大,而且结果非常不准确。此时我们可以使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"搜索引擎","attrs":{}},{"type":"text","text":" 的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"倒排索引","attrs":{}},{"type":"text","text":" 来完成。","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"搜索引擎具有的优点:它能够大大提高查询速度和搜索准确性。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"引入搜索引擎的开销","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"带来大量的维护工作,我们需要自己实现索引的构建过程,设计全量/增加的构建方式来应对非实时与实时的查询需求。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要维护搜索引擎集群","attrs":{}}]}]}],"attrs":{}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"搜索引擎并不能替代数据库,它解决了某些场景下的精准、快速、高效的“读”操作,是否引入搜索引擎,需要综合考虑整个系统的需求。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"引入搜索引擎后的系统结构如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/83/8357dac84133267f67720a6ffbf114ab.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段六、用缓存缓解读库的压力","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"常用的缓存机制包括页面级缓存、应用数据缓存和数据库缓存。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"应用层和数据库层的缓存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着访问量的增加,逐渐出现了许多用户访问同一部分","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"热门内容","attrs":{}},{"type":"text","text":" 的情况,对于这些比较热门的内容,没必要每次都从数据库读取。我们可以使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"缓存技术","attrs":{}},{"type":"text","text":" ,例如可以使用Google的开源缓存技术","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Guava","attrs":{}}],"attrs":{}},{"type":"text","text":"或者使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Memecahed","attrs":{}}],"attrs":{}},{"type":"text","text":"作为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"应用层","attrs":{}},{"type":"text","text":" 的缓存,也可以使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Redis","attrs":{}}],"attrs":{}},{"type":"text","text":"作为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"数据库层","attrs":{}},{"type":"text","text":" 的缓存。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外,在某些场景下,关系型数据库并不是很适合,例如我想做一个“每日输入密码错误次数限制”的功能,思路大概是在用户登录时,如果登录错误,则记录下该用户的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IP","attrs":{}}],"attrs":{}},{"type":"text","text":"和错误次数,那么这个数据要放在哪里呢?假如放在内存中,那么显然会占用太大的内容;假如放在关系型数据库中,那么既要建立数据库表,还要简历对应的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Java bean","attrs":{}}],"attrs":{}},{"type":"text","text":",还要写","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SQL","attrs":{}}],"attrs":{}},{"type":"text","text":"等等。而分析一下我们要存储的数据,无非就是类似","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"{ip:errorNumber}","attrs":{}}],"attrs":{}},{"type":"text","text":"这样的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"key:value","attrs":{}}],"attrs":{}},{"type":"text","text":"数据。对于这种数据,我们可以用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NOSQL","attrs":{}}],"attrs":{}},{"type":"text","text":"数据库来代替传统的关系型数据库。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"页面缓存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了数据缓存,还有页面缓存。比如使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"HTML5","attrs":{}}],"attrs":{}},{"type":"text","text":"的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"localstroage","attrs":{}}],"attrs":{}},{"type":"text","text":"或者","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Cookie","attrs":{}}],"attrs":{}},{"type":"text","text":"。除了页面缓存带来的性能提升外,对于并发访问且页面置换频率小的页面,应尽量使用页面静态化技术。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:减轻数据库的压力, 大幅度提高访问速度;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:需要维护缓存服务器,提高了编码的复杂性。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"值得一提的是:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缓存集群的调度算法不同与上面提到的应用服务器和数据库。最好采用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"一致性哈希算","attrs":{}},{"type":"text","text":" ,这样才能提高","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"命中率","attrs":{}},{"type":"text","text":" 。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"加入缓存后的系统结构如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/50/50e9837fc90bf81807492827e0dac20b.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段七、数据库水平拆分与垂直拆分","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们的网站演进到现在,交易、商品、用户的数据都还在同一个数据库中。尽管采取了增加","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"缓存","attrs":{}},{"type":"text","text":" 和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"读写分离","attrs":{}},{"type":"text","text":" 的方式,但随着数据库的压力继续增加,数据库数据量的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"瓶颈","attrs":{}},{"type":"text","text":" 越来越突出,此时,我们可以有数据","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"垂直拆分","attrs":{}},{"type":"text","text":" 和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"水平拆分","attrs":{}},{"type":"text","text":" 两种选择。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"数据垂直拆分","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"垂直拆分的意思是把数据库中不同的业务数据拆分到不同的数据库中,结合现在的例子,就是把交易、商品、用户的数据分开。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决了原来把所有业务放在一个数据库中的压力问题;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以根据业务的特点进行更多的优化。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要维护多个数据库的状态一致性和数据同步。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"问题:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要考虑原来跨业务的事务;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"跨数据库的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Join","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决问题方案:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"应该在应用层尽量避免跨数据库的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"分布式事务","attrs":{}},{"type":"text","text":" ,如果非要跨数据库,尽量在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"代码","attrs":{}},{"type":"text","text":" 中控制。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第三方中间件","attrs":{}},{"type":"text","text":" 来解决,如上面提到的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"提供了丰富的跨库","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Join","attrs":{}}],"attrs":{}},{"type":"text","text":"方案,详情可参考","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"官方文档。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据垂直拆分后的结构如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d2/d23078459276a80c60a7e44a6bffb7c8.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"数据水平拆分","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"水平拆分","attrs":{}},{"type":"text","text":" 就是把同一个表中的数据拆分到","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"两个","attrs":{}},{"type":"text","text":" 甚至","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"多个","attrs":{}},{"type":"text","text":" 数据库中。产生数据水平拆分的原因是某个业务的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"数据量","attrs":{}},{"type":"text","text":" 或者更新量到达了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"单个数据库","attrs":{}},{"type":"text","text":" 的瓶颈,这时就可以把这个表拆分到两个或更多个数据库中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果能克服以上问题,那么我们将能够很好地对数据量及写入量增长的情况。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"问题:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"访问用户信息的应用系统需要解决","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SQL路由","attrs":{}}],"attrs":{}},{"type":"text","text":"的问题,因为现在用户信息分在了两个数据库中,需要在进行数据操作时了解需要操作的数据在哪里。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"主键","attrs":{}},{"type":"text","text":" 的处理也变得不同,例如原来","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"自增字段","attrs":{}},{"type":"text","text":" ,现在不能简单地继续使用。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果需要","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"分页","attrs":{}},{"type":"text","text":" 查询,那就更加麻烦。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决问题方案:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们还是可以通过可以解决第三方中间件,如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"可以通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SQL","attrs":{}}],"attrs":{}},{"type":"text","text":"解析模块对我们的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SQL","attrs":{}}],"attrs":{}},{"type":"text","text":"进行解析,再根据我们的配置,把请求转发到具体的某个数据库。 我们可以通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"UUID","attrs":{}}],"attrs":{}},{"type":"text","text":"保证唯一或自定义ID方案来解决。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"MyCat","attrs":{}}],"attrs":{}},{"type":"text","text":"也提供了丰富的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"分页查询方案","attrs":{}},{"type":"text","text":" ,比如先从每个数据库做分页查询,再合并数据做一次分页查询等等。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据水平拆分后的结构如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b7/b7ff29ab3292da9407cbb04bdcfb0fd9.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段八、应用的拆分","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"按微服务拆分应用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着业务的发展,业务越来越多,应用越来越大。我们需要考虑如何避免让应用越来越","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"臃肿","attrs":{}},{"type":"text","text":" 。这就需要把应用拆开,从一个应用变为俩个甚至更多。还是以我们上面的例子,我们可以把用户、商品、交易拆分开。变成“用户、商品”和“用户,交易”两个子系统。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"拆分后的结构:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5e/5e3ef7215f31c99490f4c7cff3a2c2a5.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"问题:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这样拆分后,可能会有一些相同的代码,如用户相关的代码,商品和交易都需要用户信息,所以在两个系统中都保留差不多的操作用户信息的代码。如何保证这些代码可以复用是一个需要解决的问题。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决问题:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过走服务化SOA的路线来解决频繁公共的服务。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"走SOA服务化治理道路","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了解决上面拆分应用后所出现的问题,我们把","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"公共","attrs":{}},{"type":"text","text":" 的服务拆分出来,形成一种","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"服务化","attrs":{}},{"type":"text","text":" 的模式,简称","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SOA","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"采用服务化之后的系统结构:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8c/8cf28d8049a17aa24d1a295f95bf7455.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相同的代码不会散落在不同的应用中了,这些实现放在了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"各个服务中心","attrs":{}},{"type":"text","text":" ,使代码得到更好的维护。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们把对数据库的交互业务放在了各个服务中心,让前端的Web应用更注重与浏览器交互的工作。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"问题:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何进行远程的服务调用?","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解决方法:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以通过下面的引入消息中间件来解决。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"阶段九、引入消息中间件","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着网站的继续发展,的系统中可能出现","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"不同语言","attrs":{}},{"type":"text","text":" 开发的子模块和部署在不同平台的子系统。此时我们需要一个平台来传递可靠的,与平台和语言无关的数据,并且能够把","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"负载均衡透明化","attrs":{}},{"type":"text","text":" ,能在调用过程中","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"收集","attrs":{}},{"type":"text","text":" 并","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"分析","attrs":{}},{"type":"text","text":" 调用数据,推测出","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"网站的访问增长率","attrs":{}},{"type":"text","text":" 等等一系列需求,对于网站应该如何成长做出预测。开源消息中间件有阿里的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Dubbo","attrs":{}}],"attrs":{}},{"type":"text","text":",可以搭配Google开源的分布式程序协调服务","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Zookeeper","attrs":{}}],"attrs":{}},{"type":"text","text":"实现服务器的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"注册","attrs":{}},{"type":"text","text":" 与","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"发现","attrs":{}},{"type":"text","text":" 。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"引入消息中间件后的结构:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/da/dab72c7a9e8a54c63de4527976aa79e2.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"总结","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上的演变过程只是一个例子,并不适合所有的网站,实际中网站演进过程与自身业务和不同遇到的问题有密切的关系,没有固定的模式。只有认真的分析和不断地探究,才能发现适合自己网站的架构。","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章