实例解读:基于Java构建实际可用的微服务

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介:

“微服务架构”是现在编程中很流行的概念,未来能和最新趋势保持同步,我也一直在学习了解这个架构,如果具体点说,我一直在寻找一种使用Spring在Java中实现微服务架构的方法。

为什么我会有这个想法,这是有一定的背景的:我们公司很好但是却有一个过时的技术堆栈,基本上没有使用Java 8或者微服务器。所以我想要了解关于微服务器的事情,必须自己去收集学习,为此我创建了一个待办事项系统,记录我的学习经历以供将来参考!

概述

本文的目的是为不同微服务提供源代码演练,不会深入解读概念和工具,主要是介绍一个包含用于开发微服务的模式、工具和技术的应用示例。

既然是一个参考应用程序,我会使它尽量简单,源码易于理解!本文中,这个待办事项系统应用程序由8个部分组成:

  • Reminder
  • User
  • Service discovery server
  • Mailer
  • OAuth Server
  • System integration test
  • API Gateway
  • Web application client

系统如何与Microservices交互

上图中显示了系统与所有微服务器的交互,用户访问使用Angular 2编写的Web应用程序。然后连接到OAuth授权服务器,OAuth授权服务器将是可以分配用户和权限的中心点。此服务器将返回一个JSON Web令牌,其中包含客户端及其权限的信息以及格式范围。在用户认证并具有令牌之后,Web应用程序与API网关通信。通过JWT来验证它是否来自授权服务器,然后调用微服务器并构建响应。

OAuth服务器使用用户服务来获取用户的身份验证详细信息。此外,API网关使用OAuth服务器来获取用户的信息。

Remainder Service由ToDo功能来提供,,ToDo服务有一个计划工作来检查并通过电子邮件通知用户,电子邮件由邮件服务发送,该事件使用Kafka的事件提醒服务触发。

系统集成测试是一个Java应用程序,负责到达提醒服务的端点。

连接微服务

在微服务体系结构中,我们必须处理许多在不同IP和端口上运行的微服务器。因此,我们需要找到一种无需硬编码来管理每个地址的方式。

这就需要用到Netflix Eureka,它是客户端服务发现,允许服务自动查找和相互通信。我们在系统中使用了Spring Cloud Eureka,如果Eureka查找到服务运行的位置,我们就可以添加实例并应用负载平衡来在微服务器之间分配传入的应用流量。

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

我们的系统中存在一些依赖。我们正在使用Netflix Hystrix断路器将应用程序与依赖性故障隔离开来。它有助于阻止级联故障,并允许快速恢复或添加后备。Hystrix为每个依赖关系维护一个线程池,如果线程池耗尽,它会拒绝请求。它还提供断路器功能,可以停止对依赖关系的所有请求。当请求失败,拒绝或超时时,还可以实现备用逻辑。

认证

开发任何类型的系统时,安全性都是非常重要的,微服务架构也没什么不同。当“如何保持微服务的安全性?”这个问题出现时,我的第一个答案是OAuth2。OAuth2绝对是一个很好的解决方案:它是一种众所周知的授权技术,广泛应用于Google,Facebook和Github。

当然没有Spring Security的情况下,是不可能谈论安全的。。在讨论分布式系统的安全性时,Spring Security和OAuth2是显而易见的选择。

不过,我们在安全问题上还增加了一个元素:JSON Web Token(JWT)。如果仅使用OAuth,我们需要一个OAuth授权服务器来验证用户,生成令牌,并充当资源服务器的端点,询问该令牌是否有效以及授权的权限。与授权服务器相比,这需要两倍的请求。而JWT提供了一种在访问令牌中传输权限和用户数据的简单方法,一旦所有数据都已经在令牌字符串中,资源服务器就不需要请求令牌检查。所有信息都被序列化为JSON,用base64编码,最后用私有RSA密钥签名。

您可以查看OAuth2授权服务器(OAuth-server)和资源服务器(API Gateway)的代码实现。

REST

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

Martin Fowler认为RESTful可以分为四个级别,level 0-level 3。我们的微服务处于level 2,为了简单起见,这里不使用HATEOAS设计模式实现超媒体控件。

因为我们使用了Spring Cloud,所以必须实现开箱即用的可扩展性模式,将其放在HTTP连接中,例如:断路器,负载平衡,连接池,超时和重试等。

分布式事件

如上所述,我们通过使用Kafka 进行提醒服务和 Mailer服务之间的通信,并异步地与其他Microservices进行通信。在提醒服务中,我们有一个计划任务来检查提醒时间,并发布RemainderFound事件。Mailer服务中将会有一个订阅的事件,向用户发送电子邮件。

Event sourcing和 CQRS

单片应用通常具有单个关系数据库。我们可以使用ACID交易。因此,如果出现问题,我们的应用程序可以简单地开始一个事务,更改多个行,并提交事务,如果错误的话,还可以恢复到之前。不幸的是,处理微服务架构中的数据访问要复杂得多。这些数据分布在不同的数据库中,跨多个服务实施业务交易是一个很大的挑战。

