微服务错误处理与延迟应对:Netflix Hystrix 类库的容错机制解析

任何程序都需要错误地处理,不仅是最顺利的情况,还需要在微服务中处理。即使您开始部署和发布各个微服务,您也会谨慎地保持所有部署的API兼容。性别。如果您夸大其词,您甚至需要考虑在处理请求过程中用核武器攻击服务器的可能性。

微服务错误处理与延迟应对:Netflix Hystrix 类库的容错机制解析

此外,还有一个“警告”应该注意延误。也许响应微服务硬盘已满,并且响应时间已从前50ms变为10秒。如果您承受着一定的负担,则应注意它。如果BillingService不再响应,它将开始在您的系统中产生级联反应。在处理延迟和容忍度方面,Netflix的Hystrix是一个受欢迎的班级库,建议您研究它。

消息传递弹性模式

让我们看一下异步通信。如果使用Spring和RabbitMQ进行消息传递,则BillingService代码可能就是这样。要创建发票,我们将消息发送给RabbitMQ消息经纪人,该消息有一些工人在等待新消息。这些工人创建PDF发票并将其发送给相应的用户。

@Serviceclass BillingService {    @Autowired    private RabbitTemplate rabbitTemplate;     public void bill(User user, Plan plan) {        Invoice invoice = createInvoice(user, plan);        // 将 invoice 转换为 json 串,并将其作为消息体        rabbitTemplate.convertAndSend(exchange, routingkey, invoice);        // ...    }}

目前,潜在误差可能与上述误差不同,并且它不再是确定或同步HTTP通信的误差的立即响应。

每个异步微服务弹性模式都是不同的,并且具体的实现思想取决于当前正在使用的消息传递技术。如果您使用的是JMS实现,例如ActiveMQ,则可能需要交易速度,以保证两阶段(XA)提交;如果您使用的是RabbitMQ,则需要仔细阅读相关指南,并仔细考虑发布者确认,消息确认和消息可靠性。如果您已经构建了Active或RabbitMQ服务器,则需要具有正确配置它们的经验,尤其是结合群集,Docker和网络细分的经验。

哪个Java微服务框架是最好的?

还有许多流行的微服务框架,例如Spring Boot,这使得构建.jar文件非常容易,并为它们提供可以立即运行的嵌入式Web服务器,例如Tomcat或Jetty,非常适合您。构建微服务应用程序。

除此之外,最近出现了专用的微服务框架,这些框架在某种程度上受到了平行开发的启发,例如响应式编程,kubernetes或graalvm。例如,Quarkus,Micronaut,Vert.x,Helidon。

微服务框架的选择必须适合您自己的使用场景,但是我可能会在这里提供一些不太传统的建议:除了Spring Boot,所有微服务框架通常都声称自己是非常快的速度和启动速度。非常快,非常低的内存使用情况,可以无限扩展,并使用非常有影响力的图表与春季靴子的庞然大物进行比较。这消除了维护旧项目(有时需要几分钟的开始)的开发人员的担忧,以及希望在50毫秒中启动尽可能多的微容器的云本地开发人员。

但是,问题是(人造的)裸金属启动时间和重新部署时间对项目的整体成功没有影响,而不是像框架生态系统,强大的文档,社区和强大的开发人员技能那样强大。

如果是这样:

添加其他微服务挑战不仅是启动空心的Hello World,韧性,网络,消息传递,DevOps和基础架构,都会对您的项目产生更大的影响。对于开发过程中的热部部署,您可能最终会查看Jrebel或DCEVM等解决方案。

回顾西蒙·布朗(Simon Brown)的著名报价:如果您无法构建(快速高效)的大型单身应用程序,那么也很难构建(快速高效)的微服务。

因此,明智地选择您的框架。

哪个是最好的Java REST同步呼叫类库?

接下来,我们将从实际角度介绍HTTP REST API的呼叫。在基础技术方面,您可以使用以下HTTP客户端类之一:Java自己的HTTPCLIENT(自Java 11以来提供),Apache的HTTPClient或OKHTTP。

请注意,我在这里说“也许”,因为从古老且易于使用的JAX-RS客户端到现代WebSocket客户端还有其他无数方法。

无论如何,您应该选择适当的HTTP客户端,而不是摆弄HTTP来调用自己。

哪些代理最适合异步Java消息传递?

进行异步消息时,您可能首先想到ActiveMQ(经典或Artemis),RabbitMQ或Kafka。是的,这是一个非常受欢迎的选择。

但是我也有一些自己的意见供您参考:

一般而言,在选择代理时尝试排除任何人工绩效的原因。曾经有一段时间,有些团队和在线社区无休止地争论兔子的速度以及ActiveMQ的速度速度。现在,使用相同的参数,RabbitMQ的速度很慢,每秒只有20-30k消息,而Kafka每秒有100,000条消息。首先,重要的是要清楚,进行此比较很容易忽略您实际上正在比较苹果和橙子。

但更重要的是:对于阿里巴巴集团来说,这两个吞吐量可能处于低水平或中等水平,但是我们可能从未见过在现实世界中(每分钟数百万)消息中的这种大小的项目)。它们当然存在,但是对于99%的其他常规Java业务项目,无需担心这些指标。

因此,忽略那些庞大的宣传并做出明智的选择。

我可以将哪些类库用于微服务测试?

根据软件堆栈的不同,您可能最终使用春季的特定工具(春季生态系统)或类似于Arquillian(Javaee生态系统)的东西。

您需要了解Docker和真正出色的TestContainers库,该库可以轻松,快速地配置Oracle数据库,以进行本地开发或集成测试。

要模仿整个HTTP服务器,请查看WireMock。要测试异步消息传递,请尝试嵌入ActiveMQ或部署RabbitMQ,然后使用“等待DSL”编写测试。

此外,还有其他可行的选择,例如Junit,Testng to assertj和Mockito。

特别注意:这绝不是一个大而全面的清单。如果您错过了自己喜欢的工具,请留言要指出。

如何启用所有Java Microservers的记录?

使用微服务记录是一个有趣且相当复杂的主题。现在,您拥有n个日志文件,而不仅仅是一个可以更少或grep的日志文件,也许是您想要看到的是合并的日志文件。

在实际工作中,您可以找到各种方法:

微服务如何彼此找到?

到目前为止,我们一直在假设我们的微服务彼此了解并知道他们相应的IP。目前,它是更静态的设置。因此,我们的银行业务大型整体应用程序(具有IP 192.168.2001)知道,它必须与风险服务器(具有IP 192.168.2002)进行通信,这些IP 192.168.2002)在属性文件中进行了硬编码。

