Rails Rails on Cloud(Rails 微服务实践理论)

rocLv · 2021年05月21日 · 最后由 pathbox 回复于 2021年05月26日 · 912 次阅读

最近研究了一下 Java 的微服务生态。虽然目前微服务有 Spring Cloud 和 Service Mesh 两种主要模式,不过相对来说围绕 Spring Cloud 的微服务生态更加完善一些。

首先,我们看看微服务需要解决的问题。

对于很多巨头来说,随着业务的发展,应用变得越来越复杂。这里至少有两个复杂度,一个是业务的复杂度,二一个是数据的膨胀。

应对业务的复杂度,我们可以通过业务拆分来解决。比如说订单业务,经过拆分可能变成了支付模块、订单模块、仓库模块等等。业务的拆分带出来的问题就是所谓的分布式事务。

单体应用的时候,订单业务可以在一个 APP 内完成。我们可以通过数据库自带的事务模式进行应对。然而,对于分布式事务,我们需要通过其他一些手段才能实现数据库的事务模式。

从单体应用转到微服务面临几个问题:

  1. 微服务的管理。面对动辄上百万的微服务(据说 JD 的微服务数量),估计需要成立一个微服务管理局了。
  2. 微服务直接的访问。
  3. 微服务本身的负载均衡。
  4. 微服务熔断、降级。
  5. 微服务的分布式事务跟踪。
  6. 微服务日志收集、分析。

对于微服务的管理,我们可以采用注册中心的方式。 所有的微服务,当我们部署了的时候,我们可以通过在注册中心注册的方式,通知其他微服务。所以这就是微服务的注册中心的主要功能。

然而,这样的毛病在于,如果注册中心挂了,我们的整体服务都挂了。因此,为了可以保证高可用,我们需要保证注册中心的高可用。这个也是实现注册中心的难点。

说完注册中心,再说说微服务之间的访问。 为了降低微服务之间访问的延时,以及应对微服务之间的通讯协议(比如 rpc, http, protobuff 等),需要引入一个中间件。

另外,为了保证服务的可用性,我们可能还需要实现单个微服务的负载均衡。整个服务的负载均衡,我们可以通过 nginx 实现。相对于整个微服务框架来说,我们需要实现自己的简单的负载均衡。

还有微服务的熔断和降级,这些我们再单体应用的时候也有。不过现在不同的是,我们需要告诉其他的微服务,而不是用户。

微服务单独引入的有分布式事务跟踪,方便我们订单有问题的时候,进行问题跟踪。

最后一点,没在上面列出来的,就是微服务网关。

微服务网关,主要用来做认证、过滤等。

综合以上,大家可以看看基于 Spring Cloud 实现的一个后台管理 APP。

微服务框架

这里,注册中心用的是 Nacos, 微服务之间的调用用的是 openfeign,负载均衡是 Ribbon,熔断降级用的是 Sentinel,分布式事务跟踪用的是国人开源的 Skywalking。日志收集用的是 ELK。

写到这里,我想起来以前论坛里很多人问过,Rails 有微服务吗?答案是没有(或者我不知道)。

然而,据我所知,很多大的互联网厂商,一般也不会直接用 Spring Cloud 的生态,都是自研的。

说这个是什么目的呢?目的就是告诉大家,既然用微服务了,我们就自研吧。

说到自研,我们先从自研注册中心说起。

注册中心,开源的适合 Rails 的比如携程开源的 Apollo,阿里的 Nacos(所以说大厂都是自研的)。说起我们自研呢,主要需要实现的功能就是微服务注册。

同样,要保证高可用,我们需要了解一下 CAP 模型和 BASE 模型。

为了保证注册中心的高可用,我们需要根据业务类型来选择是 CP 模型,还是 AP 模型。

可能有些人还不太知道 CAP 模型,这里简单说说。C 代表一致性,A 代表可用性,P 代表分区容错性。

通常来说,CAP 不能同时满足。甚至 CP、AP 也无法 100% 满足。所以就有了 BASE 模型,也就是基本可用和最终一致性。当然 BASE 模型肯定不符合金融行业。

