提升不止一点点,Dubbo 3.0 预览版详细解读

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。更多用户信息,可以访问Dubbo @GitHub,issue#1012: Wanted: who's using dubbo。

自去年 12 月开始,Dubbo 3.0 便已正式进入开发阶段,并备受社区和广大 Dubbo 用户的关注,本文将为您详细解读 3.0 预览版的新特性和新功能。

下面先解答一下两个有意思的与 Dubbo 相关的疑问。

  • 为什么 Dubbo 一开源就是 2.0 版本?之前是否存在 1.0 版本?

笔者曾做过 Dubbo 协议的适配兼容,Dubbo 确实存在过 1.x 版本,而且从协议设计和模型设计上都与 2.0 的开源版本协议是完全不一样的。下图是关于 Dubbo 的发展路径:

  • 阿里内部正在使用 Dubbo 开源版本吗?

是的,非常确定,当前开源版本的 Dubbo 在阿里巴巴被广泛使用,而阿里的电商核心部门是用的 HSF2.2 版本,这个版本是兼容了 Dubbo 使用方式和 Remoting 协议。当然,我们现在正在做 HSF2.2 的升级,直接依赖开源版本的 Dubbo 来做内核的统一。所以,Dubbo 是得到大规模线上系统验证的分布式服务框架,这一点毋容置疑。

Dubbo 3.0 预览版的要点

Dubbo 3.0 在设计和功能上的新增支持和改进,主要是以下四方面:

  • Dubbo 内核之 Filter 链的异步化

这里要指出的是,3.0 中规划的异步去阻塞和 2.7 中提供的异步是两个层面的特性。2.7 中的异步是建立在传统 RPC 中 request – response 会话模型上的,而 3.0 中的异步将会从通讯协议层面由下向上构建,关注的是跨进程、全链路的异步问题。通过底层协议开始支持 streaming 方式,不单单可以支持多种会话模型,还可以在协议层面开始支持反压、限流等特性,使得整个分布式体系更具有弹性。综上所述,2.7 关注的异步更局限在点对点的异步(一个 consumer 调用一个 provider),3.0 关注的异步化,宽度上则关注整个调用链上的异步,高度上则向上又可以包装成 Rx 的编程模型。有趣的是,Spring 5.0 发布了对 Flux 的支持,随后开始解决跨进程的异步问题。

  • 功能方面是 reactive(响应式)支持

最近几年, reactive programming这个词语的热度迅速提升,Wikipedia 上的 reactive programming 解释是 reactive programming is a programming paradigm oriented around data flows and the propagation of change. Dubbo3.0会实现Reactive Stream 的 rx 接口,从而能让用户享受到RP带来的响应性提升,甚至面向 RP 的架构升级。当然,我们希望 reactive 不单单能够带来事件(event)驱动的应用集成方式的升级,也希望在 Load Balance(选择最优的服务节点),fault tolerance(限流降级时最好做到自适应)等方面发挥其积极价值。

  • 云原生/ ServiceMesh 方向的探索

我们定下的策略是进入 Envoy 社区来实现 Dubbo 融入 mesh 的理念思想,目前 Dubbo 协议已经被 Envoy 支持。当然,Dubbo Mesh 离真正可用还有很长一段距离,其在选址、负载均衡和服务治理方面的工作需要继续在数据面建设,另外,控制面板的建设在社区也没有提上日程。

  • 融合并支持阿里内部

Dubbo 3.0 定下了内外融合的策略,也就是说 3.0 的核心最终会在阿里巴巴的生产系统中部署,相信通过大流量、大规模的考验,Dubbo 用户可以获得一个性能、稳定、服务治理实践各方面俱佳的核心,用户在生产系统中采用 3.0 也会更加放心。这一点也是 Dubbo 3.0 最重要的使命。

Filter 链的异步化设计

Dubbo 最强大的一处设计是其在 Filter 链上的抽象设计,通过其扩展机制的开放性支持,用户可以对 Dubbo 做功能增强,并允许各个扩展点被定制来是否保留。

Dubbo 的 Filter 定义如下:

@SPIpublic interface Filter {/*** do invoke filter.* <p>* <code>* // before filter* Result result = invoker.invoke(invocation);* // after filter* return result;* </code>** @param invoker    service* @param invocation invocation.* @return invoke result.* @throws RpcException* @see org.apache.dubbo.rpc.Invoker#invoke(Invocation)*/Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;}