但是,您可以使它们更加灵活:您可以使用云配置服务器,而不是部署应用程序。

因为您的服务实例可能会动态地改变其位置(想象一下Amazon EC2实例获得动态IP,使您可以灵活地自动扩展云),因此您可能很快就会想到拥有服务注册表,哪些IP您的服务位于和可以相应路线。

由于一切都是动态的,因此出现了新问题,例如自动选举领导者:谁是处理某些任务的专家,以及如何确保不会反复处理它?当领导者出现问题时,谁会接管它?你和谁一起?

通常,这就是所谓的微服务编排,这本身就是另一个大主题。

Eureka或Zookeeper等课堂库尝试“解决”这些问题,例如客户或路由器知道可用的服务。另一方面,它们还带来了很多额外的复杂性。

如何使用Java微服务进行授权和身份验证?

这是另一个值得探索的话题。您可以选择硬码HTTPS基本身份验证和自我编码安全框架,并在您自己的授权服务器上运行OAuth2。

如何确保所有环境看起来相同?

适用于非微型服务部署,也适用于微服务部署。您可以尝试Docker/TestContainers和脚本/Ansible。

尝试保持简单。

没问题:YAML凹痕的故事

告别特定图书馆问题,让我们快速看一下yaml。它是“构型为代码”的事实上的标准文件格式。这些工具从简单的Ansible到功能强大的Kubernetes,支持这种格式。

要体验YAML缩进的痛苦,您可以先尝试自己编写一个简单的Ansible文件,尽管不同的IDE具有不同级别的支持,以查看您需要多长时间重复修改它以使压痕正常。然后,回去阅读本文。

Yaml:
- is:
- so
- great

2微服务的概念挑战

除了特定的Java微服务问题外,任何微服务项目都会带来一些问题。这些问题来自组织,团队或管理层的观点。

前端不匹配

在许多微服务项目中,在某种情况下,前端和后端微服务不匹配发生。这是什么意思?

在传统的老式,一般整体应用中,前端开发人员只有一个获得数据的特定来源。在微服务项目中,前端开发人员突然有n个用于获取数据的数据源。假设您正在构建一个Java-iot微服务项目,并监视某些机器,例如整个欧洲的工业烤箱。这些烤箱会定期向您发送温度和其他状态更新。

现在,您可能希望能够在管理接口中搜索烤箱,并且可能需要使用搜索烤箱微服务。由于后端同事对域驱动的设计或微服务术语的解释,“搜索烤箱”微服务可能仅返回烤箱的ID,而不是其他数据,例如类型,模型或位置。

为此,使用第一个微服务获得的ID来调用Get Oven详细信息Microservice,前端开发人员可能需要执行一个或多个其他额外的呼叫(取决于您的页面实现)。

虽然这只是一个简单的(但确实来自一个真实的项目)示例,但它说明了以下内容:

在现实生活中,超市被广泛接受是有原因的。因为您不必去10个不同的地方购买蔬菜,柠檬水,冷冻比萨饼和卫生纸,但是您足以去一个地方。它更简单,更快。前端开发人员和微服务也是如此。

管理期望

一些开发人员,编程杂志或云公司在大力促进微服务时也会产生负面影响:

管理层的印象是,现在您可以将无限的开发人员注入您的项目,因为开发人员现在可以完全独立地工作,并且每个人都可以从事自己的微服务。最终(即将上网时)进行一些微小的集成。

接下来,让我们看看为什么这种心态成为问题。

较小的零件可能不会更好

