您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

时间:2021-06-29 09:54:35  来源:  作者:java领路人

微服务的核心组件

微服务的架构设计之前总结过,微服务的思想是分离,微服务模式下将应用程序拆分为不同的微小服务,通过使用或者组合不同的服务来完成不同的业务功能。那么一旦分离后再组合,就意味着服务之间一定会存在相互调用的过程,在前面微服务的定义中提到过,微服务之间都使用粗糙的通信机制,它一定是轻量级的,而且是可以支持跨语言调用的,包括微服务本身对客户端提供服务也是采用这种机制的。因此,设计并实现适合的通信组件来提供远程调用的能力是微服务架构的核心。下面来了解微服务的远程调用方式。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

微服务的远程调用方式

微服务架构中常用的调用方式有两种:一种是通过异步的消息交换来通信,这里服务调用双方一般使用一些中间件,如RabbitMQ、Kafka等;另一种是通过HTTP的资源接口,通过JSON作为信息载体的格式,即REST API的方式进行远程通信。

1. 异步消息通信

先来看一下异步消息是如何通信的,这里以RabbitMQ的工作原理为例,如图2.6所示。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

首先消息由生产者发送到一个统一的交换中心(又称交易所),交换中心根据一定的转发规则(如直接、主题匹配、扇出等方式),将消息转发到对应的队列中,然后通过消息队列最终将消息传递给消费者。消费者可以选择只订阅自己关心的消息。

可以利用消息机制来做很多事情,如可以做一个简单的任务队列,也可以去订阅和发布消息。当然,订阅和发布的方式有很多,最常见的就是图2.7RabbitMQ远程调用工作原理中描述的定向转发和Topic机制,这里对消息机制的原理不做阐述,利用这种发布和订阅的工作方式,我们可以通过消息做到服务的远程调用。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

但是,在微服务中这并不是常见的用法,因为本身消息机制的实现会依赖相关的中间件或框架,服务调用双方都需要集成相同的消息服务或技术框架,这本身就会加重微服务架构的通信方式,而且过度松散异步的操作也为代码带来了一定的复杂度。所以,在微服务中最常见的通信还是基于HTTP的REST API。

2. REST API

REST(Representational State Transfer,表述性状态转移)用来描述创建HTTP API的标准方法,REST API的核心概念是资源,对于资源有4种常见的行为:查看、创建、编辑和删除,都可以直接映射到HTTP中已实现的GET、POST、PUT和DELETE方法。REST本身并没有创造新的技术、组件或服务,只是正确地使用Web的现有特征和能力,更好地使用现有Web标准中的一些准则和约束。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

如果一个架构符合REST的约束条件和原则,就称它为RESTful架构,当然理论上REST架构风格并不是绑定在HTTP上的,只不过目前HTTP是唯一与REST相关的实现,所以一般情况下REST API都是表示基于HTTP的RESTful接口。

既然是一种标准、一种架构风格,就必然会有它的相关概念和设计原则。表2.1所示为REST API中的一些重要术语。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

同时,REST API也有很多设计原则,如URL中永远不能包含动词,那么URL如何表示自己的行为呢?前面提到过4种常见的行为(查看、创建、编辑和删除)映射到HTTP中已实现的方法中,具体如下。

(1)GET(查看):从服务器或资源列表中检索特定资源。

(2)POST(创建):在服务器上创建一个新资源。

(3)PUT(编辑):更新服务器上的资源,提供整个资源。

(4)PATCH(编辑):更新服务器上的资源,仅提供已更改的属性。

(5)DELETE(删除):从服务器中删除资源。


 

下面两个不是很常用。

(1)HEAD(查看):检索有关资源的元数据,如数据的哈希值或上次更新的时间。

(2)OPTIONS(查看):检索有关允许消费者使用资源的信息。客户端和服务端的交互是无状态的,GET请求通常是可以被缓存的,资源使用复数,URL中可以有表述版本的信息,举例如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

按照顺序对应的含义如下。

(1)使用2.0版本的接口,创建一个产品。

(2)使用2.0版本的接口,根据ID查看产品信息。

(3)使用1.0版本的接口,根据ID全量更新产品信息。

(4)使用1.0版本的接口,根据ID部分更新产品信息。

(5)使用1.0版本的接口,根据ID删除产品。

RESTful的接口还有很多设计原则,这里不再赘述,感兴趣的读者可以查阅相关资料进行学习,在微服务中使用的HTTP通信协议就是采用的RESTful的接口设计,所以熟练掌握REST API的设计用法在微服务架构中是十分重要的。

HTTP通信方法