对于数据一致性,我们可以选择 Redis 或者 ETCD 作为存储。分布式 Redis 是 AP 模型,而 etcd 则是 CP 模型。这里面也各有个的问题。

除了数据的一致性以外,注册中心还需要保证多活。

多活的算法有很多种,大家可以自行去了解一下。有简单的多机备份(需要考虑数据的一致性),Leader 选举(如 Kubernetes Master Node)。

实现了注册中心之后,最主要的就是网关的实现。

虽然我们在前面把熔断、降级、负载均衡这些都分开表述,而且在 Spring Cloud 的生态里,确实各有独自的实现。不过实践中,很多会把这些功能都放在网关里。

网关的主要作用是认证、过滤、熔断、降级、负载均衡,甚至灰度发布、金丝雀发布,以及 A/B 测试等等,有时都会放在网关中实现。

对于对标 openfeign 的功能,其实可以做一个简单的封装即可。

为了做好微服务,分布式事务的跟踪也是非常必要的。对于分布式事务,可以生成一个分布式 ID,目前国内百度之类的,都有开源的实现。

另外,不知道有没基于 Ruby 或者 Rails 的分布式事务实现。分布式事务有四种模式: AT、TCC、Saga、XA, 有兴趣的可以自己看看。我自己的意见是在微服务拆分的过程中,尽量避免引入分布式事务,除非万不得已。

有了分布式 ID 之后,做分布式事务跟踪就比较容易了。

大概微服务相关的就这些内容吧。

当然做好微服务架构设计,涉及到方方面面,特别是我们总是需要在 AP 和 CP 模型之间做选择。在选择具体的工具的时候,一定要考虑这个业务是 CP 模型,还是 AP 模型;然后根据业务去选择适合的框架。

最近接手的 Java 项目就是这种微服务架构😅

Rails 没有微服务我觉得就是一个误解,既然微服务把业务拆分了通过 API 通信,那么用 Rails 来写微服务有何不可。如果一定要用某种框架才能实现微服务,那么这些微服务是不是产生了某种耦合?

Rei 回复

说耦合也正确,框架的目的是让开发更聚焦业务本身。适当的耦合比不耦合更好

微服务本身是一种架构,每个微服务可以用合适的语言实现。

各微服务尽量内聚,避免外调和跨服务事务。

经历过和听过的微服务改造,原因大体是可用性(最多),可维护,可扩展。

数据库性能那么好,分表前可以抗非常久。

分布式事务的话,如果服务拆的合理,或者一致性不那么重要,可以没有。

http 性能完全可以接受,主要是没有 schema。

rails 没有什么适合不适合的,没人搞罢了,就拿 github 来说,一个企业服务,三天两头挂,也没见他搞啥…

然而,这样的毛病在于,如果注册中心挂了,我们的整体服务都挂了

对这句有点疑问。 每个客户端本地在内存中应该是缓存了服务端地址列表或者是客户端调用连接实例的,注册中心挂了,而后端集群服务没有挂的情况,整个服务是可以继续运行,只是对有新的服务上线或下线,或者有动态扩容缩容调整机制,客户端是没法即时更新,对应的服务请求会失败

rails 在微服务架构生态目前看是没有那么完善,不过另一个思路:借助 K8s,也能实现高可用集群。微服务架构中涉及的问题主要是:服务治理、流量管理和日志监控等。K8s 可以帮助简化这些问题,甚至可以不用注册中心

微服务里面的服务 (service) 用什么语言都行吧,这不正是微服务的一个优点吗?用 rails 当然也可以

可以参看图灵出版的微服务设计

感觉文章写的是微服务之间的管理,确实不是 rails 干的事情。

pathbox 回复

一部分疑问你自己回答了,另一部分答案是并不是所有的注册中心都是这种实践的。

heroyct 回复

微服务不挑语言,生态挑

rocLv 回复

了解了👌

需要 登录 后方可回复, 如果你还没有账号请 注册新账号