This is an automated email from the ASF dual-hosted git repository. liujun pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/dubbo-awesome.git
commit 032748651d14c86b7a7d5d19e8c8751e09b6175c Author: ken.lj <[email protected]> AuthorDate: Sat Apr 2 17:38:46 2022 +0800 init some columns: proposals and summerofcode --- .gitignore | 2 + images/mesh-mix.png | Bin 0 -> 332680 bytes images/mesh-thinsdk-1.png | Bin 0 -> 46448 bytes images/mesh-xds-1.png | Bin 0 -> 26318 bytes images/mesh-xds-2.png | Bin 0 -> 40196 bytes images/multi-instance.png | Bin 0 -> 193479 bytes images/observability-2.png | Bin 0 -> 24738 bytes images/observability.png | Bin 0 -> 24738 bytes proposals/D0-triple.md | 0 .../D1-application-level-service-discovery.md | 0 proposals/D1.1-service-discovery-reflection.md | 0 proposals/D2-multi-instances.md | 114 ++++++ proposals/D3-mesh.md | 48 +++ proposals/D3.1-thinsdk-sidecar-mesh.md | 94 +++++ proposals/D3.2-proxyless-mesh.md | 454 +++++++++++++++++++++ proposals/D4-observability.md | 125 ++++++ proposals/D5-router-chain.md | 0 proposals/D6-url.md | 0 proposals/D7-async.md | 0 proposals/D8-qos.md | 0 proposals/D9-backpressure.md | 0 summerofcode/cas-ospp/2022-idea-list.md | 90 ++++ summerofcode/gsoc/2022-idea-list.md | 13 + 23 files changed, 940 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cc2124 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.iml +.idea/ diff --git a/images/mesh-mix.png b/images/mesh-mix.png new file mode 100644 index 0000000..2a11eac Binary files /dev/null and b/images/mesh-mix.png differ diff --git a/images/mesh-thinsdk-1.png b/images/mesh-thinsdk-1.png new file mode 100644 index 0000000..e70cdcc Binary files /dev/null and b/images/mesh-thinsdk-1.png differ diff --git a/images/mesh-xds-1.png b/images/mesh-xds-1.png new file mode 100644 index 0000000..f402e1a Binary files /dev/null and b/images/mesh-xds-1.png differ diff --git a/images/mesh-xds-2.png b/images/mesh-xds-2.png new file mode 100644 index 0000000..b92d311 Binary files /dev/null and b/images/mesh-xds-2.png differ diff --git a/images/multi-instance.png b/images/multi-instance.png new file mode 100644 index 0000000..2194b6c Binary files /dev/null and b/images/multi-instance.png differ diff --git a/images/observability-2.png b/images/observability-2.png new file mode 100644 index 0000000..bf9679f Binary files /dev/null and b/images/observability-2.png differ diff --git a/images/observability.png b/images/observability.png new file mode 100644 index 0000000..bf9679f Binary files /dev/null and b/images/observability.png differ diff --git a/proposals/D0-triple.md b/proposals/D0-triple.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D1-application-level-service-discovery.md b/proposals/D1-application-level-service-discovery.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D1.1-service-discovery-reflection.md b/proposals/D1.1-service-discovery-reflection.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D2-multi-instances.md b/proposals/D2-multi-instances.md new file mode 100644 index 0000000..573eaf4 --- /dev/null +++ b/proposals/D2-multi-instances.md @@ -0,0 +1,114 @@ +# D2 - Multi-instances +* Authors: Albumen, Dewei Gong, Jun Liu + +## Objective +在本设计内,我们主要涉及的内容为Dubbo的指标体系,并且需要设计的内容总共涉及三块,指标收集、本地聚合、指标推送。 +* 指标收集:我们将Dubbo内部需要监控的指标推送至统一的Collector中进行存储。 +* 本地聚合:指标收集获取的均为基础指标,而一些分位数指标则需通过本地聚合计算得出。 +* 指标推送:收集和聚合后的指标通过一定的方式推送至第三方服务器,本文档只涉及Prometheus。 + +* 我们将原来的MetricsConfig配置重构后供可观测性使用,并且只有在柔性服务开启或者Metrics,Config配置存在的情况下才会开启指标收集的功能。 + +## Background +Java 提供的静态变量(static field)能力可以将持有对象引用的行为绑定到类上面来,这给开发者提供了巨大的便利。注入单例模式、工厂模式等设计模式的实现方案都依赖了静态变量的功能。通过使用静态变量,开发者可以在任何时间、任何地点简单地获取到所需要的对象信息。 + +```java +public class Test { + public static Object obj; +} +Test.obj = xxx; +``` + +在一直以来的 Dubbo 框架开发中,静态变量受到了广泛地应用,诸如使用一个全局共享的 ConfigManager 来存储全局配置信息、ServiceRepository 来存储服务信息,不论从中心化管理配置或者是参数获取的便利性的角度来说,这种设计都是最佳的。在 Dubbo 2.7 以前的所有版本,Dubbo 所需要的运行时配置信息都通过全局静态变量获取,通过 RPC 服务三元组(interface + version + group)的方式进行唯一定位。 + +但是随着 Dubbo 用户基数的不断扩大以及在阿里集团内由 Dubbo 作为内核的 HSF3 框架都对原来的这种设计模式提出了挑战。 + +对于开源用户,社区收到的诉求主要包括以下几点: +1. 在同一个应用内能够创建多个三元组一样的订阅。这个行为在 Dubbo 2.7 中虽然没有做强限制,但是由于 Dubbo 很多参数是取自全局的,而这个获取的索引使用的就是三元组。如果用户创建了两个三元组一样的订阅,他们的参数会被相互覆盖,地址推送等功能也会收到很大的影响。 +2. Java 提供了自定义 ClassLoader 的机制可以自定义指定类的加载器来源,但是对于 Dubbo 来说并没有去支持多 ClassLoader 的场景,在动态代理生成和序列化场景下都不支持 ClassLoader 切换的行为。 +3. Dubbo 众多的测试用例都共享了同一份配置信息,导致在进行单元测试的时候极为容易造成环境污染的问题。 + +对于阿里集团内大规模落地来说,我们遇到的问题主要有: +1. 阿里集团内有众多的中间件框架,这些框架提供了各种各样的类加载方式,同时业务方期望在同一应用内的配置等信息是相互隔离的。 +2. 一些业务方的定制逻辑需要支持动态热部署的模式,具体体现在动态对某个虚拟环境进行销毁,这需要 Dubbo 内的生命周期管理更加完善。 +3. 集团内有多个对 Spring 容器进行定制化开发的框架,需要 Dubbo 能够支持多个 Spring Context 独立管理生命周期的场景。 + +基于众多的这些原因,在八月初的时候我们决定对 Dubbo 的生命周期进行重构,经过一个月的紧张开发,目前社区版本已经完整支持了多实例化的功能,Dubbo 的生命周期也变得更加清晰。 + +## Related Proposals + +## Proposal +整个 Dubbo 多实例的设计我们按照了三层模型来配置,分别是 Framework 框架层、Application 应用层、Module 模块层。 + +[multi-instance](../images/multi-instance.png) + +基于三层机制,我们可以将 Dubbo 按照一定规则进行隔离: +1. Framework 与 Framework 之间完全隔离,相当于是使用了两个完全不同的 Dubbo 实例 +2. Application 与 Application 之间按照应用名进行隔离,但是相互有些地共享 Protocol、Serialization 层,目标是达到在同一个 dubbo 端口(20880)上可以承载多个应用,而每个应用独立上报地址信息。 +3. Module 与 Module 之间可以由用户自定义进行进行隔离,可以是热部署周期的一个状态、也可以是 Spring Context 的一个 Context。通过 Module,用户可以对 Dubbo 的生命周期粒度进行最小的管理。 + +为了实现 Dubbo 多实例化,Dubbo 框架内做的最多的变化是修改掉大部分的从静态变量中获取的参数的逻辑,最明显的逻辑是 Dubbo 内部用于参数传递的 URL 对象带上了 ScopeModel 状态,这个 ScopeModel 对应的就是上面提到的三层模型的具体数据承载对象。 + +### 使用方式 + +多实例重构版本之后的 Dubbo 对于大多数用户的使用来说是无感知的,改造后的 DubboBootstrap 已经变成一个独立的启动器,用户可以通过 DubboBootstrap 定制多实例的使用。 + +下面是使用多实例的一个简单的例子。 + +```java + ServiceConfig<DemoService> service = new ServiceConfig<>(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + + ReferenceConfig<DemoService> reference1 = new ReferenceConfig<>(); + reference1.setInterface(DemoService.class); + + ReferenceConfig<DemoService> reference2 = new ReferenceConfig<>(); + reference2.setInterface(DemoService.class); + + // 创建一个启动器(自动创建新 ApplicationModel) + DubboBootstrap bootstrap1 = DubboBootstrap.newInstance(); + // 指定应用名 + bootstrap1.application(new ApplicationConfig("dubbo-demo-app-1")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内发布服务 + .service(service) + .endModule() + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference1) + .endModule() + .start(); + + // 创建一个启动器(自动创建新 ApplicationModel) + DubboBootstrap bootstrap2 = DubboBootstrap.newInstance(); + // 指定应用名 + bootstrap2.application(new ApplicationConfig("dubbo-demo-app-2")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference2) + .endModule() + .start(); + + // stub1 与 stub2 是两个独立的订阅,互相隔离 + + // 订阅的 stub + DemoService stub1 = reference1.get(); + System.out.println(stub1.sayHello("Hello World!")); + + // 订阅的 stub + DemoService stub2 = reference2.get(); + System.out.println(stub2.sayHello("Hello World!")); + + bootstrap1.stop(); + bootstrap2.stop(); +``` + +这个例子对外发布了一个 DemoService 的服务,由 dubbo-demo-app-1 这个应用提供。同时我们创建了两个订阅,分别是在 dubbo-demo-app-1 应用和 dubbo-demo-app-2 应用中,然后我们去对两个订阅进行调用,得到预期的结果。 + +这里需要注意的是虽然两个订阅的服务信息是完全一致的,在多实例化改造后,这两个订阅对于消费端来说是完全隔离的,也就是在最新版本的 Dubbo 中是支持三元组一样的情况下通过变更参数来创建多个订阅的行为的了。 \ No newline at end of file diff --git a/proposals/D3-mesh.md b/proposals/D3-mesh.md new file mode 100644 index 0000000..28b997e --- /dev/null +++ b/proposals/D3-mesh.md @@ -0,0 +1,48 @@ +# Dubbo Mesh (draft) +* Authors: Zhongming Hua, Jun Liu + +## Objective +## Background +## Related Proposals +## Proposal +### 场景 +1. 场景一(适用不具备Dubbo SDK定制能力,并且完全没有接入Mesh的用户群体):Sidecar仅托管服务发现能力以及进出口流量,该群体有三种分支场景: + ○ 希望增加Sidecar组件,来完成Mesh改造。Sidecar仍然发现原有的注册中心(非kubernetes)内的服务,需要定制控制面来适配第三方注册中心。 + ○ 希望增加Sidecar组件,来完成Mesh改造。服务注册想要切换到控制面官方支持的注册中心,比如istio支持Kubernetes等,此时可以选择采用Dubbo内的 Kubernetes Registry方案。Sidecar发现Kubernetes内的服务。 + ○ 不希望增加Sidecar,来完成Mesh改造。 +2. 场景二(适用已经具备对 Dubbo SDK、数据面、控制面的定制能力,并且完全没有接入Mesh的用户群体):已经基于目前Dubbo版本,做了不同于社区方案的kubernetes 服务注册,比如服务注册模型在kubernetes中的存储模型和存储方式将不一定按照dubbo内的方案来执行。 + ○ 希望增加Sidecar组件,对接istio、Envoy等,来完成Mesh改造。 + ○ 希望不增加Sidecar组件,来完成Mesh改造。 + +### Mesh模式 + ● 完全Proxy Mesh模式 + ● 主次模式:Proxy Mesh回切到Proxyless Mesh模式(两种并存,主Proxy Mesh,次Proxyless Mesh) + ● 完全Proxyless Mesh模式 +#### Proxy Mesh(ThinSDK)模式 + 描述:Proxy Mesh有两种一种是Sidecar、另一种是集中式Proxy。(是否要考虑集中式Proxy的情况)注:下文提到的Proxy Mesh暂时都指代Sidecar模式。 + +方案:Proxy Mesh采用Dubbo内部的直连模式来完成Dubbo SDK与Sidecar之间的通信。 + +待做事项: +1. 缩小Dubbo SDK包(新增一个Dubbo ThinSDK Library,名字叫dubbo-thin.jar ??):dubbo-thin.jar应该更加专注于RPC本身。 + ○ 服务发现 + ○ 路由(Router、Loadbalance) + ○ 服务注册(Optional) + ○ 减少部分可观测性(Optional) + ■ Metrics数据上报,如果去掉Dubbo的Metrics上报,能会丢失应用于Sidecar之间的rt损耗等。 + ■ Tracing:可以去掉。 + ■ Logging:不能去掉。 +2. 减少不必要的类加载 +3. 梳理需要适配的内容: + ○ Cluster内比如merge功能 +4. 增强与Sidecar之间的交互(dubbo 、triple) + ○ 健康状态感知(心跳保活) + ○ 部分配置露出并且透传,比如timeout、retry等。(主要为请求链路上的配置) + ○ 广播模式配置透传 +5. 是否要加强Dubbo SDK侧对mesh的配置露出(待讨论):新增MeshConfig,将Dubbo内部的一些模型进行封装,比如sidecar之间的连接数(consumer的connections),改为与sidecar之间的连接数等,让mesh配置更加突出。 + +#### 主次模式 +无需缩小包 +方案一:采用新增容错策略、并新增恢复能力(恢复到Proxy Mesh模式) +方案二:通过心跳保活探测来触发切换能力,并通过重连来触发恢复Proxy Mesh模式的能力。 +#### Proxyless Mesh模式 diff --git a/proposals/D3.1-thinsdk-sidecar-mesh.md b/proposals/D3.1-thinsdk-sidecar-mesh.md new file mode 100644 index 0000000..a90987d --- /dev/null +++ b/proposals/D3.1-thinsdk-sidecar-mesh.md @@ -0,0 +1,94 @@ +# 3.1 Dubbo Thin SDK (draft) +* Authors: Zhongming Hua, Jun Liu + +## Objective +## Background +## Related Proposals +## Proposal + +### 四大流程的核心逻辑介绍 + +除了应用启动和服务注册流程以外,其他两大流程都是在直连模式下:服务发现以及服务调用流程。其中应用下线不单独列出来主要是优雅下线时候的处理 +#### 应用启动 +以下是应用启动的大致流程(省略了spring容器启动等与mesh无关的流程): +1. ApplicationDeployer #initialize():注册ShutdownHook ->开启配置中心 -> 加载应用配置 -> 初始化ModuleDeployer -> 开启元数据中心 +2. ApplicationDeployer #doStart():ModuleDeployer #start() +3. ModuleDeployer #start():ModuleDeployer #initialize() -> 暴露服务 -> 引用服务 +4. ApplicationDeployer #onModuleStarted():暴露 MetadataService 服务-> 上报元数据信息-> 注册应用实例地址 +#### 服务暴露 + 以下是服务暴露的流程: +1. 暴露 injvm 协议的服务 +2. 暴露 Triple 协议的服务 +3. 发起服务注册:registry 协议 +4. 暴露 MetadataService 服务 +5. 发起服务注册:service-discovery-registry 协议 +#### 服务发现 + 在应用启动中的服务引用过程包含了服务发现,以下是直连模式下的引用服务流程: + +1. TripleProtocol #refer +2. 创建 TripleInvoker 实例 +3. 与对端建连(ConnectionManager #connect) +4. 将 TripleInvoker 实例包装成ClusterInvoker,附加集群相关处理能力(Cluster #join) +5. 新增Cluster Interceptor(主要是附加一些容错策略、结果处理策略) +6. 推送consumer端元数据信息 +7. 创建代理 + +#### 服务调用 +1. InvokerInvocationHandler #invoke() +2. filter chain处理:ConsumerContextFilter 、FutureFilter 、MonitorFilter 、RouterSnapshotFilter +3. 执行 router chain(直连模式不需要路由) +4. 执行负载均衡策略(由于是直连一个sidecar,所以负载均衡策略没有效果):(AbstractClusterInvoker #select) +5. TripleInvoker #doInvoke() +6. DefaultFuture2 #received + +### 四大流程涉及的改造点 +#### 应用启动 + +● Dubbo应用进程与Sidecar生命周期对齐 +○ 正常启动后,让Sidecar感知到该Endpoint是健康的。 +■ 初步方案:Dubbo应用与Sidecar建连,并且发送POST /healthcheck/ok +○ 运行态:通过健康检查来保活 +○ Dubbo应用优雅下线时,需要能够让Sidecar感知到该Endpoint下线了。(应用所在的Container原地热升级、应用优雅下线等场景) +■ 初步方案:发送POST /healthcheck/fail +● 在启动过程中,除了生命周期对齐以外,其他主要需要做缩减的动作,对mesh主流程影响不大。 + +#### 健康检查 +运行态,通过envoy的健康检查来保证Dubbo应用是否正常。目前Triple协议基于gRPC的Health接口实现健康检查。需要支持Envoy的HTTP健康检查Filter: +● https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/health_check/v3/health_check.proto#envoy-v3-api-msg-extensions-filters-http-health-check-v3-healthcheck +● https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/health_check.proto +#### 服务注册 +istio中所支持的注册中心中成熟度最高的是Kubernetes,第一阶段推荐使用Kubernetes Registry。目前已经有Kubernetes Registry的实现,主要以 CRD 的方式存储到 Kubernetes 的 etcd 中: +● 元数据内容存储在annotation中。 +● 应用名对应 Kubernetes service模型。 +● hosts:{IDL service name}.{namespace}.svc.cluster.local +但是对于Kubernetes 服务注册还缺少了许多内容,应用级别的服务注册需要考虑interface name与应用名称的映射关系,除此之外还有自定义label、namespace等。需要增加对外的配置。 +#### 服务发现 +服务发现需要解决的问题是如何触发数据面的服务发现。目前Pilot的操作是在集群第一次启动时从Kubernetes中发现全量的Service、Workload数据,并将这些服务发现数据通过xDS下发给Envoy(Pilot-Agent)实例,后续则以增量的方式推送。 +在服务发现阶段,Dubbo应用仅仅与Envoy进行建连,并没有发起任何订阅的行为。 +#### 服务调用 +● 负载均衡策略的对接:交由Sidecar来做: +○ envoy支持的负载均衡策略:https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers +● 服务路由:路由规则的存储,将Kubernetes API Server作为Config Store,注册Kubernetes CRD资源来作为路由规则的存储。通过RDS下发路由规则到Sidecar,由Sidecar来做服务路由。 +○ 涉及到现有的路由规则如何迁移到istio中路由规则管控的问题。 +目前triple协议默认的header: + +[:scheme: http, :method: POST, :path: /org.apache.dubbo.demo.GreeterService/sayHello, :authority: 127.0.0.1:50051, grpc-accept-encoding: gzip, te: trailers, content-type: application/grpc+proto, tri-consumer-appname: dubbo-demo-triple-api-consumer] + +● 在进行服务调用时: +○ :authority会被识别成一个virtual host,需要适配 +○ 需要支持envoy header:https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#config-http-conn-man-headers-custom-request-headers +○ 需要支持envoy router的header:调用时支持Envoy router header:https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#id7 +○ 对比google grpc 和envoy grpc的差异,适配header内容:https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/grpc_service.proto.html#envoy-api-field-core-grpcservice-envoy-grpc + + + +### 会议目的: +● 确定第一阶段的目标 +● 讨论整体的方案 + +### 会议记录: +优雅下线的时候已经有相关的逻辑。 +接口级别的服务注册对接sidecar +多实例:应用。 +没有mesh 迁移到mesh的方案 +gRPC 相关的支持内容调研 \ No newline at end of file diff --git a/proposals/D3.2-proxyless-mesh.md b/proposals/D3.2-proxyless-mesh.md new file mode 100644 index 0000000..eb28174 --- /dev/null +++ b/proposals/D3.2-proxyless-mesh.md @@ -0,0 +1,454 @@ +# D3.2 - Dubbo Proxyless Mesh (draft) +* Authors: Albumen, Jun Liu + +## Objective +通过不同语言版本的 Dubbo3 SDK 直接实现 xDS 协议解析,实现 Dubbo 与 Control Plane 的直接通信,进而实现控制面对流量管控、服务治理、可观测性、安全等的统一管控,规避 Sidecar 模式带来的性能损耗与部署架构复杂性。 + +## Background +* [Service Mesh](https://istio.io/) +* [控制面 xDS & UDPA](https://github.com/cncf/udpa) + +经典的 Sidecar Mesh 部署架构有很多优势,如平滑升级、多语言、业务侵入小等,但也带来了一些额外的问题,比如: +- Proxy 带来的性能损耗,在复杂拓扑的网络调用中将变得尤其明显 +- 流量拦截带来的架构复杂性 +- Sidecar 生命周期管理 +- 部署环境受限,并不是所有环境都满足 Sidecar 流量拦截条件 +- 一定有更灵活的选择 + +针对 Sidecar Mesh 模型的问题,Dubbo 社区自很早之前就做了 Dubbo 直接对接到控制面的设想与思考,并在国内开源社区率先提出了 Proxyless Mesh 的概念,当然就 Proxyless 概念的说法而言,最开始是谷歌提出来的。 + +Proxyless 模式使得微服务又回到了 2.x 时代的部署架构,如上图所示,和我们上面看的 Dubbo 经典服务治理模式非常相似,所以说这个模式并不新鲜, Dubbo 从最开始就是这么样的设计模式。但相比于 Mesh 架构,Dubbo2 并没有强调控制面的统一管控,而这点恰好是 Service Mesh 所强调的,强调对流量、可观测性、证书等的标准化管控与治理,也是 Mesh 理念先进的地方。 + + +## Related Proposals + + +## Proposal + + + +在 Dubbo3 Proxyless 架构模式下,Dubbo 进程将直接与控制面通信,Dubbo 进程之间也继续保持直连通信模式,我们可以看出 Proxyless 架构的优势: + +- 没有额外的 Proxy 中转损耗,因此更适用于性能敏感应用 +- 更有利于遗留系统的平滑迁移 +- 架构简单,容易运维部署 +- 适用于几乎所有的部署环境 + +### Architecture + + +### Details + +1. xDS 官方说明 + +https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol + +● Listener Discovery Service (LDS): Returns Listener resources. Used basically as a convenient root for the gRPC client's configuration. Points to the RouteConfiguration. +● Route Discovery Service (RDS): Returns RouteConfiguration resources. Provides data used to populate the gRPC service config. Points to the Cluster. +● Cluster Discovery Service (CDS): Returns Cluster resources. Configures things like load balancing policy and load reporting. Points to the ClusterLoadAssignment. +● Endpoint Discovery Service (EDS): Returns ClusterLoadAssignment resources. Configures the set of endpoints (backend servers) to load balance across and may tell the client to drop requests. + +2. 协议基础:protobuf + gRPC + +实现方案 1:使用 io.grpc 的依赖手动创建原生 gRPC 服务 +实现方案 2:使用 Dubbo 3.0 的新协议 + +3. 测试环境控制平面 mock + +Envoy 提供的 Java 实例控制平面 https://github.com/envoyproxy/java-control-plane + +4. Java 版协议支持 + +Envoy 提供的 Java 版控制平面 API https://search.maven.org/search?q=g:io.envoyproxy.controlplane + +协议可利用内容 + +● LDS: envoy.api.v2.Listener +● RDS: envoy.api.v2.RouteConfiguration +● CDS: envoy.api.v2.Cluster +● EDS: envoy.api.v2.ClusterLoadAssignment + +LDS + +Listener 发现协议,在 sidecar 部署模式下用户配置本地监听器,由于 Dubbo 去接入 xDS 本身就是一个 proxy-less 的模式,所以 LDS 很多的配置是不需要考虑的。 +针对 LDS 协议,需要做的有获取适配的监听器用于获取路由配置。 +对于 LDS 协议,有些控制平面并不能保证获取到的监听器是唯一的,所以需要兼容获取到多个监听器时的配置情况。 + +RDS + +Route 发现协议,通过路由配置可以对请求的地址进行匹配,经过一定的策略后获取对应的上游 Cluster 集群。 +针对 RDS 协议,可以在基于 Listener 监听器的配置,获取到一组对应的路由协议。然后根据服务自省框架对应的服务名筛选出对应的 Cluster 集群。 +对于 RDS 协议,有些控制平面并不能保证获取到的l路由组是唯一的,所以需要兼容获取到多个路由组时的配置情况。 +在 RDS 的结果中包括了流控还有重试的配置,这些可以作为路由配置和负载均衡部分的默认配置来源。 + +CDS + +Cluster 发现协议,可以获取到对应集群内的配置(如超时时间、重试限制、元数据信息等),是基于 RDS 获取的。 +CDS 的结果可以作为路由配置和负载均衡部分的配置来源。 + +EDS + +Endpoint 发现协议,可以获取到集群中对应节点信息,即是服务间通信的底层节点信息。 +通过 EDS 的结果,可以获取到对应的节点地址信息、权重信息、健康信息,进而组成服务自省框架最基础的实例信息。 + +接入模型设计 + +采用注册中心的模式对接,配置通过 ServiceInstance 运行时配置传出,通过 Invoker 传递到服务调用时。 + +服务发现逻辑 + +xDS 接入以注册中心的模式对接,节点发现同其他注册中心的服务自省模型一样,对于 xDS 的负载均衡和路由配置通过 ServiceInstance 的动态运行时配置传出,在构建 Invoker 的时候将配置参数传入配置地址。 + + +服务调用逻辑 + +在 RPC 调用链路中,当获取负载均衡策略时根据 Invoker 的参数信息构建负载均衡信息(适配 EDS 的权重信息),对于集群的重试逻辑配置则工具 RDS 和 CDS 的配置进行修改。 + +协议内容示例 + +LDS + +获取默认本地监听器,根据 Dubbo 支持的 RPC 协议读取过滤链中对应 "routeConfigName" 字段 +```json +{ + "name": "0.0.0.0_9080", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9080 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "http/1.0", + "http/1.1", + "h2c" + ] + }, + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "outbound_0.0.0.0_9080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "9080" + }, + "httpFilters": ···, + "tracing": { + "clientSampling": { + "value": 100 + }, + "randomSampling": { + "value": 100 + }, + "overallSampling": { + "value": 100 + } + }, + "streamIdleTimeout": "0s", + "accessLog": ···, + "useRemoteAddress": false, + "generateRequestId": true, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ], + "normalizePath": true + } + } + ] + }, + { + "filterChainMatch": {}, + "filters": ···, + "name": "PassthroughFilterChain" + } + ], + "deprecatedV1": { + "bindToPort": false + }, + "listenerFilters": [ + ··· + ], + "listenerFiltersTimeout": "5s", + "continueOnListenerFiltersTimeout": true, + "trafficDirection": "OUTBOUND" +} +``` + + +RDS + +根据 LDS 的 "routeConfigName" 参数获取 RDS +匹配服务名和 "domains" 字段,读取 "cluster" 字段 +```json +{ + "name": "9080", + "virtualHosts": [ + ···, + { + "name": "details.default.svc.cluster.local:9080", + "domains": [ + "details.default.svc.cluster.local", + "details.default.svc.cluster.local:9080", + "details", + "details:9080", + "details.default.svc.cluster", + "details.default.svc.cluster:9080", + "details.default.svc", + "details.default.svc:9080", + "details.default", + "details.default:9080", + "172.20.206.174", + "172.20.206.174:9080" + ], + "routes": [ + { + "name": "default", + "match": { + "prefix": "/" + }, + "route": { + "cluster": "outbound|9080||details.default.svc.cluster.local", + "timeout": "0s", + "retryPolicy": { + "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", + "numRetries": 2, + "retryHostPredicate": [ + { + "name": "envoy.retry_host_predicates.previous_hosts" + } + ], + "hostSelectionRetryMaxAttempts": "5", + "retriableStatusCodes": [ + 503 + ] + }, + "maxGrpcTimeout": "0s" + }, + "decorator": { + "operation": "details.default.svc.cluster.local:9080/*" + } + } + ], + "includeRequestAttemptCount": true + }, + { + "name": "productpage.default.svc.cluster.local:9080", + "domains": [ + "productpage.default.svc.cluster.local", + "productpage.default.svc.cluster.local:9080", + "productpage", + "productpage:9080", + "productpage.default.svc.cluster", + "productpage.default.svc.cluster:9080", + "productpage.default.svc", + "productpage.default.svc:9080", + "productpage.default", + "productpage.default:9080", + "172.20.132.203", + "172.20.132.203:9080" + ], + "routes": [ + { + "name": "default", + "match": { + "prefix": "/" + }, + "route": { + "cluster": "outbound|9080||productpage.default.svc.cluster.local", + "timeout": "0s", + "retryPolicy": { + "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", + "numRetries": 2, + "retryHostPredicate": [ + { + "name": "envoy.retry_host_predicates.previous_hosts" + } + ], + "hostSelectionRetryMaxAttempts": "5", + "retriableStatusCodes": [ + 503 + ] + }, + "maxGrpcTimeout": "0s" + }, + "decorator": { + "operation": "productpage.default.svc.cluster.local:9080/*" + } + } + ], + "includeRequestAttemptCount": true + }, + { + "name": "ratings.default.svc.cluster.local:9080", + "domains": [ + "ratings.default.svc.cluster.local", + "ratings.default.svc.cluster.local:9080", + "ratings", + "ratings:9080", + "ratings.default.svc.cluster", + "ratings.default.svc.cluster:9080", + "ratings.default.svc", + "ratings.default.svc:9080", + "ratings.default", + "ratings.default:9080", + "172.20.66.58", + "172.20.66.58:9080" + ], + "routes": [ + { + "name": "default", + "match": { + "prefix": "/" + }, + "route": { + "cluster": "outbound|9080||ratings.default.svc.cluster.local", + "timeout": "0s", + "retryPolicy": { + "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", + "numRetries": 2, + "retryHostPredicate": [ + { + "name": "envoy.retry_host_predicates.previous_hosts" + } + ], + "hostSelectionRetryMaxAttempts": "5", + "retriableStatusCodes": [ + 503 + ] + }, + "maxGrpcTimeout": "0s" + }, + "decorator": { + "operation": "ratings.default.svc.cluster.local:9080/*" + } + } + ], + "includeRequestAttemptCount": true + }, + { + "name": "reviews.default.svc.cluster.local:9080", + "domains": [ + "reviews.default.svc.cluster.local", + "reviews.default.svc.cluster.local:9080", + "reviews", + "reviews:9080", + "reviews.default.svc.cluster", + "reviews.default.svc.cluster:9080", + "reviews.default.svc", + "reviews.default.svc:9080", + "reviews.default", + "reviews.default:9080", + "172.20.193.13", + "172.20.193.13:9080" + ], + "routes": [ + { + "name": "default", + "match": { + "prefix": "/" + }, + "route": { + "cluster": "outbound|9080||reviews.default.svc.cluster.local", + "timeout": "0s", + "retryPolicy": { + "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", + "numRetries": 2, + "retryHostPredicate": [ + { + "name": "envoy.retry_host_predicates.previous_hosts" + } + ], + "hostSelectionRetryMaxAttempts": "5", + "retriableStatusCodes": [ + 503 + ] + }, + "maxGrpcTimeout": "0s" + }, + "decorator": { + "operation": "reviews.default.svc.cluster.local:9080/*" + } + } + ], + "includeRequestAttemptCount": true + } + ], + "validateClusters": false +} +``` + +CDS + +根据 "cluster" 字段获取集群配置信息 + +```json +{ + "transportSocketMatches": ···, + "name": "outbound|9080||details.default.svc.cluster.local", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "serviceName": "outbound|9080||details.default.svc.cluster.local" + }, + "connectTimeout": "10s", + "circuitBreakers": { + "thresholds": [ + { + "maxConnections": 4294967295, + "maxPendingRequests": 4294967295, + "maxRequests": 4294967295, + "maxRetries": 4294967295 + } + ] + }, + "metadata": { + "filterMetadata": { + "istio": { + "config": "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/details" + } + } + }, + "filters": ··· +} +``` + +EDS + +根据 "cluster" 字段获取节点信息 + +```json +{ + "name": "outbound|9080||ratings.default.svc.cluster.local", + "addedViaApi": true, + "hostStatuses": [ + { + "address": { + "socketAddress": { + "address": "172.21.128.222", + "portValue": 9080 + } + }, + "stats": ···, + "healthStatus": { + "edsHealthStatus": "HEALTHY" + }, + "weight": 1, + "locality": {} + } + ] +} +``` + diff --git a/proposals/D4-observability.md b/proposals/D4-observability.md new file mode 100644 index 0000000..732853a --- /dev/null +++ b/proposals/D4-observability.md @@ -0,0 +1,125 @@ +# D4 - Observability +* Authors: Zhiguo Wu, Dewei Gong, Jun Liu + +## Objective +在本设计内,我们主要涉及的内容为Dubbo的指标体系,并且需要设计的内容总共涉及三块,指标收集、本地聚合、指标推送。 +* 指标收集:我们将Dubbo内部需要监控的指标推送至统一的Collector中进行存储。 +* 本地聚合:指标收集获取的均为基础指标,而一些分位数指标则需通过本地聚合计算得出。 +* 指标推送:收集和聚合后的指标通过一定的方式推送至第三方服务器,本文档只涉及Prometheus。 + +* 我们将原来的MetricsConfig配置重构后供可观测性使用,并且只有在柔性服务开启或者Metrics,Config配置存在的情况下才会开启指标收集的功能。 + +## Background +## Related Proposals +[backpressure](./D9-backpressure.md) +## Proposal +### 指标收集 +指标通过common模块下的MetricsCollector存储所有指标数据,供柔性服务、指标推送获取。 +收集指标时,默认只收集基础指标,而一些单机聚合指标则需要开启服务柔性或者本地聚合后另起线程计算。此处若开启服务柔性,则本地聚合默认开启。且柔性服务依赖本地聚合的数据。 +柔性服务开启方式暂定。 + +本地聚合开启方式: +```xml +<dubbo:metrics> + <dubbo:aggregation enable="true" /> +</dubbo:metrics> +``` + +### 基础指标 +基础指标此处不建议收集太具体的指标,更具体的指标可通过Prometheus的Promql计算获得,或者通过开启本地聚合,另起线程计算。 + +**基础指标目前暂定以下:** +总请求数、总成功数、总失败数、正在处理的请求数、线程数、请求响应时间(补充中。。。) + +**数据流转** +在common包下定义MetricsCollector来收集Dubbo内部各类指标,若开启本地聚合则另起线程,基于MetricsCollector内已存在指标进行统计计算后再次写入该类中。 +若开启了本地聚合,则指标接口(仿照MetadataService写一个MetricsService)从MetricsCollector中获取其需要的数据。 +若开启了指标推送(Prometheus为例),则Prometheus SPI中将common包下Dubbo自定义的指标类(如Counter、Gauge等)转换为Prometheus自己的指标类。最后通过用户配置的推送方式(pull、push)来将指标推送至Prometheus服务器中。 + +具体如下图所示。 + + +### 指标聚合 +其中指标聚合大部分需要通过滑动窗口计算,此处先介绍采用的滑动窗口算法 +### 滑动窗口 +此处滑动窗口以Prometheus JavaClient的TimeWindowQuantiles为例 +假设我们初始有6个bucket,每个窗口时间设置为2分钟 +每次写入指标数据时,我们会将数据分别写入6个bucket内。每隔两分钟移动一个bucket并且清除原来bucket内的数据。 +读取指标时,我们读取当前current指向的bucket,以达到滑动窗口的效果。 +具体如下图所示。 + + + +在每个bucket内,我们计算分位数指标时也有3种常用算法可选用 +1、TDigest(极端分位精确度高,如p1 p99,中间分位精确度低,如p50。推荐使用该方式) + 1.1、https://op8867555.github.io/posts/2018-04-09-tdigest.html +1.2、https://blog.csdn.net/csdnnews/article/details/116246540 +1.3、开源实现:https://github.com/tdunning/t-digest +2、HdrHistogram(精确度低) +2.1、https://caorong.github.io/2016/07/31/hdrhistogram/ +2.2、开源实现:https://github.com/HdrHistogram/HdrHistogram +3、CKMS(允许一定错误率,由用户自己设置,Prometheus的TimeWindowQuantiles内部使用了该算法。资料偏少,大致看看即可) +3.1、https://caorong.github.io/2020/08/03/quartile-%20algorithm/ +3.2、https://www.stevenengelhardt.com/2018/03/29/calculating-percentiles-on-streaming-data-part-7-cormode-korn-muthukrishnan-srivastava/ +3.3、http://dimacs.rutgers.edu/~graham/pubs/papers/bquant-icde.pdf + +**参数设计** +指标聚合参数: +```xml +<dubbo:metrics> + <dubbo:aggregation enable="true" bucket-num="5" time-window-seconds="10"/> +</dubbo:metrics> +``` + +由于聚合指标的计算消耗较大,故在本地聚合开启时,Dubbo内部会开启另外的线程做指标的聚合计算,获取更精确的分位数指标。 + +### 本地聚合 +本地聚合指将一些简单的指标通过计算获取各分位数指标的过程。 + +**具体指标** +* qps: 基于滑动窗口获取动态qps +* rt: 基于滑动窗口获取动态rt +* 失败请求数: 基于滑动窗口获取最近时间内的失败请求数 +* 成功请求数: 基于滑动窗口获取最近时间内的成功请求数 +* 处理中请求数: 前后增加Filter简单统计即可 +*(补充中。。。) + +**指标接口** +指标接口将提供一个类似于MetadataService的MetricsService,该Service不仅提供柔性服务所需的接口级数据,也提供所有指标的查询方式。 +其中方法级指标的查询的接口可按如下方式声明 + +```java +public class MethodMetrics { + private Integer qps; + private Quantile rt; + private Integer succeed; + private Integer failed; + private Integer processing; +} + +public class Quantile { + private Double p99; + private Double p95; + private Double max; + private Double avg; + private Double min; + private Double last; +} +``` + +### 指标推送 +指标推送只有用户在设置了<dubbo:metrics />配置且配置protocol参数后才开启,若只开启指标聚合,则默认不推送指标。 +Promehteus Pull ServiceDiscovery +● 使用dubbo-admin等类似的中间层,启动时根据配置将本机 IP、Port、MetricsURL 推送地址信息至dubbo-admin(或任意中间层)的方式,暴露HTTP ServiceDiscovery供prometheus读取,配置方式如<dubbo:metrics protocol="prometheus" mode="pull" address="${dubbo-admin.address}" port="20888" url="/metrics"/>,其中在pull模式下address为可选参数,若不填则需用户手动在Prometheus配置文件中配置地址 +○ 优点:稳定,并且能通过中间层移除已下线的应用,只保留存活应用供Prometheus读取 +○ 缺点:不够轻量,如果用户没有使用dubbo-admin则必须引入。如果用户自己实现了dubbo控制台则需提供类似http-sd-starter模块供集成,并且该模块需实现健康检查代码,检测已下线的dubbo应用并移除 +Prometheus Push Pushgateway +● 用户直接在Dubbo配置文件中配置Prometheus Pushgateway的地址即可,如<dubbo:metrics protocol="prometheus" mode="push" address="${prometheus.pushgateway-url}" interval="5" />,其中interval代表推送间隔 +○ 优点:方便,用户只需要引入依赖,并加上这一行配置即可直接采集指标 +○ 缺点:Push方式Prometheus无法自动删除已下线的应用的指标,需要用户手动处理 + +### 整体结构设计 +1、移除原来与 Metrics 相关的类 +2、创建新模块 dubbo-metrics/dubbo-metrics-api、dubbo-metrics/dubbo-metrics-prometheus,MetricsConfig 作为该模块的配置类 +3、若不使用micrometer,则在common模块下实现自己的Counter、Gauge等,并在dubbo-metrics/dubbo-metrics-prometheus手动转换成prometheus对应的类型 +4、若使用micrometer,则Collector中使用基本类型代表指标,如Long、Double等,并在dubbo-metrics-api中引入micrometer,由micrometer对内部指标进行转换 \ No newline at end of file diff --git a/proposals/D5-router-chain.md b/proposals/D5-router-chain.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D6-url.md b/proposals/D6-url.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D7-async.md b/proposals/D7-async.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D8-qos.md b/proposals/D8-qos.md new file mode 100644 index 0000000..e69de29 diff --git a/proposals/D9-backpressure.md b/proposals/D9-backpressure.md new file mode 100644 index 0000000..e69de29 diff --git a/summerofcode/cas-ospp/2022-idea-list.md b/summerofcode/cas-ospp/2022-idea-list.md new file mode 100644 index 0000000..e02710b --- /dev/null +++ b/summerofcode/cas-ospp/2022-idea-list.md @@ -0,0 +1,90 @@ +## tls证书中心化管理滚动更新 + +Dubbo 作为一个 RPC 框架,在处理请求的时候只能无条件(即使采用 token 鉴权机制)认为来自对端的数据是可信的,因此如果 Dubbo 传输的数据被中间人截获,将对 Dubbo 请求的处理造成严重的影响。而基于连接的 TLS 机制可以很好的解决这个问题,但是当前 Dubbo 对于证书的管理较为简单,也无法适配动态证书生效的情况,因此需要一个中心化的组件来管控 Dubbo 的证书,基于可信通道下发认证信息。基于此 Dubbo 可以做到将节点的连接暴露的互联网中进行通信,降低节点间通信成本,和提高应用间可信程度。 + +参考:mTLS 机制 + +## 端口协议复用 + +一个端口支持多种协议可以使部署和运维更为方便,甚至在一些特殊的开发场景也能降低复杂度。例如:一个业务逻辑需要提供给不同语言、不同业务方进行调用。 +当前大多数 rpc 框架均不支持该逻辑(包括 Dubbo) +以 Dubbo 举例,使用Triple 协议并开启所有默认服务,会开启如下默认端口 +● Triple: 50051 +● Metadata : 20880 +● Qos: 22222 +如果后续增加其他功能可能还会更多,这很不优雅,并且还启动了多个 Netty Server,造成了资源浪费。 +如果本地需要测试,在不修改配置的情况下端口会冲突导致启动失败,体验很差。 +目标 +实现服务端同端口多协议暴露,将各种协议服务使用一种统一的方式使用同一个 Netty Server 进行暴露 +● 将Qos 协议和 Triple 协议使用同一个端口暴露 +● (Optional)将 Dubbo 的其他协议进行接入 +1. 对于协议切换/架构升级的场景,通常需要同时暴露多个协议,单端口多协议能最大程度上带来运维的便捷性。 +2. 从后端开发的角度一套业务代码加少许配置就能暴露多个端口也能带来降低开发成本 + 目前 Dubbo 支持一个应用对外发布多种 RPC 协议,但这些 RPC 协议都需要独立占用一个服务端端口,另外 Dubbo QoS 也同样占用了一个端口。维护这些端口的监听需要消耗一定的资源,同时暴露多端口对于运维也存在一定复杂度,如 VIP /域名等。因此可以通过在同一个端口支持多种复用协议来降低复杂度,提高易用性。 + Background + One port supports multiple protocols, which makes deployment and operation and maintenance more convenient and simple, and even reduces complexity in special development scenarios. For example, a business logic needs to be provided to different languages and different business parties for invocation. + Most current RPC frameworks do not support this logic (including Dubbo). + Taking Dubbo as an example, using the Triple protocol and enabled all default services will open the following default ports. + ● Triple: 50051 + ● Metadata : 20880 + ● Qos: 22222 + If other functions are added in the future, there may be more, which is very inelegant, and multiple Netty Servers are also started, resulting in a waste of resources. + If you need to test locally, the port conflict will cause the startup to fail without modifying the configuration, and the experience is very poor. + Goal + Implement multi-protocol exposure on the same port on the server side, and expose various protocol services using the same Netty Server in a unified way. + ● Expose the QoS protocol and the Triple protocol using the same port + ● (optional)Implement other protocols of Dubbo in this way. + Meaning + ● Start the various protocol services in a unified manner + ● Support the same port exposed multiple protocols + Before + ● Netty + +## 优雅下线 + 对于部署了 Dubbo 服务的应用,由于应用发布需要重启进程,这个时候很多在途请求会由于进程的关闭而失败。因此 Dubbo 需要一种机制,在应用进程退出前通知所有的消费端不再发起新的请求,同时等待所有在途请求结束后再关闭进程。 + +## 完善故障排查机制与流程 + +当前 Dubbo 在使用的时候由于环境等种种原因,可能会出现如地址找不到、请求超时等异常。在大多数地方都有日志进行记录,本项目希望能为 Dubbo 提供一种快速的故障排查机制,包括但不限于在日志中透出排查网页信息、故障排查码,亦或者是自动感知上下文情况自动分析获取解决办法等。 + +admin api 迁移 qos 去中心化管控 + +Dubbo 拥有多种治理规则,如基于标签路由等,这些规则都是基于 Dubbo Admin 中心化进行管控。本题目希望将 Dubbo Admin 的 API 迁移到 Dubbo QoS 中,以此来达到不需要部署 Dubbo Admin 的后端程序即可对集群进行管控的目的。 + +## 对外暴露的 API 信息控制 + +在 Dubbo 版本迭代过程中,内部相互依赖的接口签名很容易被改动。但是这些仅 Dubbo 内部使用的 API 很多被用户误使用。为了更好地控制 Dubbo 对外暴露的 API 信息,Dubbo 希望将 API 分类为三种类型:暴露给用户开放使用的、内部 Dubbo 使用的、单元测试使用的。基于此在 Dubbo 编译的时候进行强制卡点,避免用户依赖内部使用的 API。 + +参考:Guava 的 VisibleForTesting 和 kolin 的 OptIn、JDK9 中开始提供的 module 机制 + +## dubbo-website 界面交互优化 + + +## 性能调优:Profiling & Benchmark +在选型 RPC 框架时,性能是用户关心的一个核心因素,好的 RPC 框架一方面可以减少长尾请求,提供可预测的稳定响应时间,另一方面是单次调用响应时间最少。 这对于提升终端用户的体验以及降低界面加载速度来说是至关重要的。 +从框架内部看,对于一个成熟的框架,内部也需要通过微基准测试的方式来保证内部处理是趋向最优的。这样在发布版本或提交 PR 时,能够简单直观的发现框架的性能是否有所下降,也能更快的定位到修改点对最终性能的影响。通过这种方式也能鼓励那些喜欢性能调优的外部人员参与到社区内部,来为开源社区贡献自己的一份力量,从而进一步促进社区的稳定发展和运行。 +目前 Dubbo 缺少全局上和框架内部的性能数据。提供完善的性能测试套件和微基准测试套件能够给所有 Dubbo 用户和开发者更加直观的理解 Dubbo 的性能,并写出性能友好的代码。Benchamrk 能够方便用户调研框架以及开发者进行框架开发和性能调优,有利于框架的发展和让用户使用 Dubbo。 + +目标: +增加 Dubbo Java/ GO 的 benchmark ,包括但不限于 Triple / Dubbo 协议 / 内部框架实现,方式可以是微基准测试或提供 Profiling 的工具/脚本。 + + +## Dubbo Reactive Stream +Reactive Stream 提供了一套标准的异步流处理 API, 在能够让应用写出事件驱动的程序的同时,也通过 backpressure 的方式保证了节点的稳定。Triple 协议在通信协议层面为 Dubbo 框架增加了流式场景的支持,在此基础上能够实现上层包括大文件传输和推送机制的业务需求。但目前的用户 API 较为原始,需要用户实现 StreamObserver 。而 Reactive Stream 作为反应式编程的事实标准,反压策略也能最大程度的保证处理大规模流数据时不会产生 Buffer Overflow 。Dubbo + Reactive Stream Stub的组合模式可以给用户带来最方便的流式使用方式以及全链路异步性能提升。 + +目标 +Dubbo Compiler 的 code generator 支持生成 Reative Stream Stub API ,如 reactor / rxjava ,提供相应使用文档和实例,支持 backpressure + +## Triple stub generator +### Describe the proposal +Gradle is a promising build tool for modern jvm language users, we shoulde support it when users using dubbo. +Dubbo has a maven compiler plugin for generating protos, but the [protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) does not support specifing `MainClass` . So Dubbo's compiler can not work with gradle. Hoping anyone can help to fix it. + +Here are some candidate solutions +- Publish multiple maven plugins with determined `MainClass` +- Write a build script template for generating Dubbo proto files +- Write a plugin like [akka](https://plugins.gradle.org/plugin/com.lightbend.akka.grpc.gradle) +- Support `MainClass` in `protobuf-gradle-plugin` + + + diff --git a/summerofcode/gsoc/2022-idea-list.md b/summerofcode/gsoc/2022-idea-list.md new file mode 100644 index 0000000..2bc101b --- /dev/null +++ b/summerofcode/gsoc/2022-idea-list.md @@ -0,0 +1,13 @@ +## 可观测性 +Github Issue +## Proxyless Mesh +## Proxy Mesh - Thin SDK +## admin api 迁移 qos 去中心化管控 +## 服务治理场景化用例设计 +[Github Issue]() + +**任务描述** +Dubbo 拥有多种治理规则,如基于标签路由、条件路由等,但是这些治理规则的使用具有一定的难度,用户也很难直观的了解到其对应的使用场景。因此 Dubbo 期望有这样的一些场景化的用例能够体现 Dubbo 的治理能力,帮助用户将治理规则迁移到真实业务场景中使用。 + +**参考:** +Istio 中 bookinfo 应用