按照“调用一个远程服务的方法就像调用本地的方法一样”这种说法,这个直接返回 Result 响应的方式是非常好的,用起来是简单直接,问题是时代变换到了需要关注体验,需要走 Reactive 响应式的时代,也回到基本点:invoke一个 invocation 需要经过网络在不同的进程处理,天然就是异步的过程,也就是发送请求(invocation)与接收响应(Result)本身是两个不同的事件,是需要两个过程方法来在 Filter 链处理。那么如何改造这个关键的 SPI 呢?有两种方案:

第一种,把 invoke 的返回值改成 CompletableFuture, 好处是一目了然,Result 不在建议同步获取了;但基础接口的签名一改会导致代码改造量巨大,同时也会让原有的 SPI 扩展不在支持。

第二种,Result 接口直接继承 CompletationStage,是代表了响应的异步计算。这样能进避免第一种的劣势。所以,3.0.0 Preview 版本对内部调用链路实现做了一次重构:基于 CompletableFuture 实现了框架内部的全异步调用,而在外围编程上,同时支持同步、异步调用模式。

值得注意的是,此次重构仅限于框架内部实现,对使用方没有任何影响即接口上保持完全兼容。要了解 Dubbo 异步 API 如何使用,请参考《如何基于 Dubbo 实现全异步的调用链》,这篇文章将着重对实现思路和原理做一些简单介绍。此次重构的要点有:

  • 框架内部采用全异步调用模型,仅在外围做同步、异步适配;
  • 内置Filter链支持异步回调;

基本工作流程

首先我们来看一个通用的跨网络异步调用的线程模型:

通信框架异步发送请求消息,请求消息发送成功后,返回代表业务结果的 CompletableFuture 给业务线程。之后对于 Future 的处理,根据调用类型会有所区别:

  1. 对于同步请求(如上图体现的场景),业务线程会调用 future.get 同步阻塞等待结果,当收到网络层返回的业务结果后,future.get 返回并最终将结果传递给调用发起方。
  2. 对于异步请求,业务线程不会调用 future.get,而是将 future 保存在调用上下文或者直接返回给调用者,同时会为 future 注册回调监听器,以便当真正的业务结果从通信层返回时监听器可以对结果做进一步的处理。

接下来具体看一下一次异步 Dubbo RPC 请求的调用流程:

  1. 消费方面向 Proxy 代理编程,发出调用请求,请求经过 Filter 链向下传递。
  2. Invoker.invoke() 将请求异步转发给网络层,并收到代表返回结果的 Future。
  3. Future 被包装到 Result,转而由 Result 代表这次远程调用的结果(由于 Result 的异步属性,此时它可能并不包含真正的返回值)。
  4. Result 继续沿着调用链返回,在经过每个 Filter 时,Filter 可选择注册 Listener 监听器,以便在业务结果返回时执行结果预处理。
  5. 最终 Proxy 调用 result.recreate() 将结果返回给消费者:
  • 如果方法是 CompletableFuture 签名,则返回 Future;
  • 如果方法是普通同步签名,则返回对象默认值,Future 可通过 RpcContext 拿到;

6. 调用方在拿到代表异步业务结果的 Future 后,可选择注册回调监听器,以监听真正的业务结果返回。

同步调用和异步调用基本上是一致的,并且也是走的回调模式,只是在链路返回之前做了一次阻塞 get 调用,以确保在收到实际结果时再返回。Filter 在注册 Listener 时由于 Future 已处于 complete 状态,因此会同时触发回调 onResponse()/onError()。

关于流程图中提到的 Result,Result 在 Dubbo 的一次 RPC 调用中代表返回结果,在 3.0 中 Result 自身增加了代表状态的接口,类似 Future 现在 Result 可以代表一次未完成的调用。

要让 Result 具备代表异步返回结果的能力,有两中方式来实现:

1. Result is a Future,在 Java 8 中更合理的方式是继承 CompletionStage 接口。

public interface Result extends CompletionStage {}

2. 让 Result 实例持有 Future 实例,与 1 的区别即是设计中选用“继承”还是“组合”。

public class AsyncRpcResult implements Result {private CompletableFuture<RpcResult> resultFuture;}

同时,为了让 Result 更直观的体现其异步结果的特性,也为了方便面向 Result 接口编程,我们可以考虑为Result增加一些异步接口:

