利用Java上手微服务架构

做者: Alexsandro Souza​git

几乎每一个人都在关注微服务架构,咱们也不例外。做为一个与时俱进的程序员,我一直在努力了解这一架构,但愿寻找一种经过Spring在Java中实现微服务架构的方法。程序员

咱们公司虽然很棒,但技术堆栈略显过期,至今尚未使用Java 8或微服务,所以我须要从外部了解更多关于微服务架构的经验和方法。我决定经过建立一个“to-do system”项目来梳理经验以供未来参考。github

概览

本文的目标是为不一样的微服务提供源代码walkthrough,所以我不打算深刻概念和工具,而是提出一个包含用于开发微服务的模式、工具、技术的应用示例。spring

“to-do system”将由8个应用组成:数据库

  • Reminder设计模式

  • User安全

  • Service Discovery System服务器

  • Mailer架构

  • OAuth Server并发

  • System Integration Test

  • API Gateway

  • Web Application Client

系统如何工做

上图未系统与微服务的交互。用户访问Angular2编写的应用,该应用连接OAuth Authorization server,经过OAuth Authorization server分配用户和权限。此server将返回一个Jason Web Token,其中包含有关客户端及其权限的信息以及格式的范围。当用户认证经过并拥有token以后,Web应用能够与API Gateway通讯。API Gateway将利用JWT验证请求是否来自受权server,然后调用微服务并构建响应。

OAuth server经过User service获取用户权鉴细节,API Gateway从OAuth server获取用户信息。

Reminder service是安置ToDo功能的地方,ToDo服务按计划检查reminders并经过电子邮件通知用户,电子邮件由Mail service发送,该事件由使用Kafka的事件提醒服务触发。

System Integration Test是负责联络Reminder Service endpoints的Java应用。

链接微服务

在微服务架构中,咱们须要处理许多在不一样IP和端口上运行的微服务。所以有必要找到一种无需硬编码的方式来管理每一个地址。

Netflix Eureka是一种很好的解决方案,做为客户端服务发现,Eureka容许服务自动查找和相互通讯。咱们有必要理解eureka的工做原理,一边了解REST服务在不一样微服务之间的通讯。利用eureka来管理服务运行位置,咱们能够添加instance,并经过负载均衡实如今微服务之间分配incoming application traffic。】

在咱们的系统中,使用Netflix Ribbon做为客户端负载均衡器,实现容错并经过冗余增长可靠性和可用性。咱们使用Netflix Feign编写声明性REST客户端,并集成Ribbon和Eureka来提供负载平衡HTTP客户端。

咱们正在使用Netflix Hystrix断路器将咱们的应用程序与依赖性故障隔离开来。它有助于阻止cascading failure,并容许咱们快速恢复或添加fallbacks。Hystrix为每一个依赖关系提供一个thread-pool。当thread-pool耗尽,hystrix将拒绝请求。Hystrix同时提供断路器功能,能够中止对依赖关系的全部请求,在请求失败、拒绝或超时时,还能够实现备用逻辑。

Authentication

对于任何系统来讲,安全性都是很是重要的,微服务架构也同样。咱们经过OAuth2来保持微服务的安全性。OAuth2做为一项知名Authorization,早已普遍应用于Google,Facebook和Github。

在咱们的这个项目中,同时还应用了Spring Security,并在安全问题上增长了一个元素:JSON Web Token(JWT)。

若是咱们仅使用OAuth,咱们将须要一个OAuth受权服务器来验证用户,生成令牌并充当资源服务器的endpoints,询问该令牌是否有效以及受权的权限。与Authorization Server相比,这须要两倍的请求。而JWT提供了一种在access token中传输权限和用户数据的简单方法。一旦全部数据都已经存在于token string中,资源服务器就不须要再请求令牌检查。全部信息都被序列化为JSON,用base64编码,最后用私有RSA密钥签名。它假设全部资源服务器都将有一个公钥,以检查令牌是否为适当的私钥签名,并对令牌进行反序列化以获取信息。

REST

在咱们的系统中,咱们有两种交互方式:同步和异步。对于异步风格,咱们使用分布式事件与Kafka,遵循模型发布/订阅。对于同步,咱们有支持JSON和XML的REST风格。

对于RESTful,有四个成熟级别。咱们的微服务处于2级,为了简单起见,我决定不使用HATEOAS设计模式实现超媒体控件。

由于咱们正在使用Spring Cloud,因此咱们要“out-of-box“一些可扩展性模式,把它们放在HTTP链接中,如断路器、bulkhead、负载均衡、链接池、超时和重试。

分布式事件

如上所述,咱们经过使用Kafka将Reminder服务和Mailer服务之间的通讯异步地与其余微服务进行通讯。在Reminder中,咱们有一个计划任务来检查提醒时间并发布RemainderFound事件。Mailer服务中将会有一个订阅的事件,它将开始向用户发送电子邮件的过程。我邀请您看看咱们如何进行这种整合,以及我如何在Kafka事件模块中写入发送到Kafka的数据的序列化/反序列化。

Event sourcing及CQRS

一体化应用通畅具备单个关系数据库。咱们可使用ACID transaction。所以,若是出现问题,咱们的应用程序能够简单地开始一个transaction、更改多个行并提交transaction。但处理微服务架构中的数据访问要复杂得多,这是由于数据分布在不一样的数据库中。跨多个服务实施业务transactions是一个很大的挑战。

在咱们的“To-Do system“中,咱们正在使用事件来处理跨多个服务的业务事务。您能够查看在Mailer服务中应用的CQRS实施事件采购。您能够看到如何分离读和写,使咱们可以轻松地缩放每一个部分。咱们使用关系数据库做为事件存储,而后使用Kafka分发事件。咱们将须要使这两个动做为Atomic并避免存储事件,这样就不会发布最终的JVM崩溃。我不使用Kafka做为事件存储,由于从关系数据库构建聚合更简单。咱们正在努力使事情变得容易!

下一步

在To-Do-System已经包含许多微服务架构涉及到的方方面面,另外一方面也仍然存在诸多挑战。咱们将来计划在此项目基础上增长更多东西,例如Spring云配置、Docker容器、与Jenkins的持续集成、Spring Sleuth分布式跟踪、ELK日志管理等等。

推荐阅读

[开源项目:[云框架]基于Spring Cloud的微服务架构](https://github.com/cloudframe...,提供Spring Cloud微服务架构最佳实践,即插即用

在好雨云帮一键部署基于Spring Cloud的微服务架构

相关文章
相关标签/搜索