随着互联网+和平台化战略的兴起,各个行业的 IT 系统都在向互联网架构发展,涉及的主要技术包括微服务、消息和弹性计算等,采用微服务架构实现服务高内聚、低耦合,通过异步消息完成交易快速响应和高并发。由于微服务和消息是企业应用架构中用的比较多的,故希望通过本文探讨以下问题:

  • 企业服务总线(ESB)是否真的过时了?
  • 为什么 RocketMQ 是企业服务总线的最佳技术方案之一?
  • 如何设计企业微服务架构演进路线图?

SOA 架构演变史

阶段 1:企业服务总线 ESB

当单体应用拆分成多个应用后,应用服务之间需要相互调用,而 ESB 刚好是用来解决服务调用方和服务提供者之间的点对点连接关系的,点对点连接不如大家都连到一个总线上,这样就会实现物理位置、传输协议等多个方面透明。ESB 核心技术就是 MQ 消息中间件,服务一旦接入总线,相互之间紧耦合调用变成了发消息和收消息,如下图所示:

这样做的好处如下:

1、服务之间的点对点变成了总线连接,服务提供方和调用方接入总线后指定相同的队列名即可完成单向通讯。当然双向通讯也是可以实现的,比如 IBM 的 MQ 产品在推 ESB 解决方案时就提供发消息和收消息自动配对功能,实现机制是通过消息相关标识 CorrelId 字段,将一个消息与另一个消息相关,或将一个消息与应用程序正在执行的其他工作相关,使用这个机制可以完成消息发送和接收的 request-reply 模式,达到实时调用响应效果,从而使一些不适合异步消息调用的场景也可以使用 ESB。

2、服务之间负载均衡转移到总线。服务调用方可以是多个,共同发送消息,服务提供方也可以是多个,共同接收消息,因此只要总线本身是负载均衡的,那么就不存在负载均衡问题。

3、总线是服务之间的缓冲器,确保请求消息积压不会冲垮被调用方,同时能保证服务调用方的体验。

综上,ESB 企业服务总线通过 MQ 消息中间件实现 SOA 架构的两点核心功能:服务注册发现和负载均衡,服务接入 ESB 就完成了“注册”,通过指定消息队列名实现“服务发现”,而负载均衡问题通过总线本身是否负载解决。由于 ESB 优势明显,故在金融业尤其是银行业得到广泛应用,但由于早期的 MQ 消息中间件架构比较重,在高可用和高并发方面表现一般,更多关注的是消息事务性,不能完全满足 ESB 本身的职能要求,因此当 ESB 上到一定规模后就成了整个应用架构最大的性能和故障点。

阶段 2:微服务

微服务架构出现于 2014 年,采用注册中心实现了服务注册发现、负载均衡、容错、 监控等功能,同时服务拆分粒度可以更细,服务共享和 IT 组织协作也可以更加精细化,因此微服务架构也推进了 IT 团队的专业分工和高效协作。

微服务的特征:

  • 通过服务实现组件化,服务拆分粒度更细,有利于服务共享和集成 ;
  • 按业务能力来划分服务和开发团队,有利于 IT 组织高效协作 ;
  • 去中心化,服务与服务之间直接点对点连接,没有任何代理或负载均衡器,服务节点与注册中心采用异步心跳通讯。

缺点:

  • 微服务架构技术边界明显,必须通过新建方式才能完成新旧系统替换,成本较大;
  • 老系统和新系统之间的对接仍旧通过传统负载均衡或网关来实现高可用,存在单点问题;
  • 注册中心是微服务架构边界,随着加入服务节点数增加,注册中心会成为最大的故障点。

3、服务网格 ServiceMesh

针对微服务架构边界和新旧技术对接问题,诞生了服务网络 ServiceMesh,也称为代理边车(Sidecar),这种架构的本质是将微服务架构中的注册中心、负载均衡、故障处理等功能提取出来,单独作为一个代理进程与应用服务部署在同一机器,同时在网络通讯层进行干预,实现服务的自动代理和自动发现,实际是把代理做成了微服务架构,这样不用动原来的老系统,就可以用上微服务架构的核心功能,简单高效。

服务网:


缺点:

每个服务部署的服务器或容器上都要安装一个代理,就单个服务而言,代理是单点,一旦代理挂了,则该服务不可用,这个问题对每个服务都存在。

ServiceMesh 要实现所有服务的互通互连,要求所有服务代理连接到注册中心,那么注册中心又成为最大故障点。

