如何服务化
一、什么是cloud native
Cloud Native (国内译为“云原生”),最早是 Matt Stine 提出的一个概念。与微服务一样,Cloud Native 并不是一种具体的技术,而是一类思想的集合,包括DevOps、持续交付(Continuous Delivery)、微服务(MicroServices)、敏捷基础设施(Agile Infrastructure)、康威定律(Conways Law)等,以及根据商业能力对公司进行重组。Cloud Native 既包含技术(微服务,敏捷基础设施),也包含管理(DevOps,持续交付,康威定律,重组等)。所以,Cloud Native 也可以说是一系列Cloud技术、企业管理方法的集合。
Cloud Native 具备有以下特性:
- 以云为基础架构
- 云服务
- 无服务
- 可扩展
- 高可用
- 敏捷
- 云优先
- 等等
二、微服务
微服务虽然带来了架构上的优势,但同时也引入了复杂性。我们不得使用一些组件,来解决技术复杂性提高之后带来的问题:
-
服务注册中心:一个服务可以有多个实例,那么我们在向一个服务发出请求的时候,怎么知道这个服务有哪些实例呢?为了减少手工维护的麻烦,我们需要服务注册中心。每个服务实例在启动时,向注册中心注册自己的IP地址等信息。这样,服务在调用别的服务的接口时,就可以通过注册中心,查询到其他服务的实例,向实例发起请求。沃尔兹总店就是起到注册中心的作用。
-
负载均衡:由于一个服务可以有多个实例,所以不管是来自外部客户端的请求,还是微服务系统内部服务之间发起的请求,都需要引入负载均衡的机制,来发挥多实例集群的作用。有的书也称这两种负载均衡为服务器端负载均衡和客户端负载均衡,各自具有代表性意义的实现分别是Nginx和Ribbon。
-
API Gateway:一个外部请求过来之后,我们需要知道这个请求是发给哪个服务的,也就是我们需要一个请求路由的功能,比如/cm/*的请求,要发给客户管理服务,/om/*的请求,要发给订单管理服务。另外,不是所有请求都可以被我们系统处理的,我们需要判断这个请求是否携带一些必要的鉴权信息,并对其进行鉴权,也就是请求过滤的功能。而API Gateway,就是起到了这两个功能,它就像整个微服务系统的门面,所有请求,都要先经过它的处理,才会转发到对应的服务。
微服务系统的衍生组件还有很多,比如对各个服务进行的配置管理的分布式配置中心、各个服务之间进行消息通讯的消息总线和消息驱动机制(上图中的Message Queue)等。
三、服务化的愿景
「微服务」 是业内最近两三年业内很火的 buzzword,迁移到微服务架构,大多强调这些好处:
- 松耦合
- 独立发布
- 快速迭代
- 故障隔离
- 增加重用
经过服务的拆分,将复杂到难以移动的单体应用,拆分为多个可以独立部署的服务,单个服务的复杂性远远小于整体,这样不同服务的开发者可以并行开发,从而提高开发效率;因为服务的细粒度,可以 assign 给一个具体的人让他负责,随着业务的增长对服务做定向扩容;同时因为服务的隔离性,可以隔离故障,提高整体的稳定性。
四、基于 SSO 的分拆
RPC (远程过程调用)是服务化体系中基础的基础,但是慢慢的我们发现 RPC 并非分拆的唯一选择。基于 RPC 的水平分拆会引入中间层次,增加联调的环节,对于快速开发的新业务而言,无法忽视额外的联调成本。
这里我们得到的启发是,服务的分拆并非 RPC 不可。相反,我们希望看到更少的 RPC,更多的内聚。更少的 RPC 接口意味着更小的服务边界,更稳定的接口,更少的 break change。内聚意味着允许功能需求的独立演进,对其他业务的影响降到最低,也意味着内聚的业务模块内部,可以充分利用缓存来优化性能。
五、如何划分服务边界
理想的世界里,服务边界恰好匹配于业务边界。然而工程师首先要承担业务需求的压力,只能抽时间重构拆分,业务边界也并不总是如新项目那样明晰。
这意味着要考虑优先级,也需要在拆分之前认真地思考业务的边界。排定优先级,考量拆分的收益与风险即可。划分业务的边界,则需要更多的思考拆分后的未来将如何沟通协作,然后再考虑技术因素。目前我们主要有这几个考量:
- 是否拥有独立团队来维护,或者是否拥有发展为一项独立业务的潜力;
- 围绕领域而非 feature,有明确的维护团队,避免过于细粒度;
- 拆分之后,能否改善现有的合作流程;
- 能否帮助区分核心、非核心业务,改善稳定性;
以 feed 为例,它首先拥有独立团队维护,通过拆分,技术层面上允许 feed 团队重构掉下层服务与上层展现之间的冗余 RPC 调用,且调用模式较 uniform,在产品层面接受数据最终一致性的前提下可以通过 TTL 缓存提升性能,乃至按自己的业务场景做更细致的优化(优化结束后我们的某些接口 P95 性能加快了一倍);更重要的是对协作方式的影响,未来专栏、问答等生产信息的垂直业务,只提供一个 RPC 接口对接 feed 流即可,而不必集成到主站,这一来 「接入 feed」 流程的参与者,从 feed 组、垂直业务、主站三方,简化为 feed 组和垂直业务双方;此外 feed 通过 TTL 缓存,实质上冗余了一份垂直业务的数据,配合断路器的使用,依赖的垂直业务的抖动甚至崩溃在 feed 这边都可以优雅降级且保持正常展现了。将 feed 与主站的变更相隔离,也有助于改进作为一项核心业务的 feed 的稳定性。
六、服务分层:业务服务和公共服务
在垂直业务之外,也存在多数业务都会重用的公共服务,如用户、话题、网页抓取、多媒体、推送等。业务服务和公共服务在关注点上有所不同:
我们希望业务服务快速迭代,更快、更好地响应多变的业务需求,更多地面向前端工程师;
我们希望公共服务稳定可靠,较少发生改动,但 SLA 要好,更多地为业务重用;
这里会形成一个自然的分层:上层业务求快、下层公共服务求稳。