一般在项目中采用什么技术来完成HTTP通信?在一些早期的项目中,可以看到Apache HttpComponents的身影,它的功能也十分强大,但是在使用时,需要编写大量的基础代码,往往还需要进行二次封装,而在如今Spring Boot盛行的时代,大家更热衷于现取现用,正所谓约定大于配置,所有的基础工作都按照一定的约定交由框架来完成。下面以Spring为例,主要介绍RestTemplate和WebClient两种方式进行HTTP的通信。

1. RestTemplateRestTemplate是Spring Web中提供的用于在客户端完成同步的HTTP请求的核心类,大大简化了与HTTP服务器的通信,并实现了RESTful的设计原则。RestTemplate默认采用JDK原生的HTTP连接工具实现,当然也可以切换库,如Apache HttpComponents、Netty和OKHttp等第三方的HTTP库。我们以默认的实现为例,首先需要声明一个RestTemplate,这里采用Spring Boot的注解式声明方式,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

当然,还可以给它初始化一些公共属性,如URL、用户名密码,或者一些连接超时等设置,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

完成 RestTemplate 的声明之后就可以使用它了 , 之前说过RestTemplate实现了RESTful的设计原则,所以RestTemplate提供了便捷的方法去实现HTTP的GET、POST、PUT、PATCH和DELETE方法。例如,getForEntity()就是以GET的方式发送HTTP请求,而postForEntity()则 是 以 POST 的 方 式 发 送 HTTP 请 求 。 当 然 , 还 有 其 他 实 现 , 如patchForObject()、put()、delete()和optionsForAllow()等方法,这里就不一一介绍了。下面以GET和POST两种最常见的方式来介绍RestTemplate的用法,其他的大同小异。

(1)RestTemplate的GET方法。

RestTemplate提供了getForObject和getForEntity两种方式发送GET的HTTP请求,其中getForObject方法可以直接将响应的Body转换为指定的类型,方法定义如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

其中,第一个方法比较常用,按照顺序传递URL的参数,通过在URL中定义{}来表示参数的站位,{}中可以写具体含义的单词,也可以写数字,如{0},代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

此外,getForObject还提供了另外两种重载方法,分别提供了通过Map传递参数和没有参数两种功能。没有参数很好理解,不再赘述,下面的代码展示了通过Map传递参数的方式。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

不难看出,Map中的key对应着URL中{}里的单词,使用Map的不足之处是当参数太多时,顺序容易弄错,而且方法会写得很长,不易读,也不易维护。getForObject方法能满足我们大部分的需求,但有时可能需要获取除Body之外的信息,如响应头、响应状态码等,这时就需要getForEntity了,getForEntity和getForObject一样,提供了3种实现,方法定义如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

可以发现,getForEntity的方法参数和getForObject的一样,唯一的区别是getForEntity的返回类型是ResponseEntity。这里不再对每个方法进行详细介绍了,下面还是以第一个方法为例,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

(2)RestTemplate的POST方法。

与GET的方式一样,POST也提供了postForObject和postForEntity两种方式来完成POST的HTTP请求。方法定义如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

POST的6个方法定义与GET几乎一样,所以这里没有把方法说明粘贴进来,仔细观察可以发现,POST的方法多了一个request的参数,这个参数会被放进请求的Body中,当没有需要时也可以传入null,举例如下:

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

关于RestTemplate的其他方法就不再列举了,感兴趣的读者可以查看Spring Web库的源码,或者访问Spring的官网查阅相关教程。

2. WebClient

WebClient相比RestTemplate是一个较新的HTTP访问方式,之前提到过,RestTemplate是一个同步的请求方式,当请求发出后,当前线程会等待,直到有响应后才会继续执行后续代码。其实远程调用是一个可以异步的过程,在等待请求响应时,我们完全可以做其他的事情,所以RestTemplate在一些性能要求比较高的地方使用就显得不是那么合适了。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

这时就需要使用可以异步完成请求的WebClient了,当然,我们可以仍然使用RestTemplate,然后通过线程池或CompletableFuture等方式创建新的线程来执行RestTemplate的请求而不阻塞当前线程的执行。不过这样做不是特别优雅,而且每次还需要自行维护关于创建不同线程的代码。

随着JAVAScript的Reactive设计理念越来越流行,不少语言和框架开始相继模仿。Spring也采用了“No blocking”(无阻塞)的方式,推出了Spring WebFlux,关于WebFlux的功能有很多,这里主要来看一下WebFlux中WebClient的用法。

相比RestTemplate,WebClient最大的优势就是可以使用Reactive的方式执行非阻塞的HTTP请求,即异步的请求服务端。WebClient同样实现了RESTful的设计原则,支持GET、POST、PUT、PATCH和DELETE等操作,而且写法更接近于流式,示例代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