ServiceMesh 实际是微服务版本的企业服务总线,用于服务解耦和负载均衡,而 SOA 架构除了具备这些功能,还需要通过服务拆分和共享满足业务需求开发、上线、运维的快速迭代,从这个角度讲 ServiceMesh 称不上微服务架构,仅仅完成其中一部分功能。因此,
ServiceMesh 只是一个微服务架构实施的临时方案。

启示:

从单体应用到 SOA 架构的3个阶段,每个阶段都出现了不同的架构解决方案,通过以上分析不难看出,通过单一架构解决企业应用架构的所有问题是不可行的,因此我们要吸取各种架构的优点,采用多种架构融合的方式寻求最佳解决方案。

弘康人寿微服务架构建设

弘康人寿 IT 系统同国内大部分保险企业类似,都是从一个单体核心系统逐步拆分发展而来,服务与服务之间没有通过 ESB 总线,而是采用传统负载均衡方式进行通讯,还处于 SOA 架构演变的初级阶段。去年公司陆续在官网和增值服务领域引入了微服务架构,新官网使用的 Dubbo,增值服务使用的是 SpringCloud,这里说明一下,公司内部开发统一使用的微服务架构是 SpringCloud,由于新官网是外采的成型产品,技术架构无法改变,故使用 Dubbo ,这样的情况在国内很多企业都存在。

所以,在微服务架构实施初期我们就意识到统一技术架构对企业来说是有很大困难的,不同的业务线,不同的团队对技术架构的需求和理解不一样,所以技术架构方面一定要是开放的,求同存异,不能为了架构而架构。另一方面我们仔细分析了公司业务结构和特点,全部放入一个微服务架构边界(注册中心)里也是不合适的,那么也就意味着微服务架构也会分成几个不同区域,每个业务区域连接一个注册中心,架构规划图如下:

区域1直接面向互联网,属于前置应用,区域2到5在内网,属于中后台服务,架构设计到这一步,摆在我们面前的问题是不同的区域有的是微服务架构,有的是旧的分布式架构,不同架构之间都存在注册中心、负载入口等边界问题,按照传统思路各个区域使用网关或软负载统一对外提供服务,架构图如下:

在各个区域增加一个负载均衡器,每个区域内部使用微服务或老架构进行通信,跨区域则通过负载均衡器,由于传统的负载均衡器(如 Nginx)都存在单点问题,一旦出现宕机或阻塞,将会影响整个系统运行,所以为了分摊风险,负载均衡器也采用分区设计。

另一方面,大家可以看到各个应用区域之间的互连互通也是非常必要的,尤其是在大数据、AI 等新科技驱动下,企业的数据化转型一个最基本的要求是所有数据能否自由流通,所以从这个角度看,上图中的负载均衡器实际上是一个数据总线的雏形,我认为可以参考企业服务总线 ESB 和 ServiceMesh 的设计思想,用高可用的消息中间件取代上图中各个区域的负载均衡器。

为什么 RocketMQ 是企业服务总线的最佳技术方案之一

在 SOA 架构发展的三个阶段,我们提到了 ESB 的优势和缺点,对于 ESB 当时采用的消息中间件过重、性能差等技术问题,随着开源技术的不断发展和进步,这些问题得到有效解决,目前开源技术中消息中间件大概有 RabbitMQ、RocketMQ 和 Kafka 三种选项,网上有很多纯技术指标对比,单就 ESB 级别的应用来说 RocketMQ 是最均衡的,并且经过阿里巴巴"双11"压力考验,性能稳定,下边从以下几个方面说明:

1、微服务架构、高性能、高可用

RocketMQ 消息中间件架构上基于微服务设计,由 NameServer 注册中心、 broker 集群、Producer 集群、Consumer 集群四部分组成,每个部分都支持多节点扩展,broker 支持主从模式,有同步双写、异步复制两种模式。NameServer 注册中心各节点互相独立,彼此没有通信关系,单台 NameServer 挂掉,不影响其他 NameServer,这一点比 zookeeper 轻量很多。同时 RocketMQ 底层基于 Netty 异步事件驱动通讯框架,采用长连接,具有高性能、高可靠性特点。

2、单机支持上万 Topic 主题,Topic 数量增加对性能影响很小

RocketMQ 是以 Topic 作为消息通道的划分单元,不同的业务使用不同的 Topic 发送和接收消息,这样可以达到物理上划分消息通道资源的目的,这一点对企业服务总线很重要。
而 RocketMQ 单机支持上万 Topic,Topic 的增加对性能影响很小,这一点是 Kafka 欠缺的。