如果您将零件分为20个零件,则不一定会获得20个更好的零件。从技术质量的角度来看,这可能意味着您的服务必须执行400个休眠查询,从而从跨层中找到数据库的用户,并且代码更难维护。

让我们回顾一下西蒙·布朗(Simon Brown),如果人们无法正确构建大型单片应用程序,他们也将很难构建正确的微服务。

特别是在许多微服务项目中,此后总是想到灵活性。在启动之后,一切实际上都在发生。查看现场运行的微服务,总是会使人们感到有些不安。 。

原因实际上非常简单,因为Java开发人员通常对弹性,网络和其他相关主题不感兴趣,并且没有接受适当的培训。

较小的零件,更多的技术

此外,用户故事变得越来越技术性(因此越来越愚蠢)存在非常糟糕的趋势,因此它们变得越来越微观和抽象。

想象一下,要求您的微服务团队为数据库编写技术登录微服务,大致如下:

@Controllerclass LoginController {    // ...    @PostMapping("/login")    public boolean login(String username, String password) {        User user = userDao.findByUserName(username);        if (user == null) {            // 处理不存在用户的情况            return false;        }        if (!user.getPassword().equals(hashed(password))) {            // 处理密码错误的情况            return false;        }        // 棒棒的,登录成功!        // 设置 cookies, 做些你想做的事        return true;    }}

现在,您的团队可能会感到(甚至可能说服另一方):这太简单又无聊,我们不写任何登录名,但是我们想编写真正酷的Userstatatechangechanged Microservice(没有任何实际,有形的业务需求) 。

此外,Java现在已经过时了,让我们在Erlang上写下Userstatechanged Microservice。从集成,维护和整体项目的角度来看,这与在同一大型单片应用中编写一堆类似面食的代码一样糟糕。

这是虚构的例子吗?有点夸张吗?是的。但是不幸的是,这在现实生活中并不少见。

较小的零件使其更全面

作为开发人员,即使您仅负责独立的微服务[95:login-101:UpdateUserProfile],您也需要了解整个系统,其过程和工作流程。

当然,这取决于组织的信任和沟通水平。如果每个人都自己战斗,那么整个微服务链中的链接存在失败的不确定性,那么许多人可能只是耸耸肩,并说这与我无关,甚至互相责备。人们承担整体责任。

这是一个真正的问题。实际上,n个孤立的部分很难理解,很难弄清楚它们在全球环境中的位置。

沟通和维护

让我们谈谈最后一个问题:沟通和维护。显然,这个问题在很大程度上取决于公司的规模,一般来说:规模越大,问题就越大。

总体而言,本节所述的问题与应用DevOps遇到的问题相似,在更大的国际公司中,全面促进微服务也可以带来许多其他挑战。

3结论

阅读本文后,您可能会得出以下结论:我强烈建议不要使用微服务。这不是完全正确的 - 作者主要想强调微服务热潮中忘记的关键点。

微服务就像钟摆

完全使用Java微服务是摆的一端。另一方面,它可能是一个大型的整体应用,并具有数百个非常老式的毛衣模块。您必须找到正确的平衡。

尤其是在一个全新的项目中,没有什么可以阻止您采取更保守,大型整体式方法来构建更少,定义得出的Maven模块,而不是立即开始使用约20个微服务。

微服务会产生很多额外的复杂性

请记住,您拥有的微服务越多,真正强大的DevOps越少(请注意,仅执行某些Ansible脚本或在Heroku上部署它们就不算在内),并且您将来在生产环境中遇到的问题将会更多。

常见的Java微服务问题已经很累了。接下来,我们还必须考虑针对所有这些基础设施挑战实施解决方案。您会突然意识到,这些与业务编程无关(您可以得到奖励),只需将更多的技术应用于更多的技术即可。

Siva在他的博客上完美地总结了它:

如果团队将其70%的时间用于建设和配置现代基础架构,并且只有30%的时间用于实际的业务逻辑,那么这种糟糕的感觉简直是无法言喻的。 - - Siva Prasad Reddy

那么我应该使用Java微服务吗?

为了回答这个问题,我想以Google风格的面试问题无耻地结束这篇文章。如果您根据经验知道此问题的答案,则可以准备使用微服务。

场景

假设您在最小的Hetzner专用机器上分别运行了一个大型Java单片应用程序。同样,数据库服务器在类似的Hetzner机器上运行。

再次假设您的Java大型整体应用程序可以处理工作流,例如用户注册,并且每个工作流只会产生一些(少于10)数据库查询而不是数百个数据库查询。

问题

您的Java大型整体应用程序(连接池)应打开几个数据库连接?

您认为有多少个活跃的并发用户可以大致扩展到大致扩展?为什么?

如果您已经有了答案,请在下面留言!

参考阅读:

InfoQ读取器通信组在线!亲爱的朋友们,您可以在下面扫描QR码,添加Infoq助手,然后回复关键字“ Enter the Group”以申请加入组。每个人都可以与Infoq读者自由交谈,并与编辑密切联系。出色的有价值的技术礼品套餐正在等待您接收,而巨大的价值活动也在等待您参加。快来加入我们!

单击以查看是否有更少的错误

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

26阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

26阅读