这是一个GET方法,代码很好理解,只不过是流式的写法,先定义HTTP的方法,然后定义URI,最后定义返回类型。再来看一个POST的例子,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

很显然,相比GET方法多一个syncBody 方法,类似于RestTemplate的request参数,这个方法会把该参数当作请求的Body发送到服务端。仔细观察可以发现,与RestTemplate相比有一个最大的不同,就是方法的返回值变成了Mono类型,其实除了Mono类型,WebFlux还提供了Flux类型,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

首先通过代码可以发现,Mono和Flux的区别在于前者是单个元素,后者是集合,当然这不是最关键的,Mono中也可以是一个集合,如Mono<List<User>>、Mono和Flux之间可以相互转换。关键在于WebClient是异步的请求,在调用它时得到的返回类型不可能是直接的期待返回的类型,如findAllUsers得到的不是List<User>类型,而是Flux<User>类型。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

这就好比我们通过CompletableFuture创建了一个线程A,然后在执行时会立刻返回一个CompletableFuture类型的对象,这时主线程就不会阻塞,而是继续执行。当我们需要得到返回值时,可以通过CompletableFuture的join方法,将线程A加入当前线程,这时如果线程A已经执行完成,那么当前线程就会立刻得到线程A的执行结果,如果线程A还没有执行完,那么当前线程就会等待,直到线程A执行完成。这是一个典型的异步执行方法的例子,而WebClient的Mono和Flux就和CompletableFuture具有相同的作用,而且更加强大。

例如,可以提前定义对返回数据的操作,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

再如,可以打包合并多个Mono或Flux,然后只执行一次join,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法

 

可以看到,Mono提供了类似join的方法:block。如果你更喜欢使用 CompletableFuture , Mono 和 Flux 也可以轻松地转换成CompletableFuture,代码如下。

微服务你得知道这些!从核心组件到远程调用方式以及HTTP通信方法


Tags:微服务   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  Tags: 微服务  点击:(8)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  Tags: 微服务  点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  Tags: 微服务  点击:(35)  评论:(0)  加入收藏
实施微服务架构,我们一直在遵循一个实践原则:每个微服务要有自己独立的数据库,避免数据库层面的耦合。这种理所当然感觉好像不需要多加思考,就是应该这样做; 图片来源:James Lewi...【详细内容】
2021-10-11  Tags: 微服务  点击:(42)  评论:(0)  加入收藏
在今年的NGINX Sprint 2.0虚拟大会上,NGINX(来自流行的开源web服务器/负载均衡器和反向代理背后的公司F5),发布了NGINX现代应用参考架构(MARA)。该公司在一篇博客文章中说,这将帮...【详细内容】
2021-09-26  Tags: 微服务  点击:(60)  评论:(0)  加入收藏
今天,字节跳动正式宣布开源 CloudWeGo。这是一套以 Go 语言为核心、专注于微服务通信与治理的中间件集合,具有高性能、可扩展、高可靠的特点。项目地址:https://github.com/clo...【详细内容】
2021-09-08  Tags: 微服务  点击:(92)  评论:(0)  加入收藏
1. Spring Boot 与 Spring Cloud Spring Boot 是用于编写微服务的 Java 基础框架。在Spring Cloud 提供了各种构建全栈微服务的功能。构建小型和大型系统都适合。由于控制反...【详细内容】
2021-08-31  Tags: 微服务  点击:(162)  评论:(0)  加入收藏
现有问题在 EFK 日志收集 篇中,我们讲解了如何利用 EFK 收集 Kubernetes 集群日志。但是,还存在如下问题。 Elasticsearch 以单节点的形式部署,不能满足生产环境的要求 Fluentd...【详细内容】
2021-08-13  Tags: 微服务  点击:(102)  评论:(0)  加入收藏
在 Java 和 Kotlin 中, 除了使用Spring Boot创建微服务外,还有很多其他的替代方案。 名称 版本 发布时间 开发商 GitHub ...【详细内容】
2021-08-06  Tags: 微服务  点击:(173)  评论:(0)  加入收藏
一、微服务的现状及未来1.服务架构的演变1.1 单体架构&emsp;&emsp;单体架构应该是我们最先接触到的架构实现了,在单体架构中使用经典的三层模型,即表现层,业务逻辑层和数据访问...【详细内容】
2021-07-22  Tags: 微服务  点击:(125)  评论:(0)  加入收藏
▌简易百科推荐
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(3)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(7)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(10)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(8)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(20)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(16)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(23)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  大数据架构师    Tags:Netty   点击:(16)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  人月聊IT    Tags:架构   点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  GreekDataGuy  CSDN  Tags:单体应用   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条