Nacos Client 1.4.1 版本踩坑记录

问题发现

就在这周,我接到 MSE Nacos 用户的反馈,说线上 Nacos 不可用,服务都下线了,日志里面也是一堆报错,我下意识以为线上炸了,赶紧上线排查。本文主要记录这次问题的排查过程,以及解决方案。

首先看用户反馈的报错,日志如下:

并且用户反馈业务日志也出现了大量的服务地址找不到的报错,说明 Nacos 服务都下线了。

我立刻查看了服务端的监控,发现用户的 MSE Nacos 集群并无异常,cpu/内存等指标有下降,并没有异常行为,排除了服务端异常的可能性。

随即将视线聚焦在了客户端。老实说,这个报错我第一次见,看异常堆栈,字面意思便是域名解析出问题了。这个报错大概持续了 10 分钟,立刻让用户在业务节点上使用 ping、dig 等工具确认域名解析是否正常,测试发现均无异常。继续让用户 telnet mse-xx.com 8848,发现也能够 telnet 通。

根据这些现象,大概能得出结论:用户的机器上出现了短暂的域名解析问题,导致短时间访问不通 MSE Nacos。但用户继续反馈说,一部分重启以后的机器已经恢复了,但没有重启的机器,竟然还会出现调用报错。不然怎么说重启大法好呢,但也加深了问题的诡异性。

正当一筹莫展时,另一用户也找上来了,竟然也是一样的问题,并且由于第二个用户还同时使用了 redis,报错日志中除了出现 nacos 的域名解析问题,还报了 redis 的域名解析报错。至此,更加坚定了我之前推测,根因肯定是域名解析出现了故障,导致这两个用户收到了影响。但问题在于,为什么短暂的域名解析失败(大概 10 分钟),会导致持续性的 Nacos 问题呢?并且只有重启才能恢复。

分析两个用户的共性,最终我和同事将可疑点锁定在了 Nacos 客户端版本上,对比发现,用户都是同一个报错,并且竟然都是 nacos-client 1.4.1 版本。

##Nacos 1.4.1 版本引入的 bug

在问题发生时,Nacos 1.x 最新的版本已经是 Nacos 1.4.2 了,将源码 checkout 到 1.4.1 版本,追踪堆栈附近的问题,

上述这段代码是 Nacos 访问服务端的一段代码,进入 595 行,一探究竟。

我们成功找到了堆栈中的直接报错,就是这段 IsIPv4 的判断触发。splitIPPortStr 这个方法的主要逻辑是从 Nacos 的连接串筛选出连接地址,主要是为了做默认端口号的判断,如果用户没有携带 8848,会默认带上 8848。

但问题恰恰便是出现在这儿:

InetAddress.getByName(addr) 是一个内置的方法,描述如下:

1
Given the name of a host, returns an array of its IP addresses, based on the configured name service on the system.

意思是把一个域名传给操作系统,返回一串 IP,这不就是域名解析吗!我当时就很好奇,你说你判断 IPv4 格式,为啥要这么判断呢?直接判断 IPv4 的 pattern 不行吗?而这段代码,恰恰是导致问题的凶手之一。

我们看看 1.4.2,已经修复了这个逻辑了,直接改成了正则判断。

但疑问还是存在的,域名解析短暂失败了,为啥会导致服务全都下线了,并且解析恢复后,服务依旧没有上线呢?

继续追踪这段代码,发现 callServer 这段代码会被 com.alibaba.nacos.client.naming.beat.BeatReactor 持有,用于维持自身和 Nacos 的心跳。

而由于上述域名解析失败,抛出的异常是 IllegalArgumentException,并没有被里层方法转换成 NacosException,从而导致心跳线程没有 catch 住异常,彻底停止发送心跳了!

这也就成功解释了,为什么短暂的域名解析失败,会导致服务全部下线了。(Nacos 是利用心跳维护和 server 端的存活状态的)

改进建议

  1. 修改 isIPv6 和 isIPv4 的判断方式,改为正则匹配。上文提及,这点已经在 1.4.2 修复了。
  2. 心跳线程要保证不被异常中断下一次心跳的提交。

第二点,也已经被修复了。

总结

nacos-client 1.4.1 存在严重的 bug,客户端与 Nacos Server 如果发生短暂的域名解析问题,会导致心跳永久丢失,进而引发服务全量下线,即使网络恢复,也不会自动恢复心跳。

域名解析失败常见于网络抖动或者 K8s 环境下的 coreDNS 访问超时等场景,为避免域名解析对 Nacos 造成的重大影响,请务必自查应用代码中使用的 nacos-client 的版本。

该问题仅存在于 1.4.1 版本,低于此版本不受此问题的影响,使用 1.4.1 的用户建议升级至 1.4.2 以避免此问题。

