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

简介:

“微服务架构”是现在编程中很流行的概念,未来能和最新趋势保持同步,我也一直在学习了解这个架构,如果具体点说,我一直在寻找一种使用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

相关文章
|
监控 Java 数据库
从零学 Dropwizard:手把手搭轻量 Java 微服务,告别 Spring 臃肿
Dropwizard 整合 Jetty、Jersey 等成熟组件,开箱即用,无需复杂配置。轻量高效,启动快,资源占用少,内置监控、健康检查与安全防护,搭配 Docker 部署便捷,是构建生产级 Java 微服务的极简利器。
1247 117
|
监控 Kubernetes Java
使用 New Relic APM 和 Kubernetes Metrics 监控 EKS 上的 Java 微服务
在阿里云AKS上运行Java微服务常遇性能瓶颈与OOMKilled等问题。本文教你通过New Relic实现集群与JVM双层监控,集成Helm部署、JVM代理注入、GC调优及告警仪表盘,打通从节点资源到应用内存的全链路观测,提升排障效率,保障服务稳定。
813 115
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
存储 Java 关系型数据库
Java 项目实战基于面向对象思想的汽车租赁系统开发实例 汽车租赁系统 Java 面向对象项目实战
本文介绍基于Java面向对象编程的汽车租赁系统技术方案与应用实例,涵盖系统功能需求分析、类设计、数据库设计及具体代码实现,帮助开发者掌握Java在实际项目中的应用。
450 0
|
IDE Java API
Java 17 新特性与微服务开发的实操指南
本内容涵盖Java 11至Java 17最新特性实战,包括var关键字、字符串增强、模块化系统、Stream API、异步编程、密封类等,并提供图书管理系统实战项目,帮助开发者掌握现代Java开发技巧与工具。
869 0
|
安全 Java 测试技术
Java 大学期末实操项目在线图书管理系统开发实例及关键技术解析实操项目
本项目基于Spring Boot 3.0与Java 17,实现在线图书管理系统,涵盖CRUD操作、RESTful API、安全认证及单元测试,助力学生掌握现代Java开发核心技能。
689 0
|
NoSQL Java 微服务
2025 年最新 Java 面试从基础到微服务实战指南全解析
《Java面试实战指南:高并发与微服务架构解析》 本文针对Java开发者提供2025版面试技术要点,涵盖高并发电商系统设计、微服务架构实现及性能优化方案。核心内容包括:1)基于Spring Cloud和云原生技术的系统架构设计;2)JWT认证、Seata分布式事务等核心模块代码实现;3)数据库查询优化与高并发处理方案,响应时间从500ms优化至80ms;4)微服务调用可靠性保障方案。文章通过实战案例展现Java最新技术栈(Java 17/Spring Boot 3.2)的应用.
1190 9
|
Java 开发者
【Java实例-神秘年龄】用Java挑战你的直觉
我们一起走进这款款简单却充满趣味的Java小游戏——“神秘年龄”。这款游戏不仅适合编程初学者作为练习项目,也能为有一定基础的开发者提供一个轻松的编程小憩。
241 0
【Java实例-神秘年龄】用Java挑战你的直觉
|
缓存 Cloud Native Java
Java 面试微服务架构与云原生技术实操内容及核心考点梳理 Java 面试
本内容涵盖Java面试核心技术实操,包括微服务架构(Spring Cloud Alibaba)、响应式编程(WebFlux)、容器化(Docker+K8s)、函数式编程、多级缓存、分库分表、链路追踪(Skywalking)等大厂高频考点,助你系统提升面试能力。
1835 0
|
存储 算法 Java
【Java实例-智慧牌局】Java实现赌桌上的21点
游戏规则:游戏开始时,玩家和庄家各获得两张牌,玩家可以看到自己手中的两张牌以及庄家的一张明牌。玩家需要根据手中的牌面总和,选择“要牌”(Hit)以获取更多牌,或“停牌”(Stand)停止要牌。如果玩家的牌面总和超过21点,即为爆牌,玩家立即输掉游戏。若玩家选择停牌,庄家则开始行动,其策略是当牌面总和小于17点时必须继续要牌。若庄家牌面总和超过21点,则庄家爆牌,玩家获胜。若双方均未爆牌,最终比较牌面总和,更接近21点的一方获胜;若牌面总和相同,则游戏以平局结束。
437 0