如上图,不同的业务可以划分不同容量的总线通道,例如日志通道可以通过分配更多的 broker 主题方式提高通道传输能力效果。

3、内存模式支持同步请求处理

一般消息中间件适合异步请求处理场景,RocketMQ 的内存模式支持消息不落盘,性能更高,这样也适用于“request-reply”同步请求处理场景。

4、延迟消息优势

RocketMQ 支持延迟消息,消息发送后可指定延迟被消费的时间,例如1小时后被消费,这一特性对于不同系统间数据同步或对账来说非常实用,特别是一些老系统比较多的企业,大量的批处理都是为了这个目的,使用 RocketMQ 消息总线可以很好的治理这个问题,而不用大量使用定时任务。

5、流数据处理

对于日志流数据处理需求,RocketMQ 支持 log4j、logback 等日志异步 appender,对于其他非交易数据处理需求,也可采用异步发送+batch 模式提高数据传输效率。

6、客户端支持多语言,多 JDK 版本,兼容性好

RocketMQ Producer、Consumer 客户端支持 Java, C++, Go 语言,对于 java 语言,支持 JDK1.6 到 1.8,满足目前各企业主流使用需求,适用新旧系统。

通过以上六大特性分析,我们认为 RocketMQ 是目前开源消息中间件中最适合企业服务总线 ESB 的技术方案,因此我们选择使用 RocketMQ 作为连接各个系统区域的边界总线。

弘康人寿微服务边界总线架构图

我们将应用系统的5个区域连接到 RocketMQ 边界总线,这样所有跨区域的数据传输通过总线完成,每个区域(2-5)内部的服务与服务交互仍采用微服务架构。对于区域1属于前置层,直接面向互联网,采用微服务架构的意义不大,故在区域1的每个应用程序上绑定一个 RocketMQ 客户端,负责收消息和发消息,这也得益于 RocketMQ 良好的 JDK 版本支持。

对于区域2-5,每个区域会部署2个以上的 RocketMQ 代理微服务,对区域内部提供收消息和发消息服务,避免过多 MQ 客户端连接到总线,为总线 NameServer 减负。对于一些对于性能要求比较的业务场景,也允许区域内的系统直接客户端方式连接到总线,提高处理效率,但这种情况不多。整体架构达到的最终效果为:

  • 除区域 1 采用传统负载负载均衡方式对终端用户提供服务外,区域 2-5 各个系统均无需使用传统负载均衡,消灭单点问题
  • RocketMQ 集群只是作为一种边界总线,不会与太多的系统连接,我们初步估算一下需要连接到总线的客户端不会超过 100 个,这对 RocketMQ 集群 几乎没有什么压力,所以架构设计上保证了边界总线是轻量级的,同时也保证了其稳定性和处理性能,前面我们讲到在 ESB 那个阶段大多数企业实施到最后阶段都会觉得 ESB 过重,除技术本身问题外,认为 ESB 应该作为所有系统间调用的通道也是一种错误,这无形加重了 ESB 的负担。
  • 遵循“统一边界总线,差异化服务治理”的架构设计思想,各个区域的微服务架构可以不统一,比如区域2可以使用 SpringCloud1.5.x 版本,区域3可以使用 SpringCloud2.x 版本,区域4可以使用 Dubbo,区域5可以使用低成本的 ServiceMesh,只要各个区域内的版本统一即可。
  • 有利于各个区域内的技术升级换代。所有的技术升级换代都是区域性的,随着业务的发展,我们可以不断拆分各个业务区域,这样技术升级风险更小,也更平滑。

最后,回答一下刚开始提出的三个问题:

Q1. 企业服务总线(ESB)是否真的过时了?

A1. 企业服务总线(ESB)采用的核心技术是 MQ 消息中间件,对于点对点服务解耦有不可超越的优势,两个服务点对点需要处理负载均衡、容错、超时等问题,但是通过 ESB 消息管道后这些问题迎刃而解,这是 ESB 最大的魅力,所以我认为 ESB 没有过时,在技术不断进步的今天,各个企业可以尝试搭建自己的轻量级 ESB 边界总线。

Q2. 为什么 RocketMQ 是企业服务总线的最佳技术方案之一?

A2. 结合本文中描述 RocketMQ 六大优势,符合这六点才能满足互联网时代的总线应用要求。