使用 SpringCloud/Dubbo 的用户,需要确认实际框架使用的 nacos-client 版本,可以通过显式指定 nacos-client 的版本以覆盖框架默认的版本。其中 Dubbo 用户要格外小心,Dubbo 的 2.7.11 版本默认使用了 nacos-client 1.4.1,务必显式指定 nacos-client 的版本到 1.4.2,Dubbo 也将在下个 release 版本替换 Nacos 的默认版本。


警惕 Spring Boot Actuator 引发的安全漏洞

前言

一年一度的 HW 行动开始了,最近也是被各种安全漏洞搞的特别闹心,一周能收到几十封安全团队扫描出来的漏洞邮件,这其中有一类漏洞很容易被人忽视,但影响面却极广,危害也极大,我说出它的名字你应该也不会感到陌生,正是 Spring Boot Actuator

写这篇文章前,我跟我的朋友做了一个小调查,问他们对 Spring Boot Actuator 的了解,结果惊人的一致,大家都知道 Spring Boot 提供了 spring-boot-starter-actuator 的自动配置,但却很少有人真正用到它相关的特性。在继续往下面看这篇文章时,大家也可以先思考下几个问题:

  1. 检查下你开发的项目中有引入 spring-boot-starter-actuator 依赖吗?
  2. 你在项目中有真正用到 spring-boot-starter-actuator 的有关功能吗?
  3. 你知道 spring-boot-starter-actuator 的安全风险和正确配置方式吗?

Netty实现长连接服务的难点和优化点

转载自:https://www.dozer.cc/2014/12/netty-long-connection.html

原文作者:dozer

推送服务

还记得一年半前,做的一个项目需要用到 Android 推送服务。和 iOS 不同,Android 生态中没有统一的推送服务。Google 虽然有 Google Cloud Messaging ,但是连国外都没统一,更别说国内了,直接被墙。

所以之前在 Android 上做推送大部分只能靠轮询。而我们之前在技术调研的时候,搜到了 jPush 的博客,上面介绍了一些他们的技术特点,他们主要做的其实就是移动网络下的长连接服务。单机 50W-100W 的连接的确是吓我一跳!后来我们也采用了他们的免费方案,因为是一个受众面很小的产品,所以他们的免费版够我们用了。一年多下来,运作稳定,非常不错!

时隔两年,换了部门后,竟然接到了一项任务,优化公司自己的长连接服务端。

再次搜索网上技术资料后才发现,相关的很多难点都被攻破,网上也有了很多的总结文章,单机 50W-100W 的连接完全不是梦,其实人人都可以做到。但是光有连接还不够,QPS 也要一起上去。

所以,这篇文章就是汇总一下利用 Netty 实现长连接服务过程中的各种难点和可优化点。


小白也能懂的 Nacos 服务模型介绍

前言

按照目前市场上的主流使用场景,Nacos 被分成了两块功能:服务注册发现(Naming)和配置中心(Config)。在之前的文章中我介绍了 Nacos 配置中心的实现原理,今天这篇文章所介绍的内容则是与 Nacos 服务注册发现功能相关,来聊一聊 Nacos 的服务模型。

说到服务模型,其实需要区分视角,一是用户视角,一个内核视角。即 Nacos 用户视角看到的服务模型和 Nacos 开发者设计的内核模型可能是完全不一样的,而今天的文章,是站在用户视角观察的,旨在探讨 Nacos 服务发现的最佳实践。


Kirito 杭州买房记 | 纯小白向杭州购房攻略

2021 年刚开年,解决了人生的一个大事,没错,就像标题里透露的那样,我在杭州买房啦。第一次有在杭州买房这个念头,还要说回 2020 年 6 月,当时和朋友们聚餐时偶然聊到了房子的话题,意外地发现竟然只有自己还没有在杭州买房,其中不乏有 96 年如此年轻的小伙子,自那次聚餐之后,我便开始关注起了杭州的楼市。

先说结果吧,我参与摇号的盘是在杭州市余杭区未来科技城的【天空之城】,摇号结果:

摇号结果

这是个什么概念呢,一共 6181 户参与摇号,房子一共有 1014 套,大概有 1/6 的人算是摇中,而我是摇中的人里面第 2 顺位选房的。记得等待摇号结果的那个周日中午,等待结果通知的那最后一个小时,真的比高考都要紧张,所幸不负期许,人品可以说非常爆炸了,希望摇号这件事没有花光我今年所有运气。

预计在大年初七~初十的时间点还需要办理预审并交付首付,再往后还要办理按揭、网签等流程,还需要忙活一段时间才算尘埃落定。趁着过年这段时间比较空闲,所幸记录一下自己在杭州楼市的经历,这样也给那些刚来到杭州,想要定居于此的小白们一些参考。


谈谈中间件开发

