Skip to content
Permalink
Browse files
修正文档 (#886)
  • Loading branch information
diaoxiong committed Aug 2, 2021
1 parent 8eabe9d commit ccc069d763b2641ab8d2af368f9243d8c2eff74d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 52 deletions.
@@ -142,6 +142,76 @@ The above class would be encapsulated to be a `AbstractProxyInvoker` instance, a

![/dev-guide/images/dubbo_protocol_header.jpg](/imgs/dev/dubbo_protocol_header.png)

- Magic - Magic High & Magic Low (16 bits)

Identify protocol version, Dubbo protocol: 0xdabb

- Req/Res (1 bit)

Identify a request or response. request: 1; response: 0.

- 2 Way (1 bit)

Only useful when Req/Res is 1(request), identifying if you expect to return a value from the server. Set to 1 if a return value from the server is required.

- Event (1 bit)

Identifies whether it is an event message, for example, a heartbeat event. Set to 1 if this is an event.

- Serialization ID (5 bit)

Identifies the serialization type: for example, the value of fastjson is 6.

- Status (8 bits)

Only useful when Req/Res is 0 (response), used to identify the status of the response

- 20 - OK
- 30 - CLIENT_TIMEOUT
- 31 - SERVER_TIMEOUT
- 40 - BAD_REQUEST
- 50 - BAD_RESPONSE
- 60 - SERVICE_NOT_FOUND
- 70 - SERVICE_ERROR
- 80 - SERVER_ERROR
- 90 - CLIENT_ERROR
- 100 - SERVER_THREADPOOL_EXHAUSTED_ERROR

- Request ID (64 bits)

Identifies the only request, the type is long.

- Data Length (32 bits)

The length of the serialized content (variable part), counted in bytes, the type is int.

- Variable Part

After being serialized by a specific serialization type (identified by the serialization ID), each part is a byte [] or byte.

- If it is a request packet (Req/Res = 1), each part is:
- Dubbo version
- Service name
- Service version
- Method name
- Method parameter types
- Method arguments
- Attachments
- If it is a response packet (Req/Res = 0), each part is:
- Return value's type (byte), identifying the type of value returned from the server:
- Return null: RESPONSE_NULL_VALUE 2
- Normal response value: RESPONSE_VALUE 1
- Exception: RESPONSE_WITH_EXCEPTION 0
- Return value: response bytes returned from the server

**Note:** For the variable part, when uses json serialization in current version of Dubbo framework, an additional line break is added as a separator between each part of the content. Please add a new line break after each part of the variable part, such as:

```
Dubbo version bytes (line break)
Service name bytes (line break)
...
```

### Thread dispatch model

![/dev-guide/images/dubbo-protocol.jpg](/imgs/dev/dubbo-protocol.jpg)
@@ -179,7 +179,7 @@ Wheel wheel = wheelMaker.makeWheel(url);
// ...
```

时,注入的 `Adaptive` 实例可以提取事先定义好的 Key 来决定使用哪个 `WheelMaker` 实现来调用对应实现的真正的 `makeWheel` 方法。如提取 `wheel.type` Key,即 `url.get("wheel.type")` 来决定 `WheelMaker` 实现。`Adaptive` 实例的逻辑是固定,从 URL 中提取事先定义好的 Key,动态生成真正的实现并执行它。
时,注入的 `Adaptive` 实例可以提取事先定义好的 Key 来决定使用哪个 `WheelMaker` 实现来调用对应实现的真正的 `makeWheel` 方法。如提取 `wheel.type` Key,即 `url.get("wheel.type")` 来决定 `WheelMaker` 实现。`Adaptive` 实例的逻辑是固定的,从 URL 中提取事先定义好的 Key,动态生成真正的实现并执行它。

`ExtensionLoader` 里面的扩展点注入的 `Adaptive` 实现是在dubbo加载扩展点时动态生成的。Key是从URL中获取的,而URL中Key的值是在扩展点接口的方法定义上通过@Adaptive注解提供的。

@@ -240,4 +240,3 @@ public class XxxFilter implements Filter {
[^1]: 注意:这里的配置文件是放在你自己的 jar 包内,不是 dubbo 本身的 jar 包内,Dubbo 会全 ClassPath 扫描所有 jar 包内同名的这个文件,然后进行合并
[^2]: 注意:扩展点使用单一实例加载(请确保扩展实现的线程安全性),缓存在 `ExtensionLoader`


@@ -73,7 +73,7 @@ description: "Dubbo 代码中的一些实现细节"

上图是服务提供者暴露服务的主过程:

首先 `ServiceConfig` 类拿到对外提供服务的实际类 ref(如:HelloWorldImpl),然后通过 `ProxyFactory` 类的 `getInvoker` 方法使用 ref 生成一个 `AbstractProxyInvoker` 实例,到这一步就完成具体服务到 `Invoker` 的转化。接下来就是 `Invoker` 转换到 `Exporter` 的过程。
首先 `ServiceConfig` 类拿到对外提供服务的实际类 ref如:HelloWorldImpl),然后通过 `ProxyFactory` 类的 `getInvoker` 方法使用 ref 生成一个 `AbstractProxyInvoker` 实例,到这一步就完成具体服务到 `Invoker` 的转化。接下来就是 `Invoker` 转换到 `Exporter` 的过程。

Dubbo 处理服务暴露的关键就在 `Invoker` 转换到 `Exporter` 的过程,上图中的红色部分。下面我们以 Dubbo 和 RMI 这两种典型协议的实现来进行说明:

@@ -91,14 +91,14 @@ RMI 协议的 `Invoker` 转为 `Exporter` 发生在 `RmiProtocol`类的 `export`

上图是服务消费的主过程:

首先 `ReferenceConfig` 类的 `init` 方法调用 `Protocol``refer` 方法生成 `Invoker` 实例(如上图中的红色部分),这是服务消费的关键。接下来把 `Invoker` 转换为客户端需要的接口(如:HelloWorld)
首先 `ReferenceConfig` 类的 `init` 方法调用 `Protocol``refer` 方法生成 `Invoker` 实例如上图中的红色部分,这是服务消费的关键。接下来把 `Invoker` 转换为客户端需要的接口如:HelloWorld

关于每种协议如 RMI/Dubbo/Web service 等它们在调用 `refer` 方法生成 `Invoker` 实例的细节和上一章节所描述的类似。

### 满眼都是 Invoker

由于 `Invoker` 是 Dubbo 领域模型中非常重要的一个概念,很多设计思路都是向它靠拢。这就使得 `Invoker` 渗透在整个实现代码里,对于刚开始接触 Dubbo 的人,确实容易给搞混了。
下面我们用一个精简的图来说明最重要的两种 `Invoker`服务提供 `Invoker` 和服务消费 `Invoker`
下面我们用一个精简的图来说明最重要的两种 `Invoker`——服务提供 `Invoker` 和服务消费 `Invoker`

![/dev-guide/images/dubbo_rpc_invoke.jpg](/imgs/dev/dubbo_rpc_invoke.jpg)

@@ -144,29 +144,29 @@ public class DemoServiceImpl implements DemoService {


- Magic - Magic High & Magic Low (16 bits)
Identifies dubbo protocol with value: 0xdabb

标识协议版本号,Dubbo 协议:0xdabb

- Req/Res (1 bit)
Identifies this is a request or response. Request - 1; Response - 0.

标识是请求或响应。请求: 1; 响应: 0。

- 2 Way (1 bit)
Only useful when Req/Res is 1 (Request), expect for a return value from server or not. Set to 1 if need a return value from server.

仅在 Req/Res 为1(请求)时才有用,标记是否期望从服务器返回值。如果需要来自服务器的返回值,则设置为1。

- Event (1 bit)
Identifies an event message or not, for example, heartbeat event. Set to 1 if this is an event.

标识是否是事件消息,例如,心跳事件。如果这是一个事件,则设置为1。

- Serialization ID (5 bit)
Identifies serialization type: the value for fastjson is 6.

标识序列化类型:比如 fastjson 的值为6。

- Status (8 bits)
Only useful when Req/Res is 0 (Response), identifies the status of response

仅在 Req/Res 为0(响应)时有用,用于标识响应的状态。

- 20 - OK
- 30 - CLIENT_TIMEOUT
- 31 - SERVER_TIMEOUT
@@ -177,36 +177,36 @@ public class DemoServiceImpl implements DemoService {
- 80 - SERVER_ERROR
- 90 - CLIENT_ERROR
- 100 - SERVER_THREADPOOL_EXHAUSTED_ERROR

- Request ID (64 bits)
Identifies an unique request. Numeric (long).
- Data Length (32)
Length of the content (the variable part) after serialization, counted by bytes. Numeric (integer).

标识唯一请求。类型为long。

- Data Length (32 bits)

序列化后的内容长度(可变部分),按字节计数。int类型。

- Variable Part
Each part is a byte[] after serialization with specific serialization type, identifies by Serialization ID.
Every part is a byte[] after serialization with specific serialization type, identifies by Serialization ID

1. If the content is a Request (Req/Res = 1), each part consists of the content, in turn is:
- Dubbo version
- Service name
- Service version
- Method name
- Method parameter types
- Method arguments
- Attachments

1. If the content is a Response (Req/Res = 0), each part consists of the content, in turn is:
- Return value type, identifies what kind of value returns from server side: RESPONSE_NULL_VALUE - 2, RESPONSE_VALUE - 1, RESPONSE_WITH_EXCEPTION - 0.
- Return value, the real value returns from server.


**注意:**对于(Variable Part)变长部分,当前版本的dubbo框架使用json序列化时,在每部分内容间额外增加了换行符作为分隔,请选手在Variable Part的每个part后额外增加换行符, 如:

被特定的序列化类型(由序列化 ID 标识)序列化后,每个部分都是一个 byte [] 或者 byte

- 如果是请求包 ( Req/Res = 1),则每个部分依次为:
- Dubbo version
- Service name
- Service version
- Method name
- Method parameter types
- Method arguments
- Attachments
- 如果是响应包(Req/Res = 0),则每个部分依次为:
- 返回值类型(byte),标识从服务器端返回的值类型:
- 返回空值:RESPONSE_NULL_VALUE 2
- 正常响应值: RESPONSE_VALUE 1
- 异常:RESPONSE_WITH_EXCEPTION 0
- 返回值:从服务端返回的响应bytes

**注意:** 对于(Variable Part)变长部分,当前版本的Dubbo 框架使用json序列化时,在每部分内容间额外增加了换行符作为分隔,请在Variable Part的每个part后额外增加换行符, 如:

```
Dubbo version bytes (换行符)
Service name bytes (换行符)
@@ -229,4 +229,3 @@ Service name bytes (换行符)




0 comments on commit ccc069d

Please sign in to comment.