在“ToDo”项目中,我们使用事件来处理跨多个服务的业务事务。 您可以查看在Mailer服务中应用的CQRS实施事件。 可以看到如何分离读和写,轻松地缩放每个部分。 我们使用关系数据库作为事件存储,然后使用Kafka分发事件。 当然我们需要将这两个动作定义为原子操作并避免存储事件,这样就不会导致JVM崩溃。 不使用Kafka作为事件存储,是因为从关系数据库构建聚合更简单。

未来的计划

您可能也注意到这个项目中尚且还有很多事情尚未解决,这是一个开发中的项目,未来我们会添加更多的东西,例如Spring云配置,Docker容器,与Jenkins的持续集成,Spring Sleuth的分布式跟踪,ELK的日志管理等。


本文作者:田晓旭

来源:51CTO

相关文章
|
6天前
|
运维 持续交付 API
从零构建微服务架构:一次深度技术探索之旅####
【10月更文挑战第28天】 本文记录了作者在从零开始构建微服务架构过程中的深刻技术感悟,通过实战案例详细剖析了微服务设计、开发、部署及运维中的关键要点与挑战。文章首先概述了微服务架构的核心理念及其对企业IT架构转型的重要性,随后深入探讨了服务拆分策略、API网关选型、服务间通信协议选择、容器化部署(Docker+Kubernetes)、以及持续集成/持续部署(CI/CD)流程的设计与优化。最后,分享了在高并发场景下的性能调优经验与故障排查心得,旨在为读者提供一套可借鉴的微服务架构实施路径。 ####
40 3
|
8天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
15天前
|
Kubernetes 负载均衡 Docker
构建高效后端服务:微服务架构的探索与实践
【10月更文挑战第20天】 在数字化时代,后端服务的构建对于任何在线业务的成功至关重要。本文将深入探讨微服务架构的概念、优势以及如何在实际项目中有效实施。我们将从微服务的基本理念出发,逐步解析其在提高系统可维护性、扩展性和敏捷性方面的作用。通过实际案例分析,揭示微服务架构在不同场景下的应用策略和最佳实践。无论你是后端开发新手还是经验丰富的工程师,本文都将为你提供宝贵的见解和实用的指导。
|
14天前
|
监控 API 持续交付
构建高效后端服务:微服务架构的深度探索
【10月更文挑战第20天】 在数字化时代,后端服务的构建对于支撑复杂的业务逻辑和海量数据处理至关重要。本文深入探讨了微服务架构的核心理念、实施策略以及面临的挑战,旨在为开发者提供一套构建高效、可扩展后端服务的方法论。通过案例分析,揭示微服务如何帮助企业应对快速变化的业务需求,同时保持系统的稳定性和灵活性。
44 9
|
14天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
本文介绍了Docker和Kubernetes在构建高效微服务架构中的应用,涵盖基本概念、在微服务架构中的作用及其实现方法。通过具体实例,如用户服务、商品服务和订单服务,展示了如何利用Docker和Kubernetes实现服务的打包、部署、扩展及管理,确保微服务架构的稳定性和可靠性。
58 7
|
9天前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
24 2
|
13天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【10月更文挑战第22天】随着云计算和容器技术的快速发展,微服务架构逐渐成为现代企业级应用的首选架构。微服务架构将一个大型应用程序拆分为多个小型、独立的服务,每个服务负责完成一个特定的功能。这种架构具有灵活性、可扩展性和易于维护的特点。在构建微服务架构时,Docker和Kubernetes是两个不可或缺的工具,它们可以完美搭档,为微服务架构提供高效的支持。本文将从三个方面探讨Docker和Kubernetes在构建高效微服务架构中的应用:一是Docker和Kubernetes的基本概念;二是它们在微服务架构中的作用;三是通过实例讲解如何使用Docker和Kubernetes构建微服务架构。
51 6
|
14天前
|
Kubernetes 监控 数据中心
容器化与微服务:构建高效开发环境的双剑合璧
【10月更文挑战第20天】本文探讨了容器化技术(如Docker和Kubernetes)与微服务架构的结合,如何共同构建高效、灵活的开发环境。容器化解决了环境一致性、快速部署和资源隔离的问题,而微服务架构则提升了系统的可维护性和可扩展性。通过容器编排工具、CI/CD流程和服务网格,两者的结合进一步优化了开发和运维效率。文章还分享了实施这两项技术的最佳实践和职业心得。
|
15天前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
16天前
|
监控 安全 Java
构建高效后端服务:微服务架构深度解析与最佳实践###
【10月更文挑战第19天】 在数字化转型加速的今天,企业对后端服务的响应速度、可扩展性和灵活性提出了更高要求。本文探讨了微服务架构作为解决方案,通过分析传统单体架构面临的挑战,深入剖析微服务的核心优势、关键组件及设计原则。我们将从实际案例入手,揭示成功实施微服务的策略与常见陷阱,为开发者和企业提供可操作的指导建议。本文目的是帮助读者理解如何利用微服务架构提升后端服务的整体效能,实现业务快速迭代与创新。 ###
46 2