最近频繁地在跟实习生候选人打交道,每次新接触一个候选人,都要花上一定的时间去介绍我们团队,候选人问的最多的一个问题就是「中间件部门一般是干嘛的?」,恰好我之前也接触过一些想从事中间件开发的小伙伴,问过我「现在转行做中间件开发还来得及吗?」诸如此类的问题,索性就写一篇文章,聊聊我个人这些年做中间件开发的感受吧。

什么是中间件开发?

我大四实习时,在一个 20 多人的软件开发团队第一次接触了中间件,当时项目的架构师引入了微博开源的 RPC 框架 Motan,借助于这个框架,我们迅速构建起了一个基于微服务架构的内部电商系统。接着在项目中,由于业务需求,我们又引入了 ActiveMQ…在这个阶段,我已经在使用中间件了,但似乎没有接触到中间件开发,更多的是使用层面上的接触。

我毕业后的第一份工作,公司有几百号研发,当时的 leader 看我对中间件比较感兴趣,有意把我分配在了基础架构团队,我第一次真正意义上成为了一名”中间件研发“,平时主要的工作,是基于开源的 Kong 和 Dubbo,进行一些内部的改造,以提供给业务团队更好地使用。这个阶段,做的事还是比较杂的,业务团队对某些中间件有定制化的需求,都需要去了解这个中间件,熟悉源码。这段时间,也是我成长最快的一个时期,我是在这个期间学会了 Docker、Neo4j、Kong 等以前从来没接触过的技术,并且更加深入地了解 Dubbo 这类 RPC 框架的原理。可能坐在我旁边的就是一个订单部门的同学,抛了一个功能点让我来改造。

现在,我供职于阿里云云原生中间件,相较于上一份中间件研发工作,阿里云这类互联网大公司,任意一个中间件都有少则数人,多则数十人负责,中间件部门和业务部门之间也有着明确的界限。在这里,中间件团队的职责可以细分为三个方向:

  1. 中间件团队会被业务团队的需求所驱动,为集团内部提供定制化的解决方案,俗称「自研」。所以你可能并不了解到 HSF、Diamond 这些阿里内部的中间件。
  2. 中间件团队会从事开源,花费大量的精力提升中间件的极致性能,提升开源影响力,引领技术先进性。这部分中间件则比较为人所熟知,例如 Dubbo、Spring Cloud Alibaba、RocketMQ、Nacos。
  3. 中间件会在阿里云输出商业化产品,相比开源产品,提供更高的 SLA、更强大的功能、更友好的交互。这部分商业化产品诸如:微服务引擎 MSE、消息队列 RocketMQ、分布式应用链路追踪 ARMS。

我的这三段经历,正好反应了不同规模的公司对中间件开发的不同需求。小公司使用中间件,例如 RPC、MQ、缓存等,基本是由业务开发人员自己维护的。但如果后台研发达到数百人,基本就会组建自己的中间件团队,或者选择使用阿里云等云厂商提供的中间件产品。


从校园到职场,聊聊实习这点事

从我最近发的实习招聘文章就可以知道,我最近在忙春招的事了,本人也非常“荣幸”,担任了我们团队这次春招的负责人。陆陆续续沟通了很多学生,于是在这个周末抽出了一点时间,跟大家聊聊我对校园实习的一些看法。


用了这么久配置中心,还不知道长轮询是什么?

前言

传统的静态配置方式想要修改某个配置时,必须重新启动一次应用,如果是数据库连接串的变更,那可能还容易接受一些,但如果变更的是一些运行时实时感知的配置,如某个功能项的开关,重启应用就显得有点大动干戈了。配置中心正是为了解决此类问题应运而生的,特别是在微服务架构体系中,更倾向于使用配置中心来统一管理配置。

配置中心最核心的能力就是配置的动态推送,常见的配置中心如 Nacos、Apollo 等都实现了这样的能力。在早期接触配置中心时,我就很好奇,配置中心是如何做到服务端感知配置变化实时推送给客户端的,在没有研究过配置中心的实现原理之前,我一度认为配置中心是通过长连接来做到配置推送的。事实上,目前比较流行的两款配置中心:Nacos 和 Apollo 恰恰都没有使用长连接,而是使用的长轮询。本文便是介绍一下长轮询这种听起来好像已经是上个世纪的技术,老戏新唱,看看能不能品出别样的韵味。文中会有代码示例,呈现一个简易的配置监听流程。


Dubbo 基础教程:使用 Nacos 实现服务注册与发现

什么是 Nacos

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

在接下里的教程中,将使用 Nacos 作为微服务架构中的注册中心,替代 ZooKeeper 传统方案。


Service 层需要实现接口吗

前几天看技术交流群的话题,又刷到了「Service 层和 Dao 层真的有必要每个类都加上接口吗?」这个问题,之前简单回答了一波,给出的观点是「看情况」

现在结合我参与的项目以及阅读的一些项目源码来看,如果项目中使用了像 Spring 这样的依赖注入框架,那可以不用接口

先来说说为什么使用了依赖注入框架以后,可以不使用接口。


Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×