平滑迁移 Dubbo 服务的思考

前言

近日,有报道称在 HashCorp 的商业软件试用协议上发现,旗下所有商业产品禁止在中国境内使用、部署、安装,这其中就包含了 Terraform, Consul, Vagrant 等众多知名软件,其中 Consul 是一个在微服务领域的开源软件,可以用于做注册发现、配置管理等场景。

该新闻在国内发酵后,有人在 Twitter上咨询了HashCorp 公司的创始人,得到的回复是影响的软件仅限于 Vault 这款加密软件,目前 HashCorp 公司的官方网站上已经更新了相关的条款,明确了受影响的产品仅限 Vault 这一款产品。

Consul 开源版是否收到影响?

上面的条款里只提到了商业软件,那么开源的 Consul 是否受到影响呢?在 Github 的 Consul 仓库上,可以得知项目的 license 是 Mozilla Public License 2.0 ,这款许可证在 Apache 官网上是 Category B , 属于 Weak Copy Left 许可,那么它有哪些特点呢?

License

  1. 任何可以使用,复制,修改,重新分发该代码,包括商业目的使用。
  2. 如果修改了 MPL 协议许可下的源码,再重新发布这部分源码的话,必须保留原来 MPL 许可证不得更换。
  3. 如果基于该项目衍生出更大的项目,那么这部分工作可以使用新许可证的方式进行分发,只要没有修改原来 MPL 许可下的代码。(这也是为什么 Apache 项目的分发的源码中可以包含 MPL 协议下二进制文件的原因)

可以看到,MPL 通常被认为是介于 Apache License 和 GPL/LGPL 之间的一个折中方案。相对于 Apache License,MPL 2.0 要求修改了源码必须保持相同协议;相对于 GPL/LGPL, MPL 2.0 可以商用,同时衍生的作品在一定条件下也可以更换许可证类型。

总体来看的话,开源版 Consul 无论是私用还是商用都是不受限制的。但这也可能是一个警钟,如果对 Consul 还是有所顾忌的话,如何替代掉它呢?

在微服务领域,Consul 主要被用来做充当注册中心和配置中心,例如 Dubbo 和 SpringCloud 都有对应的支持。本文便以这个事为一个引子,介绍如何平滑地迁移 Dubbo 服务,达到替换注册中心的效果。

查看更多

分享到

Arthas | 追踪线上耗时方法

前言

本文是 Arthas 系列文章的第三篇。

本文主要介绍 trace 指令,用于定位两种类型的问题:

  1. 线上服务 RT 比较高,但没有打印日志,无法确定具体是哪个方法比较耗时
  2. 线上服务出现异常,需要追踪到方法的堆栈

查看更多

分享到

Arthas | 定位线上 Dubbo 线程池满异常

前言

本文是 Arthas 系列文章的第二篇。

Dubbo 线程池满异常应该是大多数 Dubbo 用户都遇到过的一个问题,本文以 Arthas 3.1.7 版本为例,介绍如何针对该异常进行诊断,主要使用到 dashboard/thread 两个指令。

查看更多

分享到

阿里巴巴中间件技术部春招开始啦

阿里巴巴中间件技术部 - aPaaS 产品团队春招意向沟通正式开始啦!三月前我们会完成和同学的意向沟通,三月初正式进入招聘流程。

简历投递:jingfeng.xjf@alibaba-inc.com

意向沟通联系微信:xiayimiaoshenghua

查看更多

分享到

Arthas | 热更新线上代码

前言

本文是我介绍 Arthas 系列文章的第一篇。

一般线上问题比开发环境的问题更难解决,一个主要的原因便在于开发态可以任意 debug 断点调试,而线上环境一般不允许远程调试,所以在实践中,我一般习惯用 Arthas 来定位线上的问题。

Arthas 是阿里巴巴开源的 Java 应用诊断利器

Arthas 可以完成很多骚操作,今天给大家介绍的 Arthas 诊断技巧便是 – 热更新线上代码。在生产环境热更新代码,并不是很好的行为,可能会引发一些问题

  • 黑屏化的操作可能会导致误操作
  • 不符合安全生产的规范,不满足可监控、可回滚、可降级

但有时候也有一些场景可以考虑使用 Arthas 来热更,例如开发环境无法复现的问题、找到修复思路后临时验证等。

本文以 Arthas 3.1.7 版本为例,主要使用到 jad/mc/redefine 三个指令。

查看更多

分享到

EDAS 微服务治理解密

前言

2020 是多事的一年,新冠状性病毒的肆虐,其次是自己也生了一场病,希望随着天气暖和起来,一起都能变得更好。

