微服务实现 - Netflix技术栈

微服务实现 - Netflix技术栈

你好。今天我将讨论并解释如何实现基于微服务的系统。有很多用于实现微服务的工具和技术。我今天关注的是Netflix技术栈和SpringBoot。目前微服务是业内热门话题之一。每个人都需要了解微服务,每个人都需要在微服务体系结构上完成项目。

在实践微服务之前,我们必须清楚微服务体系结构的概念,为什么我们的项目需要微服务,在微服务体系结构中有什么优点和缺点。在这里, Krish正在做关于微服务的很好的系列教程。如果您想深入了解微服务架构,请在开始实施前仔细阅读这些教程。

主要议题

  1. 示例项目简介
  2. 核心服务
  3. 发现服务器
  4. 发现客户端
  5. 客户端负载平衡器
  6. API网关
  7. 安全流程
  8. 服务弹性和容错
  9. 无状态服务器
  10. 公共类库

示例项目简介

首先我将解释系统的高层体系结构,以了解我们要做什么。这只是一个便于解释的示例应用程序。只是一个假想的基于电子商务的Web应用程序。所有这些系统设计和实施说明都是基于我以前的项目经验。有时候您的系统设计可能会根据您的要求而有所不同。

核心服务

根据微服务架构,您可以在这里看到我们将整个应用程序划分为不同的服务。每种服务都是可销售的,可以独立部署,并且具有精确定义的范围。这些服务被构建为SpringBoot项目。我将在本文末尾提供源代码项目。所以,尝试理解这个概念,而不要担心代码。在这个例子中,我们有五个核心服务。

身份验证服务负责处理系统的认证过程,授权用户检索,和授权用户存储。它与用户,角色,权限数据库表连接。我在这里使用了MongoDB。

商品服务服务负责商品存储,商品列表等库存处理的流程。

订单服务负责处理买家为商品安排的订单。然后卖方处理为其商品获得的订单。

消息服务负责在系统内处理个每用户之间的实时消息。

搜索服务负责搜索产品,用户,类别。在这些类型的应用程序中,搜索是最苛刻的操作,因此在此我使用RedisSearchBox来提供高性能服务。但这只是一个示例项目,您可以选择任何适合的技术。

发现服务器

在上一节中,我们讨论了我们系统的核心服务。那些是独立的服务。其中一些部署在单台服务器机器中,或者其他部署可能部署另一台服务器机器。在某些情况下,某些服务需要与其他服务进行通信,稍后我会解释这些情况。但是如果我们不知道它的位置在哪里,我们如何与其他服务进行通信。这就像我们正试图打电话给某人而不知道他的电话号码。

解决方案是发现服务器。发现服务器有助于发现我们需要的服务。当某些服务需要访问其他服务时, 发现服务器提供所请求服务的所有端点详细信息以建立连接。发现服务器充当服务注册表。所有的服务都需要在发现服务器上注册,其他聪明的发现服务器也不知道该服务。发现服务器有多个实现: Netflix Eureka, Consul, Zookeeper。在这里, 我将讨论 Netflix Eureka。

我们可以轻松地将Netflix Eureka设置为我们的发现服务器。我不打算在这里深入每一段代码,我关注重要的配置和实施点。你可以在源项目中找到它。为了使Springboot应用程序成为Eureka Discovery服务器,您必须将@EnableEurekaServer注释放入应用程序的启动(main方法)中来提及它。

