今天要讲的题目比较热,但也比较“简单”,由于有不少公司大型系统已经在用。个人演讲内容包括两个方面:一个是分布式架构的实践,另一个是服务体系中容器化怎么作。docker
分布式服务框架实践数据库
可能你们不少都听过服务化,或者叫微服务,可是这个“微”字很难平衡,由于每一个人有每一个人的理解,咱们的理念仍是以简单实用为主,下面是惟品会 RPC 服务化框架的主要结构,proxy 层是咱们特别重要的一个环节,后面会详细介绍。缓存
在展开以前,先介绍下惟品会作服务化的缘由,重要的有 5 点:网络
-
服务复杂度高。你们知道惟品会作特卖的,里面涉及到的大的系统比较多,包括库存、订单、支付等等。架构
-
团队规模大,国内的大电商企业规模都是几千人的技术规模,这是一个比较大的挑战,不像咱们如今说有几十我的的创业公司。几千人的公司实际上推进一些公共技术架构比较困难。咱们有专门的运维部门、业务部门等。团队越分越散,最后的结果很难协调一块儿开发,这是咱们最大的问题。并发
-
弹性应对高并发能力,要有足够的弹性,由于咱们有双十一,12.8 日店庆,接下来立刻是 4.19 大促。业界竞争是咱们作大促的缘由,可是大促如今已经愈来愈烂了,包括京东、苏宁易购,包括惟品会,一周一个大促,这个不能叫大促,只能叫“周促”。大促形成的流量的并发愈来愈凌乱,今天可能 10 点钟很频繁了,到 11 点钟没流量了,但到了晚上 8 点流量又上来了,这种无规律的突发流量,要好支撑以及运维高性价比是很困难的一件事情。框架
-
足够的容错和自愈能力,这是咱们作服务化最大的动力。整个的容错体系,不能说今天死了,找一个运维人员从新找一个机器上切换 IP。固然,现实还有一部分系统作不到服务化,旧的体系依然还存在。运维
-
下降维护成本,出错的话到底查仍是不查,须要查的成本很是低。否则的话,没法把握下一次发生什么事情。作开发的,有一大部分时间都是作查错。异步
通常公司技术体系能够分红基础层、业务层、接入层三层的划分。基础层技术团队能作的很少,数据库、缓存及文件系统都是标准化的组件。可是服务化是在作中间层及业务聚合层,再提供 API 出来给到上面有网站及 APP 使用,服务化怎么作对整个架构以及全部技术团队都有影响。分布式
通过对服务化的思考与实践,咱们主要目标是作好两个事情,一个是整个体系的服务注册与发现,第二个是服务治理。
服务注册与发现
惟品会是本身构建的通讯框架,基于 Thrift RPC 的方式。整个 RPC 框架分红三段:client、proxy,service。
咱们的作法是把 proxy 这一层独立出来,经过 proxy 调用服务。
为何这么作?
当服务愈来愈多,会发现一个问题,A 部门今天升级,B 部门不升级,就会形成业务处理很混乱,路由和容错都会很混乱。咱们很难强迫业务部门说今天必定要把业务用的框架升级,业务部门会反感这种自身没有变动需求的被动升级。因此咱们会把服务治理功能独立出来放在一个地方,就是这里提的 proxy 端。
服务发现网上已经有不少选择了,搭建不是太复杂,原理上只要把服务注册到公共的地方,即把 IP + 端口注册,而后 client 端获取对应的 IP + 端口的列表就能够了。有不少不一样的技术实现服务发现。如 etcd、consul 及传统的 DNS 方式。
服务治理
服务治理传统你们用得多的是代理模式,使用治理功能的服务都须要流经它。考虑到这个远程代理若是有什么异常会影响总体服务质量,咱们把代理放到本地,没用采用中心化的部署。
这是咱们实现分布式服务总结的一个理念:尽可能让全部的中心化功能都本地化,经过本地化的方式找到服务在哪里,在本地完成治理。
当咱们须要升级时,只须要把本地代理升级换掉就能够了。
如上图所示,服务治理还作了不少事情,主要跟业务相关的,通用层面包括服务路由、流量控制等。
灰度流量控制
刚才另一个朋友也讲灰度,咱们叫 AB 测试,作法以下。
咱们能够经过百分比的方式,在新上一个服务的时候,只放 1% 或者千分之一的流量来作灰度。
这样的话,影响客户量是最小的,否则的话,原来有 9 台机,再上一台可能有问题的机器,就有十分之一的几率出错。
治理策略
服务治理方面还作了服务之间的隔离,防火墙的部署和邻近机房路由等。
若是服务部署在异地多个机房,服务就会产生跨墙的问题,机房与机房最快也要三二十毫秒,须要充分考虑跨墙及延迟的特性。咱们还作了一些熔断、限流的策略。
你们能够对比一下 Dubbo,咱们没有选择它的缘由就是上述服务治理方面功能的需求。
对于 proxy 高可用,实际上咱们有一个灾备,把一样的 proxy 在中央找一个地方作容灾,当你发现本地不通的时候能够在远端找到。这样就能够作灾备,实现无缝升级。
另外咱们作的弹性路由,在不一样的 IDC 机房间配不一样的 IP 段之间路由的优先级,当优先级不一样的时候优先选邻近的机房的服务处理。
减化运维
另一个减化运维的需求,也是跟多机房有关。
若是有不少机房,有一个机房正好作支付,如今支付的要求比较高一些,全部的服务都会被保护起来,就会有一个问题,当找到那台机器的 IP 时候,有可能发现这台机器不通。
这是因为咱们从注册发现来找,有可能找到的是防火墙后面的那台机器,这样每次去申请支付的时候,就会出现一个问题,要求全部的客户端的防火墙访问策略都要被打开,而后才容许不一样的客户端进来。
但最大的问题是作支付服务的那我的根本不知道有多少人在用它。怎么办?咱们实际上经过判断服务是否是个特定的服务,若是是把它所有绕到一个防火墙后面的远程 Proxy,而后经过反向代理的方式进来,这样的话,避免每次都须要作配置防火墙策略,只须要给(Proxy)独立开一个对外的开放端口就能够了。
中间聚合层
服务自己是零散化的东西,一般要接入的是中间层。实际上会在中间层作聚合,聚合层自己便可以作业务聚合,也能够作中间层的聚合,每一层的聚合都要作异步调用的设计。同时要对接口进行抽取,这样的话才能给 APP 使用。由于 APP 自己是没有服务发现的。
RPC 性能
使用 RPC 有不少理由, 咱们这里对比一下它的总体的性能(固然性能只是一方面,是否真的须要,取决于你到底用多少性能,latency 想要多少)。
这是咱们本身内部的一个简单的对比。咱们会起用调用跟踪、写日志等,大概咱们在 4.8 万 TPS,用 Tomcat Rest 方式压,能够到 2.4 万。
总结
整个服务化来讲,不是纯粹引入一个 RPC 框架来作这么简单,整个服务化是一个体系,它包括不少东西,服务框架只是其中一个面。服务离散化以后,在管控服务方面,须要付出的代价也会大,你们作服务化以前必定要想清楚。
其余实践总结
顺带提一下咱们的“黑科技”。
一、压测时候须要把 JMeter 参数调好,否则的话,颇有可能不是的服务的问题,而是 JMeter 可能压不到。
二、注意 Young GC 的次数。
三、ZooKeeper
咱们服务发现与治理用的 Zookeeper,Zookeeper 瓶颈很是多,如何在跨机房、大数据量状况下若是用好 ZooKeeper?
首先整个系统设计,核心作选举的三个节点必定要放在同一个数据中心部署。否则写数据会形成整个 Zookeeper 集群不稳定。另外全部的业务节点所有挂在观察者模式上,让观察者模式不要影响全局。
容器化演进
下面分享一下咱们容器化的演进。
咱们运维思路遵循简单原理,目前采用单进程部署,运维简单也是为了最大的容错。
在物理机体系上,虽然私有云咱们也在作。可是要打造的体系比较大,运维难度也比较大。很多物理机CPU 才百分之几。这是咱们为何要作容器化的缘由。
容器化的选型,没有说哪个对哪个错,咱们选型充分考虑了本身的特性。
咱们容器化最后选择 Marathon 和 Mesos,主要缘由是为了适应物理层。
Kubernetes 尚未作物理机这一层管理。咱们须要方案有对整个体系后续的管理能力。K8S 里面的细节我就不说了(最大到 1000个 节点),每一个人都有本身的喜爱及场景来选择。
下面是整个容器平台的概貌,左边服务化体系和监控体系,最右边是原有的物理机运维体系,这两个均可以直接沿用以前的系统,不须要太多调整。
容器里面是咱们主要提几个东西,包括业务的服务、Flume Agent, cAdervisor 等,咱们仍是遵循容器单进程的理念。
整个容器化的发布流程也比较简单,从开发一直到运维,经过 Mesos + Marathon 作调度,用 Docker 运行,再作监控分析,还有一些辅助的系统,好比网络和运维的工具等。
镜像的发布
从发布的角度,要考虑怎么简单。咱们作的简易化的发布,直接用 Registry + Jenkins 实现。你们只要在 Jenkins 写好脚本就能够了,这是一个简化的流程。不须要作代码开发。
对于 Registry HA 方案,若是作一个相似于用分布式软件存储的方式,我不肯定能不能作好管理。咱们仍是走最简单的方式,在 Jenkins 里面把它部署到多个 Registry 里。前面配置反向代理,让客户端能够访问到,这样容量就不会有问题。
网络
默认无论用 NAT 的方式仍是 host 方式,它的管理始终是很麻烦。我仍是但愿 Marathon + Mesos 的方式无论网络,网络交给咱们本身管。目前个人方式是每台机器用 Linux VLan 的方式。但愿后续 libnetwork 能够支撑更好的 DHCP 的方式,目前还没考虑引入。
VIP DCOS
你们都很熟悉 DCOS,咱们要作的事情就是基于 mesos + marathon 和 docker、cAdervisor 等组合成一个服务,包括实现咱们本身的监控体系,还有策略的管理,包括弹性伸缩调度的能力,而后作一些预警,这些组件整合在一块儿,有一个独立的入口。
业务部门始终都是比较厌烦繁杂的东西。所以提供了一些相对友好的一些界面。
资源共享
当公司大了以后,不一样的部门有本身的运维,不一样的部门有本身的机器。他不想与别人共享,整个云化又是共享的概念,咱们针对这种方式作一个限制的资源池的隔离,好比购物车和下单隔离成两组,本身的共享及弹性调度在本身的池里去作。
固然当大促的时候,咱们会从公有池给它分额外的资源。未来继续演进,若是须要咱们能够把它升级到公有云,把公有云机器变成 Mesos 的 slave 机器,把它挂到本身的集群里面,它就能够被调度了。
容器的“黑科技”
容器使用,咱们使用了一些“黑科技”。
首先,咱们在作容器化的时候调整了 Linux,在上面作一些额外的手脚。
内存策略:首先是主机 memory,一个是回收的策略的调整,一个是 swap 的调整,它是比较大的问题。默认的 memory 使用 60% 后就会使用 swap,可是最好的方式尽量用光 memory 再用 swap。
IO 优化:两个 IO 比较关键,一个是磁盘 IO,一个是网络 IO。由于容器多了以后,实际上一个物理机能支撑 log 输出的磁盘 IO 是很是有限的。这样的话,支撑不了几个容器,因此 IO 是一个很大的影响。尽量在物理机上配多个磁盘,把不一样的 log 文件用不一样的磁盘隔离开。第二个手段是应用程序自己将 IO 作一个抽样,不是全部的应用程序全部的 log 都要输出,根据状况作抽样大多能够知足须要。
磁盘 IO:再次,像咱们这样的服务化体系,将 log 搜集到中心地方,log 存到本地意义不大。这样能够用一块内存磁盘方式先写进来,避免磁盘 IO。
网络 IO:建议最好用高性能万兆网卡和交换机。若是没有,则能够用多个千兆卡把它bond在一块儿。 今天讲的大概这么多,谢谢你们!