前一段时间真的很忙,一直没有抽出时间,也没有什么思路给大家分享优质的文章,今天这篇文章很久之前就想写了,抓住这次假期的尾巴,总结一下我最近这一年的工作。

查看更多

分享到

Dubbo 稳定性案例:Nacos 注册中心可用性问题复盘

问题描述

上周四晚刚回到家,就接到了软负载同学的电话,说是客户线上出了故障,我一听”故障“两个字,立马追问是什么情况,经过整理,还原出线上问题的原貌:

客户使用了 Dubbo,注册中心使用的是 Nacos,在下午开始不断有调用报错,查看日志,发现了 Nacos 心跳请求返回 502

1
2
2019-11-15 03:02:41.973 [com.alibaba.nacos.client.naming454] -ERROR [com.alibaba.nacos.naming.beat.sender] request xx.xx.xx.xx failed.
com.alibaba.nacos.api.exception.NacosException: failed to req API: xx.xx.xx.xx:8848/nacos/v1/ns/instance/beat. code:502 msg:

此时还没有大范围的报错。随后,用户对部分机器进行了重启,开始出现大规模的 Nacos 连接不上的报错,并且调用开始出现大量 no provider 的报错。

查看更多

分享到

一文聊透 Dubbo 优雅上线

1 前言

在此文之前,我写过一篇 《一文聊透 Dubbo 优雅停机》,这篇文章算是一个续集,优雅停机和优雅上线两者都是微服务生命周期中,开发者必须关心的环节。

优雅上线还有很多称呼:「无损上线」,「延迟发布」,「延迟暴露」。它们的对立面自然是:「有损上线」,「直接发布」。

我最近写的「一文聊透 Dubbo xx」系列文章,都有一个特点,即当你不注重文章中实践,你的 Dubbo 应用依旧可以正常运行,但总归在某些场景 case 下,你的系统会出现问题。做不到优雅上线,你的系统将会出现:在应用刚启动时,就有流量进入,而此时应用尚未初始化完毕,导致调用失败,在集群规模较大时,影响会变得很明显。

2 方案一:延迟发布

以 SpingBoot 下使用 Dubbo 为例,被 Dubbo 的 @Service 注解修饰的服务,会按照 Spring 中初始化 Bean 的顺序,串行执行发布逻辑。Dubbo 框架会完成一系列的操作:

  • 创建远程调用的 Proxy
  • 把代理对象注册到 ProviderConsumerRegTable,方便远程调用到来时寻找到对应的服务
  • 向注册中心注册

一旦服务信息注册到注册中心,在消费者看来该服务就是可以被调用的。然而,此时可能出现一些数据库、缓存资源尚未加载完毕的场景,这取决于你的系统有没有对应的组件,它们何时加载完毕,也完全取决于你的业务。如果你担心你的系统存在这种隐患,可以尝试多次重启集群中的任意一台机器,查看调用方是否存在报错,如果有报错,一种可能性是没有实现优雅停机,一种可能性是没有实现优雅上线。

Dubbo 服务暴露的起点一般是以 Spring 容器启动完毕后发出的 ContextRefreshedEvent 事件为准,Dubbo 的 ServiceBean 实现了 ApplicationListener<E extends ApplicationEvent> 接口,用以接收这一容器刷新事件。

1
2
3
4
5
6
7
public void onApplicationEvent(ContextRefreshedEvent event) {
// 是否有延迟导出 && 是否已导出 && 是不是已被取消导出
if (isDelay() && !isExported() && !isUnexported()) {
// 导出服务
export();
}
}

Dubbo 为服务提供了 delay 配置:

1
<dubbo:service delay="5000" />

如上配置后,Dubbo 服务将会在 Spring 容器启动后 5s,再执行暴露逻辑。这里 delay 的时长,取决于你系统资源初始化的耗时,没有一个经验值。如果不配置改值,Dubbo 将会在收到 ContextRefreshedEvent 事件后,立即执行发布逻辑。

Dubbo 2.6.5 版本对服务延迟发布逻辑进行了细微的调整,将需要延迟暴露(delay > 0)服务的倒计时动作推迟到了 Spring 初始化完成后进行。在此之前的版本的逻辑不太合理,如果想要让 2.6.5 之前的版本延迟到 Spring 初始化完成后,再暴露服务,可以这样配置:<dubbo:service delay=”-1” />

本节参考 Dubbo 官方文档

延迟暴露:http://dubbo.apache.org/zh-cn/docs/user/demos/delay-publish.html

3 方案二:QOS 命令上线

Dubbo 还为服务提供了另一个配置项:

1
<dubbo:service register="false" />

该配置项配置后,服务将不会发布到注册中心,可能很多 Dubbo 用户不会注意到这个配置,它的作用恰恰是 QOS 指令使用的。