你必须进行一些配置。在这种情况下,我配置到内置的application.yml(或者你可以使用application.properties

在这里我注明这个实例不是一个Discovery客户端,在这里服务器的端口是从maven属性获得的。但是你可以放任何你需要的端口号。默认端口是1111。

发现客户端

在服务发现部分,我告诉每个服务都必须在发现服务器上注册。因此,我们必须使用@EnableDiscoveryClient将每项服务标为Discovery客户端这个注解可以与在您的项目中实施的任何发现客户端实施(Eureka,Consul,Zookeeper)一起使用您也可以使用@EnableEurekaClient注解,但它仅适用于Eureka的发现客户端实现

你必须进行一些配置。

在这里你必须配置spring.application.name。因为该名称将是其他人用来访问此服务的Service-Id

我需要指出的其他事情,我们可以通过使用相同的Service-Id根据对服务的需求保持服务的集群。实际上,Eureka服务器通过使用Instance-Id保留了他的发现客户端的踪迹有人可以通过提供服务ID来请求Eureka获得特定服务的所有端点。然后,Eureka能够提供该服务客户端的所有服务端点列表。

Instance - Id =  { Server - Host }  +  ':'  { Service - Id }  +  ':'  +  { Server - Port }

你可以看到有一些简单的配置。你必须通过使用defaultZone属性来标明Eureka服务器的位置借助leaseRenewalIntervalInSeconds,您可以更改注册时间。注册需要30秒,因为这是默认的客户端刷新时间。

客户端负载平衡器

我已经告诉过你,在某些情况下,某些服务需要从其他服务获取服务或数据。在这种情况下,一个服务将成为另一个服务的客户。客户服务(client-server)可以使用Service-Id调用所需的服务。但假设所需的服务组成了集群。然后Eureka为所请求的服务提供所有的端点。现在,客户端服务如何决定哪个端点需要选择来建立连接。这是客户端负载平衡器入场的时间。

根据负载均衡算法,客户端负载均衡器将从列表中选择最佳端点来建立连接。在我们的案例中,我使用Netflix Ribbon作为客户端负载均衡器。

根据您的要求,您可以选择最佳的负载平衡算法。在Ribbon中有几个实现。简单循环负载均衡(Simple Round Robin LB),加权响应时间负载均衡(Weighted Response Time LB),区域感知循环均衡(Zone Aware Round Robin LB)和随机负载均衡(Random LB)。 或者你可以实现你自己的负载均衡实现。默认的是简单循环。

Spring框架为访问REST端点提供了使用RestTemplate类的简单的方法。

在使用RestTemplate之前,您必须在spring上下文中创建实例。@LoadBalanced注解将有助于将Ribbon配置设置到RestTemplate中。这是如何通过使用RestTemplate访问另一项服务。

我希望你现在知道我们如何通过使用Ribbon和Eureka来进行服务间通信。

API网关

现在我们要实现系统的入口。外部用户(Web应用程序,移动应用程序)如何访问我们的服务,或者换句话说,我们如何为外部用户公开微服务。是的,解决方案是API网关。系统的外部用户通过API网关访问我们的核心服务。在这里我们使用Netflix Zuul API网关。我们可以使用Zuul作为代理和请求过滤器。我将通过查看配置来解释更多细节。

您可以在这里看到,我们必须提及Eureka服务器的细节,就像我们在Discovery Client部分中所做的一样。原因是当请求进入Zuul时,它将通过使用Service-Id访问特定的核心服务。就像以前我们做的一样。我们不需要担心客户端负载平衡,Zuul通过使用功能区进行负载平衡。

在Zuul属性的另一边,我们可以注明URL前缀是什么。在路由属性部分,我们必须标明每个核心服务具有相同的名称。在里面我们可以标明访问核心服务的url路径。最后,我们必须标明特定服务的Service-Id。

例如,如果外部用户需要访问核心的商品服务。他请求的端点URL可能与这些结构类似。假设Zuul在8080上运行。

http://localhost:8080/api/product-service/{ core-product-service-end-point }

http://localhost:8080/api/product-service/products

http://localhost:8080/api/product-service/products/10

安全流程

在本节中,我将讨论我们的应用程序中安全处理的方式。为此,我主要使用JWT(JSON Web Token)和Spring Security。

登录

您可以在这里看到登录请求进入auth服务。让我们看看auth令牌(auth-token)是如何生成的。

header = {"alg": "HS256", "typ": "JWT"}
payload = {
              "exp": "2017-08-09 12:00:00",
              "user_name": "user",
              "authorities": [
                   "ROLE_SELLER"
               ],
               ...
              }
secret_key = "quebic_secret"
Token = HMAC( base64(header) + "." + base64(payload) , secret_key)

服务检查用户名和密码是有效的,如果证书正确,auth-service会创建有效负载。有效负载包含用户名,权限和令牌到期时间。密钥存储在每个服务的配置(application.yml)中。

在另一边的jwt配置中,我们可以设置包含auth-token的请求头是什么。为此我们使用Authorization标头。并且您可以根据您的要求更改密码和到期时间。在这种情况下,web-app将生成的auth令牌存储在浏览器存储中。

授权

根据我们的示例项目,商品存储操作仅适用于卖家(USER_SELLER)。您可以在这里看到网络应用程序发送产品服务的新产品详细信息。

product_service不知道任何关于传入用户的信息,所以他要求auth-service获取auth-object。auth-service能够解密auth令牌,如果token是有效的auth-service返回auth-object。auth-object包含userId,用户名和权限。现在根据授权的的商品服务将继续这个过程。

在这里您了解我们安全流程的主要要点。首先,我们的核心服务不去维护关于日志用户的会话。所有的服务都是无状态的。第二件事是商品服务,订单服务,消息服务和搜索服务委托认证服务进行认证过程。获得auth对象后,他们可以处理授权过程,因为每个核心服务都包含使用Spring Security实现的权限规则。

身份验证委派过滤器(Authentication Delegating Filter)

CommonAuthenticationTokenFilter是Authentication Delegating的实现。这包含在我们的common-lib依赖中。您可以在com.quebic.common.security包中找到此过滤器类。通过覆盖OncePerRequestFilter类的doFilterInternal()方法,我实现了Auth委托逻辑。

使用Spring Security进行授权

您可以从WebSecurityConfig类中找到授权规则。每个服务都包含它自己的实现,这个类位于security.config包下。

登出

当以无状态进行时,不可能在授权令牌过期之前使授权令牌失效。所以当退出时,从客户端扔掉令牌。作为一个例子,如果客户端是一个Web应用程序,我们可以从浏览器存储中释放auth令牌。

服务弹性和容错

当我们设计基于微服务的项目时,我们必须考虑服务弹性和容错机制的实现。有几种方法可以实现这一点,断路器模式是处理这个问题的好方法。Netflix Hystrix是电路断路器模式的一个实现。

如果readList()方法在其执行过程中失败,则后退方法将立即触发而不会中断主进程。

无状态服务器

正如我在前面提到的,所有核心服务都必须是可销售的,并且可以独立部署。根据需求,我们可以保留来自同一服务的多个实例。但是如果我们保持基于服务器的会话,那么当我们部署新实例时,我们必须共享这些会话数据,它将杀死微服务架构的自由。所以所有的服务都被设计成无状态服务器。

不要将会话数据或缓存保存在服务器内存中,将它们存储在分布式内存中。有很多很好的解决方案。例如:Hazelcast,Redis,Memcache。

公共类库

如果您对所有服务都有共同点,请不要在每个服务中复制它。把这些放在公共场所。在这个例子中,我保存了一个名为common-lib的独立项目。每个核心服务都必须添加common-lib作为依赖项。

好吧,现在我们来到了讨论的最后。我认为你对微服务架构的实现有相当的了解。我希望这将有助于您未来的项目。这是GitHub源代码项目,请按照我在README中给出的说明运行该项目。您可以将微服务托管在AWS EC2,Pivotal WebServices或heroku中。我将在以后的文章中解释更多关于托管的内容。谢谢阅读。祝你好运。

本文的版权归 ★忆先★ 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

推荐-zabbix原理篇(1)

snmp介绍 介绍zabbix 之前让我们先来熟悉一下什么是snmp? SNMP:Simple Network Management Protoclol 翻译一...

2785
来自专栏张善友的专栏

VSTS知识整理

原文:http://www.qddn.net/blogs/xumingxsh/archive/2006/01/19/4513.aspx 学习VSTS有一段时间,...

3265
来自专栏张善友的专栏

开放式管理基础结构 OMI

Windows 长久以来在 CIM 实施领域一直傲立桥头,而这一切都是从 WMI(Windows 管理基础结构)开始的。分布式管理任务组 (DMTF) 通用信息...

1898
来自专栏IMWeb前端团队

基于MQTT的实时日志系统

MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网...

26310
来自专栏Spark学习技巧

Spark源码系列之Standalone模式下Spark应用的整个启动过程

一,Standalone模式下的spark角色 大家都知道在Standalone模式下,spark一共有以下五种角色: sparksubmit,maste...

1927
来自专栏架构师之路

php使用tcp长连接的一种优化思路

一、面向人群 如果站点架构满足以下几点,那么本文的优化方案会非常适合: 1)使用php等脚本语言作为开发语言 2)需要连接后端服务,例如RPC服务、memcac...

2656
来自专栏纯洁的微笑

springcloud(十):服务网关zuul初级篇

前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud...

2888
来自专栏架构师小秘圈

那些年不加班的开发团队的秘密,原因竟是因为持续集成!

持续集成,让很多开发团队又 「 爱 」 又 「 恨 」 。爱,在于整个流程对项目的交付价值大有裨益,尽最大可能地减少不必要的加班;恨,在于成本过大,部署的困难、...

3885
来自专栏DevOps时代的专栏

60 个最棒的 DevOps 开源工具

你喜欢免费的东西吗?获得开发者社区支持的自动化,开源的工具是大家梦寐以求的。这里列举了 60+ 款最棒的开源工具,可以帮助你很好的实行 DevOps。

1373
来自专栏DevOps时代的专栏

这些工具都没用过?还谈什么 DevOps

导语: DevOps 越来越流行,越来越成为加快产品研发速度、提升团队效率的有效工具。现在,在开发、测试、部署、交付、维护以及监控分析等工作中,有越来越多的开源...

37115

扫码关注云+社区