我们团队的后台服务,一开始只有一个大服务,所有的东西都写在里面。可以想象,当这个服务变得越来越庞大时,它会变得多么难以维护。后来,一些数据服务逐渐分离成单独的API服务。在原有的服务中,还是有一些模板渲染,数据聚合,一些耦合的业务逻辑。目前,拆迁还不够干净。我们的目标是希望这个老服务作为一个APIGateway,或者前端的一个中间层。单一职责原则其实是一种很重要的解耦方式。一个服务做好一件事就够了。偶然看到下面这篇文章,虽然只是很简单的介绍,但也让我学到了很多。也分享给大家。客户端阅读原文,在数据传输过程中,一般需要经过一些认证,满足安全要求,才能获得访问微服务架构中服务的权限。不同的服务在认证方面或多或少存在差异。APIGateway就像一个集线器,用来抹平各种服务协议之间的差异,满足对特定客户端的特殊处理。他的存在方便了客户享受各种服务。微服务和消费者微服务适用于团队可以独立设计、开发和运行服务的架构。它允许系统中每个服务的技术多样性,团队可以在合适的场景下使用合适的开发语言、数据库和网络协议。例如,一个团队使用JSON和HTTPREST,而另一个团队可能使用gRPC和HTTP/2或像RabbitMQ这样的消息代理。在某些场景下,使用不同的数据序列化方式和协议可能会受益匪浅,但需要使用我们服务的客户可能会有不同的需求。由于各种客户端的存在,我们需要支持的数据格式也是多种多样的。例如,一个客户端可能希望数据为XML格式,而另一个客户端可能希望数据为JSON格式。另外一个你可能需要面对的问题是,不同的服务之间可能会有一些共同的逻辑(比如授权认证),所以不能在每个服务中都实现,对吧?总结:我们不想在微服务中重复实现一些与支持多客户端相关的通用逻辑。我们需要一个API网关来提供一个中间层来处理服务协议之间的差异,满足特定客户端的需求。什么是API网关API网关是微服务架构中的一种服务,它为客户端提供共享层和API以与内部服务进行通信。API网关可以路由请求、转换协议、聚合数据并实现一些共享逻辑,例如身份验证和速率限制器。你可以把APIGateway看作是享受各种微服务的入口。我们的系统可以有一个或多个API网关,这取决于客户的需求。例如,我们可以为桌面浏览器、移动应用程序和公共API提供单独的网关。面向前端团队的Node.jsAPIGateway由于APIGateway提供了对浏览器等客户端应用的支持,因此可以由负责前端应用的团队来实现和管理。这也意味着API网关实现语言应该由负责客户端的团队来选择。由于JavaScript是开发浏览器应用程序的主要语言,因此即使您的微服务架构是用不同的语言开发的,Node.js也是实现API网关的绝佳选择。Netflix成功使用Node.jsAPI网关及其Java后端来支持广泛的客户端,了解更多。APIGateway的实用性我们之前讨论过可以将常用的共享逻辑放到APIGateway中,本节将介绍其常用的用法。路由和版本控制我们将APIGateway定义为微服务的入口。在您的API网关中,您可以将来自客户端的请求路由到指定的服务。您甚至可以在路由过程中选择服务程序的版本或更改后端接口,而暴露的接口可以保持不变。您还可以将多个微服务聚合到API网关中的一个点。迭代设计API网关可以帮助您分解臃肿的应用程序。由于业务的不断迭代,从头开始将整个应用重写成微服务架构系统似乎不太可行。在这种情况下,我们可以在我们的单体应用程序前面放置一个代理或API网关,并将新功能实现为微服务,只需确保API网关可以将新接口路由到新服务,同时确保旧接口仍然可以访问。慢慢的我们不得不将这些老旧的服务迁移到微服务中来达到分解臃肿应用的目的。通过小步迭代设计,我们可以从一个巨大的单体架构平滑过渡到微服务架构。身份验证大多数微服务在使用前都需要身份验证。将身份验证等共享逻辑放在API网关上可以让您的微服务更加专注。在微服务架构中,可以通过网络配置将服务置于DMZ(隔离区),通过APIGateway暴露给客户端。网关还可以处理多种认证方式,例如可以支持基于cookie和基于token的认证。数据聚合在微服务架构中,客户端可能需要不同程度聚合的数据。在这种情况下,我们可以使用API网关来解决这些依赖关系,并从多个服务中收集数据。当不同的客户端需要不同格式的数据时,就会出现序列化格式转换的问题。试想一下,如果我们在微服务中使用JSON,但在某个客户端只支持XMLAPI,这时候我们该怎么办?我们可以把JSON转XML的过程放在APIGateway中,而不是在每个微服务中实现。协议转换微服务架构允许使用不同的协议以获得使用不同技术的优势。然而,大多数客户端只支持一种协议。在这种情况下,我们需要转换客户端的服务协议。API网关也可以是客户端和微服务之间的协议转换层。在下图中,大家可以看到客户端只是通过HTTPREST与各种服务交换信息,但实际上我们内部的各种微服务是可以根据不同的规范和协议来传递信息的。速率控制和缓存除了身份验证,您还可以在API网关中实现速率限制、缓存和各种与可靠性相关的功能。在实现过大的API网关时,应避免将非通用逻辑(如特定领域的数据转换)放入其中。服务应该始终拥有其数据域的完全所有权。构建一个太大而无法与服务团队争夺控制权的API网关违反了微服务的理念。这就是为什么你应该注意你的API网关中的数据聚合——如果你明确它的职责,它会非常强大,你应该避免在API网关中处理业务逻辑,无论谁来做,一定要明确它在整体架构中的作用.Node.js网关如果你想在API网关中执行简单的操作,比如将请求路由到特定的服务,你可以使用像nginx这样的反向代理。但在某些时候,您可能需要实现通用代理不支持的逻辑。在这种情况下,您可以在Node.js中实现自己的API网关。在Node.js中,可以使用http-proxy完成一些简单的代理请求服务,当然也可以使用功能更多的express-gateway。在第一个API网关示例中,我们在将请求代理到实际服务之前进行了身份验证。constexpress=require('express')consthttpProxy=require('express-http-proxy')constapp=express()constuserServiceProxy=httpProxy('https://user-service')//Authenticationapp.use((req,res,next)=>{//TODO:我的身份验证逻辑next()})//代理请求app.get('/users/:userId',(req,res,next)=>{userServiceProxy(req,res,next)})另一种方式是通过API网关向微服务发送请求,然后将响应返回给客户端:constexpress=require('express')constrequest=require('request-promise-native')constapp=express()//Resolve:GET/users/meapp.get('/users/me',async(req,res)=>{constuserId=req.session.userIdconsturi=`https://user-service/users/${userId}`constuser=awaitrequest(uri)res.json(user)})总结:APIGateway提供了一个中间层来协调客户端和微服务架构。它帮助我们践行单一职责原则,让我们的应用或服务持续专注于一件事。可以将常用的逻辑放到APIGateway中,但也要注意不要过度使用API??Gateway。