Q3. 如何设计企业微服务架构演进路线图?

  • 首先进行应用架构分区和微服务边界总线规划。
  • 搭建RocketMQ集群,建立统一ESB边界总线服务。
  • 逐个区域实施微服务架构改造,通过消息代理或客户端接入RocketMQ边界总线。

本文作者:舒平,弘康人寿架构部负责人,长期从事保险行业IT服务化治理工作。

原文链接

本文为云栖社区原创内容,未经允许不得转载。

弘康人寿基于 RocketMQ 构建微服务边界总线的实践的更多相关文章

  1. [置顶] Docker学习总结(7)——云端基于Docker的微服务与持续交付实践

    本文根据[2016 全球运维大会•深圳站]现场演讲嘉宾分享内容整理而成 讲师简介 易立 毕业于北京大学,获得学士学位和硕士学位:目前负责阿里云容器技术相关的产品的研发工作. 加入阿里之前,曾在IBM中 ...

  2. 云端基于Docker的微服务与持续交付实践

    云端基于Docker的微服务与持续交付实践笔记,是基于易立老师在阿里巴巴首届在线技术峰会上<云端基于Docker的微服务与持续交付实践>总结而出的. 本次主要讲了什么? Docker Sw ...

  3. ASP.NET Core基于K8S的微服务电商案例实践--学习笔记

    摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...

  4. 基于Istio构建微服务安全加固平台的探索

    简介 An open platform to connect, secure, control and observe services. Istio 是一个由谷歌.IBM 与Lyft共同开发的开源项 ...

  5. 基于Spring Cloud和Netflix OSS构建微服务,Part 2

    在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...

  6. 滴滴出行基于RocketMQ构建企业级消息队列服务的实践

    小结: 1. https://mp.weixin.qq.com/s/v6NM3UgX-qTI7yO1QPCJrw 滴滴出行基于RocketMQ构建企业级消息队列服务的实践 原创: 江海挺 阿里巴巴中间 ...

  7. Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台

    Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台: https://gitee.com/leecho/cola-cloud

  8. 基于 abp vNext 微服务开发的敏捷应用构建平台 - 文章目录

    系列文章: <基于 abp vNext 微服务开发的敏捷应用构建平台 - 设计构想> [点击查看] <基于 abp vNext 微服务开发的敏捷应用构建平台 - 文章目录> [ ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

随机推荐

  1. 新手玩ubuntu(一)终端

    有终端才能行天下事 点击为如下,就可以进行下面的开发了

  2. Intelij Idea 2016破解

    在注册时选择License server,输入http://www.iteblog.com/idea/key.php,点击OK

  3. PAT甲级——A1025 PAT Ranking

    Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhe ...

  4. JavaWeb — Servlet(Server Applet)

    Servlet(Server Applet) 全称Java Servlet,未有中文译文.是用Java编写的服务器端程序.其主要功能在于交互式地浏览和修改数据,生成动态Web内容. 狭义的Servle ...

  5. js+php如何实现上传图片

    近期有一些朋友,在做上传图片这一块的时候进度卡住了.有个朋友说,我已经在这个问题上浪费了一天了. 确实,对于新手而言,上传图片成了比较复杂的的一个事,今天整理了一下常用的两种方式,让新手轻松掌握上传图 ...

  6. (精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)

    Spring的核心框架主要包含两个技术,分别用来处理工厂类,以及事务处理和连接管理的. 两大核心概念 1)  IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过se ...

  7. there is no permission with id `12`

    Laravel 本地环境添加菜单之后, 线上报错, 线上线上用同一个数据库, 原因是缓存问题, 解决方法: php artisan cache:clear 如果缓存有重要数据的, 那就要清除对应的缓存 ...

  8. PHP1.6--数组

    一.数组的键值操作函数 1.array_values() 函数作用是返回数组中所有元素的值,只有一个参数,规定传人给定数组,返回一个包含给定数组中所有值的数组,但不保留键名 被返回的数组将使用顺序的数 ...

  9. h5文件简介

    h5文件是层次格式的第5代版本,用于存储科学数据的一种文件格式和库文件,由美国超级计算中心与应用中心研发的文件格式,用以存储和组织大规模数据. H5将文件结构简化成两个主要的对象类型: 1 数据集da ...

  10. Jdbc封装和对CURD的封装

    1.查询emp表中的所有记录为例 2.测试类 public Emp getByNameAndEmail(String name, String email){ String sql = "s ...