Dubbo 2.5.8 及以上的版本,还提供了一些在线运维命令。为了演示该命令,我们准备一个 GreetingService 的 demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DubboProvider {

public static void main(String[] args) throws Exception {
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
service.setApplication(new ApplicationConfig("dubbo-provider"));
service.setRegistry(new RegistryConfig("nacos://127.0.0.1:8848"));
service.setInterface(GreetingsService.class);
service.setRef(new GreetingsServiceImpl());
service.setRegister(false);
service.export();

System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}

注意我们配置了不发布:service.setRegister(false),由于 QOS 配置是默认打开的,在本地的 22222 端口,可以进入 QOS 控制台。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 krito git:(master) ✗ telnet localhost 22222
Trying ::1...
Connected to localhost.
Escape character is '^]'.
___ __ __ ___ ___ ____
/ _ \ / / / // _ ) / _ ) / __ \
/ // // /_/ // _ |/ _ |/ /_/ /
/____/ \____//____//____/ \____/
dubbo>ls
As Provider side:
+-------------------------------------+---+
| Provider Service Name |PUB|
+-------------------------------------+---+
|com.alibaba.edas.api.GreetingsService| N |
+-------------------------------------+---+
As Consumer side:
+---------------------+---+
|Consumer Service Name|NUM|
+---------------------+---+

dubbo>online
OK
dubbo>ls
As Provider side:
+-------------------------------------+---+
| Provider Service Name |PUB|
+-------------------------------------+---+
|com.alibaba.edas.api.GreetingsService| Y |
+-------------------------------------+---+
As Consumer side:
+---------------------+---+
|Consumer Service Name|NUM|
+---------------------+---+

dubbo>

如上图所示,我们首先查看到 com.alibaba.edas.api.GreetingsService 服务是未发布的,通过 online 命令手动将服务发布,再使用 ls 查看服务列表时,已经显示服务处于发布状态了。

除了使用 telnet,还可以通过 HTTP 访问:

1
curl localhost:22222/online

小 tips:在使用 SpringBoot 注解式声明一个 Service 时,register 属性会失效,在 xml 或者 API 方式下声明则运行正常,怀疑是 dubbo-spring-boot-starter 的一个 bug。

image-20191117205139227

image-20191117205207044

大家在 SpringBoot 下使用 Dubbo 需要留意类似的问题,之前有过一些属性在 SpringBoot 注解中未解析或为提供注解配置的案例,在使用时需要注意。

本节参考 Dubbo 官方文档

服务配置说明:http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-service.html

QOS:http://dubbo.apache.org/zh-cn/docs/user/references/qos.html

最佳实践

本文介绍了两种 Dubbo 的机制:

  • 方案一:延迟发布(delay=5000)
  • 方案二:不发布 + QOS 指令发布(register=false)

想要实现优雅上线,可以采取适合你系统的方式。方案一延迟发布的优势在于实现简单,但具体 delay 多少秒,比较依赖系统维护者的经验。方案二使用 QOS 指令,一般依靠于发布系统,当发布系统检测到固定的资源加载完毕这样一个信号时,自动触发上线命令,更加灵活。

当你系统遇到应用启动时流量有所损失时,就应该考虑一下优雅上线的问题了,更多 Dubbo 使用的注意点,请持续关注公众号。

img

「技术分享」某种程度上,是让作者和读者,不那么孤独的东西。欢迎关注我的微信公众号:Kirito的技术分享」

分享到

一文聊透 Dubbo 元数据中心

前言

如果让你在本地构建一个 Dubbo 应用,你会需要额外搭建哪些中间件呢?如果没猜错的话,你的第一反应应该是注册中心,类 Dubbo 的大多数服务治理框架都有注册中心的概念。你可以部署一个 Zookeeper,或者一个 Nacos,看你的喜好。但在 Apache Dubbo 的 2.7 版本后,额外引入了两个中间件:元数据中心和配置中心。

在今年年初 Dubbo 2.7 刚发布时,我就写了一篇文章 《Dubbo 2.7 三大新特性详解》,介绍了包含元数据中心改造在内的三大新特性,但一些细节介绍没有详细呈现出来,在这篇文章中,我将会以 Dubbo 为例,跟大家一起探讨一下服务治理框架中元数据中心的意义与集成细节。

Dubbo 2.7 架构

查看更多

分享到

Linux 环境写文件如何稳定跑满磁盘 I/O 带宽?

  • 准备
    • 要求
    • 机器配置
    • 测试磁盘 IO 性能
  • 实验一: Buffer IO 写入
  • 实验二: 4K 单次 Direct IO 写入
  • 实验三: mmap 写入
  • 实验四: 改进的 mmap 写入
  • 结论

查看更多

分享到