微服务实现 - 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 条评论
登录 后参与评论

相关文章

来自专栏安恒信息

安全漏洞公告

1 IBM WebSphere Portal WEB内容管理程序信息泄露漏洞 IBM WebSphere Portal WEB内容管理程序信息泄露漏洞发布时...

29412
来自专栏nummy

flume简介

Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同...

982
来自专栏腾讯移动品质中心TMQ的专栏

【腾讯TMQ】移动H5性能测试平台解决方案

说到H5性能测试,大家想到最多的是在PC端利用Firebug、Fiddle和HttpWatch等工具进行测试和性能指标的分析,但是如果我们测试的是Android...

9320
来自专栏逸鹏说道

基于GRPC+consul通信的服务化框架

—.背景 谈论服务化框架的时候,我们首先先了解这些概念:SOA、ESB、OSGi、servicemix、微服务、Spring Boot ...

4915
来自专栏码神联盟

碎片化 | 第一阶段-03-Java语言环境搭建-视频

如清晰度低,可转PC网页观看高清版本: http://v.qq.com/x/page/v0565h4wpb6.html ---- 什么是jre、什么是JDK。...

37311
来自专栏CSDN技术头条

15个最受欢迎的Python开源框架

本文从GitHub中整理出15个最受欢迎的Python开源框架。这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等。 Django: P...

2978
来自专栏小巫技术博客

Android自动化构建之Ant多渠道打包实践(下)

702
来自专栏IT技术精选文摘

使用API网关构建微服务

当您选择将应用程序构建为一组微服务时,您需要确定应用程序的客户端将如何与微服务器进行交互。使用单体应用程序,只有一组(通常是复制的,负载均衡的)端点。然而,在微...

3808
来自专栏主机笔记

Windows2012搭建我的世界(Minecraft)服务器超简单

有台qq云的服务器一直在挂机没事干,使用Windows2012系统搭建我的世界服务端,傻瓜式安装简单快速,亲测试可以玩。 0.安装环境 服务器配置:2核2G1M...

9069
来自专栏纯洁的微笑

构建高可用网关之容错实践

自从微服务概念以来,众多的软件架构在践行着这一优秀的设计理念。各自的系统在这一指导思想下收获了优雅的可维护性,但一方面也给接口调用提出了新的要求。比如众多的AP...

3967

扫码关注云+社区