public interface Result extends Serializable {Result thenApplyWithContext(Function<Result, Result> fn);<U> CompletableFuture<U> thenApply(Function<Result, ? extends U> fn);Result get() throws InterruptedException, ExecutionException;}

Filter SPI

Filter 是 Dubbo 预置的拦截器扩展 SPI,用来做请求的预处理、结果的后处理,框架本身内置了一些拦截器实现,而从用户层面,我相信这个 SPI 也应该是被扩展最多的一个。在 3.0 版本中,Filter 回归单一职责的设计模式,将回调接口单独提取到 Listener 中。

@SPIpublic interface Filter {Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;interface Listener {void onResponse(Result result, Invoker<?> invoker, Invocation invocation);void onError(Throwable t, Invoker<?> invoker, Invocation invocation);}}

以上是 Filter 的 SPI 定义,Filter 的核心定义中只有一个 invoke() 方法用来传递调用请求。

同时,增加了一个新的回调接口 Listener,每个 Filter 实现可以定义自己的 Listenr 回调器,从而实现对返回结果的异步监听,参考以下是为 MonitorFilter 增加的 Listener 回调实现:

class MonitorListener implements Listener {@Overridepublic void onResponse(Result result, Invoker<?> invoker, Invocation invocation) {if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) {collect(invoker, invocation, result, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), false);getConcurrent(invoker, invocation).decrementAndGet(); // count down}}@Overridepublic void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) {collect(invoker, invocation, null, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), true);getConcurrent(invoker, invocation).decrementAndGet(); // count down}}}

泛化调用异步接口支持

为了更直观的做异步调用,泛化接口新增了 CompletableFuture<Object>$invokeAsync(Stringmethod,String[]parameterTypes,Object[]args)接口:

public interface GenericService {/*** Generic invocation** @param method         Method name, e.g. findPerson. If there are overridden methods, parameter info is*                       required, e.g. findPerson(java.lang.String)* @param parameterTypes Parameter types* @param args           Arguments* @return invocation return value* @throws GenericException potential exception thrown from the invocation*/Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;default CompletableFuture<Object> $invokeAsync(String method, String[] parameterTypes, Object[] args) throws GenericException {Object object = $invoke(method, parameterTypes, args);if (object instanceof CompletableFuture) {return (CompletableFuture<Object>) object;}return CompletableFuture.completedFuture(object);}}

这样,当我们想做异步调用时,就可以直接这样使用:

CompletableFuture<Object> genericService.$invokeAsync(method, parameterTypes, args);

更具体用例请参见《泛化调用示例》

https://github.com/apache/incubator-dubbo-samples/tree/3.x/dubbo-samples-generic/dubbo-samples-generic-call

异步与性能

组要注意的是,框架内部的异步实现本身并不能提高单次调用的性能,相反,由于线程切换和回调逻辑的存在,异步反而可能会导致单次调用性能的下降,但是异步带来的优势是能减少对资源的占用,提升整个系统的并发程度和吞吐量,这点对于 RPC 这种需要处理网络延迟的场景非常适用。更多关于异步化设计的好处,请参考其他异步化原理介绍相关文章。

响应式编程支持

响应式编程让开发者更方便地编写高性能的异步代码,很可惜,在之前很长一段时间里,dubbo 并不支持响应式编程,简单来说,dubbo 不支持在 rpc 调用时使用 Mono/Flux 这种流对象(reative-stream 里流的概念),给用户使用带来了不便。(关于响应式编程更详细的信息请参见这里:http://reactivex.io/)

RSocket 是一个开源的支持 reactive-stream 语义的网络通信协议,他将 reative 语义的复杂逻辑封装起来了,使得上层可以方便实现网络程序。(RSocket详细资料请参见这里:http://rsocket.io/)

dubbo 在 3.0.0-SNAPSHOT 版本里基于 RSocket 对响应式编程进行了简单的支持,用户可以在请求参数和返回值里使用 Mono 和 Flux 类型的对象。下面我们给出使用范例,(范例源码可以在这里获取:https://github.com/apache/incubator-dubbo-samples/tree/3.x/dubbo-samples-rsocket)

首先定义接口如下:

public interface DemoService {Mono<String> requestMonoWithMonoArg(Mono<String> m1, Mono<String> m2);Flux<String> requestFluxWithFluxArg(Flux<String> f1, Flux<String> f2);}

然后实现该 demo 接口:

public class DemoServiceImpl implements DemoService {@Overridepublic Mono<String> requestMonoWithMonoArg(Mono<String> m1, Mono<String> m2) {return m1.zipWith(m2, new BiFunction<String, String, String>() {@Overridepublic String apply(String s, String s2) {return s+" "+s2;}});}@Overridepublic Flux<String> requestFluxWithFluxArg(Flux<String> f1, Flux<String> f2) {return f1.zipWith(f2, new BiFunction<String, String, String>() {@Overridepublic String apply(String s, String s2) {return s+" "+s2;}});}}

然后配置并启动服务端,注意协议名字填写 rsocket:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- provider's application name, used for tracing dependency relationship --><dubbo:application name="demo-provider"/><!-- use registry center to export service --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- use dubbo protocol to export service on port 20880 --><dubbo:protocol name="rsocket" port="20890"/><!-- service implementation, as same as regular local bean --><bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/><!-- declare the service interface to be exported --><dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/></beans>
public class RsocketProvider {public static void main(String[] args) throws Exception {new EmbeddedZooKeeper(2181, false).start();ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/rsocket-provider.xml"});context.start();System.in.read(); // press any key to exit}}

然后配置并启动消费者消费者如下, 注意协议名填写 rsocket:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),don't set it same as provider --><dubbo:application name="demo-consumer"/><!-- use registry center to discover service --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- generate proxy for the remote service, then demoService can be used in the same way as thelocal regular interface --><dubbo:reference id="demoService" check="true" interface="org.apache.dubbo.samples.basic.api.DemoService"/></beans>
public class RsocketConsumer {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/rsocket-consumer.xml"});context.start();DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxywhile (true) {try {Mono<String> monoResult = demoService.requestMonoWithMonoArg(Mono.just("A"), Mono.just("B"));monoResult.doOnNext(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}}).block();Flux<String> fluxResult = demoService.requestFluxWithFluxArg(Flux.just("A","B","C"), Flux.just("1","2","3"));fluxResult.doOnNext(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}}).blockLast();} catch (Throwable throwable) {throwable.printStackTrace();}}}}

可以看到配置上除了协议名使用 rsocket 以外其他并没有特殊之处。

实现原理

以前用户并不能在参数或者返回值里使用 Mono/Flux 这种流对象(reative-stream 里的流的概念)。因为流对象自带异步属性,当业务把流对象作为参数或者返回值传递给框架之后,框架并不能将流对象正确的进行序列化。

dubbo 基于 RSocket 实现了 reative 支持。RSocket 将 reative 语义的复杂逻辑封装起来了,给上层提供了简洁的抽象如下:

/*** Fire and Forget interaction model of {@code RSocket}.** @param payload Request payload.* @return {@code Publisher} that completes when the passed {@code payload} is successfully*     handled, otherwise errors.*/Mono<Void> fireAndForget(Payload payload);/*** Request-Response interaction model of {@code RSocket}.** @param payload Request payload.* @return {@code Publisher} containing at most a single {@code Payload} representing the*     response.*/Mono<Payload> requestResponse(Payload payload);/*** Request-Stream interaction model of {@code RSocket}.** @param payload Request payload.* @return {@code Publisher} containing the stream of {@code Payload}s representing the response.*/Flux<Payload> requestStream(Payload payload);/*** Request-Channel interaction model of {@code RSocket}.** @param payloads Stream of request payloads.* @return Stream of response payloads.*/Flux<Payload> requestChannel(Publisher<Payload> payloads);

我们只需要在此基础上添加我们的 rpc 逻辑即可。

  • 从客户端视角看,框架建立连接之后,只需要将请求信息编码到 Payload 里,然后通过 requestStream 方法即可向服务端发起请求。
  • 从服务端视角看,rsocket 收到请求之后,会调用我们实现的 requestStream 方法,我们从 Payload 里解码得到请求信息之后,调用业务方法,然后拿到 Flux 类型的返回值即可。
  • 需要注意的是业务返回值一般是 Flux,而 RSocket 要求的是 Flux,所以我们需要通过 map operator 拦截业务数据,将 BizDO 编码为 Payload 才可以递交给我 RSocket。而 RSocket 会负责数据的传输和 reative 语义的实现。

经过上面的分析,我们知道了 Dubbo 如何基于 RSocket 实现了响应式编程的支持。有了响应式编程支持,业务可以更加方便的实现异步逻辑。

小结

当前 Dubbo 3.0 将提供具备当代特性(如响应性编程)的相关支持,同时汲取阿里内部 HSF 的设计长处来实现两者的融合,当前预览版的很多地方还在探讨中,希望大家能够积极反馈,我们都会虚心学习并参考。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins Tutorial

什么是Jenkins Jenkins是一个自动化平台&#xff0c;它允许你使用pipelines去部署应用。它也可以自动化其他任务。 BUILDTESTDEPLOYMENT Jenkins 架构 首先&#xff0c;你拥有一个Master Server&#xff0c;它控制pipelines和安排Build到你的Agent上&#xff1b; 其次&…

阿里云首次在ASPLOS'19发布重磅论文:揭秘帮助ECS快速迭代的热升级技术

第24届ACM编程语言和操作系统&#xff08;ASPLOS19&#xff09;&#xff0c;于2019年4月13日至17日&#xff0c;在普罗维登斯召开&#xff0c;阿里云高级技术专家郑晓代表团队在会上发表了技术报告。 论文主题为《Fast and Scalable VMM Live Upgrade in Large Cloud Infrastr…

痛!做C#半年,挣的不如做AI1个月?”看到第二句泪目……

前段时间在网上发现一个热门话题&#xff1a;“做开发一年&#xff0c;在北京月薪不到1万&#xff0c;有点迷茫。” 其中&#xff0c;这个回答我永远忘不了&#xff1a;来源&#xff1a;库库的派派知乎回答&#xff0c;已取得授权在这短短的一条信息里&#xff0c;小编佩服不…

联想电脑u盘安装Linux,如何使用u盘安装linux系统

ps: 请注意&#xff0c;硬盘不是软盘7. 选择您的U盘作为硬盘驱动器&#xff0c;然后写入usb hdd 8. 点击[写]三&#xff0c;安装系统1. 将U盘插入计算机2. 启动计算机并按住[F2]进入BIOS以修改第一个启动项3. 选择U盘后&#xff0c;跳转到以下界面4. 按键盘键进入第二个“测试…

源码|详解分布式事务之 Seata-Client 原理及流程

前言 在分布式系统中&#xff0c;分布式事务是一个必须要解决的问题&#xff0c;目前使用较多的是最终一致性方案。自年初阿里开源了Fescar&#xff08;四月初更名为Seata&#xff09;后&#xff0c;该项目受到了极大的关注&#xff0c;目前已接近 8000 Star。Seata 以高性能和…

SonarQube中配置c语言/c++语言代码规则插件

文章目录一、下载安装重新启动1. 下载文件2.安装3. 重新启动SonarQube4. SonarQube管控台验证二、SonarQube管控台配置2.1. 创建配置模板2.2. 添加规则2.3. 查看配置模板规则列表2.4. 修改默认语言规则应用2.5. C配置流程同上我是java出身,因为特殊需要,要用sonarqube做一套c代…

从虚拟化前端Bug学习分析Kernel Dump

前言 也许大家都知道&#xff0c;分析 Kernel Dump 有个常用的工具叫 Crash&#xff0c;在我刚开始学习分析 Kernel Dump 的时候&#xff0c;总是花大量的时间折腾这个工具的用法&#xff0c;却总是记不住这个工具的功能。后来有一次在参加某次内部分享的时候&#xff0c;有位…

Apache Shiro RememberMe 1.2.4 反序列化过程命令执行漏洞【原理扫描】

文章目录一、分析定位1. 漏洞描述2. 项目引发漏洞简述二、 若依系统2.1. 版本升级2.2. 配置文件2.3. 推荐做法2.4. 栗子2.5. 项目场景三、Gus系统3.1. shiro版本升级3.2. 调用重新生成3.3. 生成工具类shiro漏洞补充&#xff1a;一、分析定位 1. 漏洞描述 目前厂商已经发布了新…

Linux系统json文件打中文,如何在 Linux 终端上漂亮地打印 JSON 文件

JSON 文件非常棒&#xff0c;因为它们以人类可读的格式存储数据集合。然而&#xff0c;如果 JSON 文件被最小化过&#xff0c;那么阅读 JSON 文件可能会很痛苦。• 来源&#xff1a;linux.cn • 作者&#xff1a;Abhishek Prakash • 译者&#xff1a;geekpi •(本文字数&#…

超级干货!31 条2020 年最新版 ZooKeeper面试题,先收藏再看!| 博文精选

作者| ThinkWon责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;金三银四&#xff0c;虽然受疫情影响&#xff0c;大多数企业还未正式复工&#xff0c;但没有条件&#xff0c;创造条件也要上&#xff0c;许多企业已经开始物色合适的人才了&#…

Node.js 应用故障排查手册 —— 雪崩型内存泄漏问题

楔子 实践篇一中我们也看到了一个比较典型的由于开发者不当使用第三方库&#xff0c;而且在配置信息中携带了三方库本身使用不到的信息&#xff0c;导致了内存泄漏的案例&#xff0c;实际上类似这种相对缓慢的 Node.js 应用内存泄漏问题我们总是可以在合适的机会抓取堆快照进行…

检测到远端X服务正在运行中

文章目录一、 漏洞详情二、 解决方案2.1. 方案1(推荐使用)2.2. 方案2一、 漏洞详情 二、 解决方案 2.1. 方案1(推荐使用) 既然漏洞是6000端口导致的&#xff0c;首先要分析linux6000端口是谁在用呢、又和什么程序有关&#xff1f;如果没有用直接关掉6000端口即可&#xff0c;…

Kubernetes从懵圈到熟练:读懂这一篇,集群节点不下线

排查完全陌生的问题&#xff0c;完全不熟悉的系统组件&#xff0c;是售后工程师的一大工作乐趣&#xff0c;当然也是挑战。今天借这篇文章&#xff0c;跟大家分析一例这样的问题。排查过程中&#xff0c;需要理解一些自己完全陌生的组件&#xff0c;比如systemd和dbus。但是排查…

面试还搞不懂Redis,快看看这40道面试题!| 博文精选

作者| 程序员追风责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;近年来&#xff0c;微服务变得越来越热门&#xff0c;越来越多的应用部署在分布式环境中。常用的分布式实现方式之一就有 Redis。对于想要年后换东家的程序员来说&#xff0c;如…

阿里新一代分布式任务调度平台Schedulerx2.0破土而出

1. 产品简介 Schedulerx2.0是阿里中间件自研的基于Akka架构的新一代分布式任务调度平台&#xff0c;提供定时、任务编排、分布式跑批等功能。使用Schedulerx2.0&#xff0c;您可以在控制台配置管理您的定时任务&#xff0c;查询历史执行记录&#xff0c;查看运行日志。借助Sch…

阿里云POLARDB如何助力轻松筹打造5亿用户信赖的大病筹款平台?

轻松筹首创了“大病救助”模式&#xff0c;帮助了众多病患在第一时间解決了医疗资金等问题&#xff0c;为了从源头解决了医疗资金问题。而在轻松筹这样全球5.5亿用户信赖的大病筹款平台的背后&#xff0c;是日益增长的各种数据。面对这样数据量所造成的巨大挑战&#xff0c;阿里…

彻彻底底给你讲明白啥是SpringMvc异步处理

来源 | 编程新说责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;生活在这个世界上&#xff0c;我们必须承认任何事物都是运动变化着的&#xff0c;没有什么东西是一成不变的。不仅因为这句话是出自马克思主义哲学的唯物辩证法&#xff0c;而且事…

选择阿里云数据库HBase版十大理由

根据Gartner的预计&#xff0c;全球非关系型数据库&#xff08;NoSQL&#xff09;在2020~2022预计保持在30%左右高速增长&#xff0c;远高于数据库整体市场。 阿里云数据库HBase版也是踏着技术发展的节奏&#xff0c;伴随着NoSQL和大数据技术的兴起和发展&#xff0c;从2010年…

酷睿i7cpu适合的linux,CPU性能篇 - Core i7-4770K Linux之旅:有喜有忧_Linux新闻_Linux公社-Linux系统门户网站...

CPU性能篇——Rodinia是学术界经常使用的科学测试工具。OpenMP LavaMD负载中&#xff0c;4770K相比3770K快了12&#xff05;&#xff0c;8350表现也可以。OpenMP Leukocyte负载里&#xff0c;4770K对比3770K的优势依然有10&#xff05;&#xff0c;但是8350大亮了&#xff0c;竟…

GitOps:Kubernetes多集群环境下的高效CICD实践

为了解决传统应用升级缓慢、架构臃肿、不能快速迭代、故障不能快速定位、问题无法快速解决等问题&#xff0c;云原生这一概念横空出世。云原生可以改进应用开发的效率&#xff0c;改变企业的组织结构&#xff0c;甚至会在文化层面上直接影响一个公司的决策&#xff0c;可以说&a…