diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0.json new file mode 100644 index 0000000000..07c5265181 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0.json @@ -0,0 +1,34 @@ +{ + "version.label": { + "message": "v1.11.0", + "description": "The label for version v1.11.0" + }, + "sidebar.tutorialSidebar.category.Installation and Deployment": { + "message": "安装与部署", + "description": "The label for category Installation and Deployment in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.EventMesh SDK for Java": { + "message": "EventMesh SDK for Java", + "description": "The label for category EventMesh SDK for Java in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Design Document": { + "message": "设计文档", + "description": "The label for category Design Document in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Upgrade Guide": { + "message": "升级指南", + "description": "The label for category Upgrade Guide in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Event Handling and Integration": { + "message": "事件处理和集成", + "description": "The label for category Event Handling and Integration in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Observability": { + "message": "可观测性", + "description": "The label for category Observability in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Connect": { + "message": "连接器", + "description": "The label for category Connect in sidebar tutorialSidebar" + } +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/01-runtime-protocol.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/01-runtime-protocol.md new file mode 100644 index 0000000000..ce0e6ac800 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/01-runtime-protocol.md @@ -0,0 +1,417 @@ +# TCP 协议文档 + +#### 1. 协议格式 + +**消息组成详解:** + +``` +魔术字:9 位,当前值为“EventMesh” + +通信协议版本号:4 位,当前值为“0000” + +消息总长度值 (length):4 位,int 类型 + +消息头长度值 (headerLength):4 位,int 类型 + +消息头 (header):长度 = headerLength + +消息体 (body):长度 = length - headerLength - 4 - 4 +``` + +#### 2. 业务逻辑层 + ++ 消息组成 + +消息头(header)+ 消息体(body) + +```java +public class Package { + + private Header header; + private Object body; +} + +public class Header { + + private Command cmd; + private int code; + private String msg; + private String seq; +} +``` + ++ 详解 + +消息头 (header):类型为 Header,Header 中有 Command 字段,用于区分不同的消息类型 + +消息体 (body):对于不同的消息类型,body 的类型不同 + +| 消息命令字 | body 类型 | +| ------------------------------------------------------------ | ------------ | +| HEARTBEAT_REQUEST, HEARTBEAT_RESPONSE, HELLO_RESPONSE, CLIENT_GOODBYE_REQUEST, CLIENT_GOODBYE_RESPONSE, SERVER_GOODBYE_REQUEST, SERVER_GOODBYE_RESPONSE, LISTEN_REQUEST, LISTEN_RESPONSE, UNSUBSCRIBE_REQUEST, SUBSCRIBE_RESPONSE, UNSUBSCRIBE_RESPONSE, ASYNC_MESSAGE_TO_SERVER_ACK, BROADCAST_MESSAGE_TO_SERVER_ACK | 无 | +| HELLO_REQUEST | UserAgent | +| SUBSCRIBE_REQUEST | Subscription | +| REQUEST_TO_SERVER, REQUEST_TO_CLIENT, RESPONSE_TO_SERVER, RESPONSE_TO_CLIENT, ASYNC_MESSAGE_TO_SERVER, ASYNC_MESSAGE_TO_CLIENT, BROADCAST_MESSAGE_TO_SERVER, BROADCAST_MESSAGE_TO_CLIENT, ASYNC_MESSAGE_TO_CLIENT_ACK, BROADCAST_MESSAGE_TO_CLIENT_ACK, RESPONSE_TO_CLIENT_ACK, REQUEST_TO_CLIENT_ACK | OpenMessage | +| REDIRECT_TO_CLIENT | RedirectInfo | + +#### 3. Client 与 EventMesh Runtime(Server) 交互场景详解 + +```java +public enum Command { + + //心跳 + HEARTBEAT_REQUEST(0), //client 发给 server 的心跳包 + HEARTBEAT_RESPONSE(1), //server 回复 client 的心跳包 + + //握手 + HELLO_REQUEST(2), //client 发给 server 的握手请求 + HELLO_RESPONSE(3), //server 回复 client 的握手请求 + + //断连 + CLIENT_GOODBYE_REQUEST(4), //client 主动断连时通知 server + CLIENT_GOODBYE_RESPONSE(5), //server 回复 client 的主动断连通知 + SERVER_GOODBYE_REQUEST(6), //server 主动断连时通知 client + SERVER_GOODBYE_RESPONSE(7), //client 回复 server 的主动断连通知 + + //订阅管理 + SUBSCRIBE_REQUEST(8), //client 发给 server 的订阅请求 + SUBSCRIBE_RESPONSE(9), //server 回复 client 的订阅请求 + UNSUBSCRIBE_REQUEST(10), //client 发给 server 的取消订阅请求 + UNSUBSCRIBE_RESPONSE(11), //server 回复 client 的取消订阅请求 + + //监听 + LISTEN_REQUEST(12), //client 发给 server 的启动监听请求 + LISTEN_RESPONSE(13), //server 回复 client 的监听请求 + + //RR + REQUEST_TO_SERVER(14), //client 将 RR 请求发送给 server + REQUEST_TO_CLIENT(15), //server 将 RR 请求推送给 client + REQUEST_TO_CLIENT_ACK(16), //client 收到 RR 请求后 ACK 给 server + RESPONSE_TO_SERVER(17), //client 将 RR 回包发送给 server + RESPONSE_TO_CLIENT(18), //server 将 RR 回包推送给 client + RESPONSE_TO_CLIENT_ACK(19), //client 收到回包后 ACK 给 server + + //异步事件 + ASYNC_MESSAGE_TO_SERVER(20), //client 将异步事件发送给 server + ASYNC_MESSAGE_TO_SERVER_ACK(21), //server 收到异步事件后 ACK 给 client + ASYNC_MESSAGE_TO_CLIENT(22), //server 将异步事件推送给 client + ASYNC_MESSAGE_TO_CLIENT_ACK(23), //client 收到异步事件后 ACK 给 server + + //广播 + BROADCAST_MESSAGE_TO_SERVER(24), //client 将广播消息发送给 server + BROADCAST_MESSAGE_TO_SERVER_ACK(25), //server 收到广播消息后 ACK 给 client + BROADCAST_MESSAGE_TO_CLIENT(26), //server 将广播消息推送给 client + BROADCAST_MESSAGE_TO_CLIENT_ACK(27), //client 收到广播消息后 ACK 给 server + + //重定向指令 + REDIRECT_TO_CLIENT(30), //server 将重定向指令推动给 client +} +``` + +#### 4. Client 发起交互 + +| 场景 | Client 向 Server 发送消息命令字 | Server 回复 Client 消息的命令字 | 说明 | +| -------------- | ---------------------------- | ------------------------------- | ---- | +| 握手 | HELLO_REQUEST | HELLO_RESPONSE | | +| 心跳 | HEARTBEAT_REQUEST | HEARTBEAT_RESPONSE | | +| 订阅 | SUBSCRIBE_REQUEST | SUBSCRIBE_RESPONSE | | +| 取消订阅 | UNSUBSCRIBE_REQUEST | UNSUBSCRIBE_RESPONSE | | +| 开始监听消息 | LISTEN_REQUEST | LISTEN_RESPONSE | | +| 发送 RR 请求 | REQUEST_TO_SERVER | RESPONSE_TO_CLIENT | | +| 发送 RR 回包 | RESPONSE_TO_SERVER | 无 | | +| 发送异步事件 | ASYNC_MESSAGE_TO_SERVER | ASYNC_MESSAGE_TO_SERVER_ACK | | +| 发送广播事件 | BROADCAST_MESSAGE_TO_SERVER | BROADCAST_MESSAGE_TO_SERVER_ACK | | +| 客户端主动断连 | CLIENT_GOODBYE_REQUEST | CLIENT_GOODBYE_RESPONSE | | + +#### 5. Server 发起交互 + +| 场景 | Server 向 Client 发送消息命令字 | Client 回复 Server 消息命令字 | 说明 | +| ------------------ | ---------------------------- | ------------------------------- | ---- | +| 客户端接收 RR 请求 | REQUEST_TO_CLIENT | REQUEST_TO_CLIENT_ACK | | +| 客户端接收 RR 回包 | RESPONSE_TO_CLIENT | RESPONSE_TO_CLIENT_ACK | | +| 客户端接收异步事件 | ASYNC_MESSAGE_TO_CLIENT | ASYNC_MESSAGE_TO_CLIENT_ACK | | +| 客户端接收广播事件 | BROADCAST_MESSAGE_TO_CLIENT | BROADCAST_MESSAGE_TO_CLIENT_ACK | | +| 服务端主动断连 | SERVER_GOODBYE_REQUEST | 无 | | +| 服务端进行重定向 | REDIRECT_TO_CLIENT | 无 | | +| | | | | + +#### 6. 消息类型 + ++ 发送 RR 消息 + +![rr-msg](/images/design-document/sync-message.png) + ++ 发送异步单播消息 + +![async-msg](/images/design-document/async-message.png) + ++ 发送广播消息 + +![broadcast-msg](/images/design-document/broadcast-message.png) + +## HTTP 协议文档 + +Java 类`EventMeshMessage`的`content`字段表示一个特殊的协议,因此,如果您要使用 eventmesh-sdk-java 的 http-client,则只需设计协议的`content`即可。`EventMeshMessage`组成如下: + +```java +public class EventMeshMessage { + + private String bizSeqNo; + + private String uniqueId; + + private String topic; + + private String content; + + private Map prop; + + private long createTime = System.currentTimeMillis(); +} +``` + +#### 1. 消息发送方式与组成 + +**消息发送方式**:POST 方式 + +**消息组成**:请求头 (RequestHeader) + 请求体 (RequestBody) + ++ 心跳消息 + +**RequestHeader** + +| Key | 说明 | +| -------- | ---------------- | +| Env | client 所属环境 | +| Region | client 所属区域 | +| Idc | client 所属 IDC | +| Dcn | client 所在 DCN | +| Sys | client 所属子系统 | +| Pid | client 进程号 | +| Ip | client Ip | +| Username | client 用户名 | +| Passwd | client 密码 | +| Version | 协议版本 | +| Language | 语言描述 | +| Code | 请求码 | + +**RequestBody** + +| Key | 说明 | +| ----------------- | ------------------------------ | +| clientType | 客户端类型 | +| heartbeatEntities | 心跳实体,包含 topic、url 等信息 | + ++ 订阅消息: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +| Key | 说明 | +| ----- | ----------------- | +| topic | 客户端订阅的 topic | +| url | topic 对应的 url | + ++ 取消订阅消息: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +与订阅消息一致 + ++ 发送异步事件: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +| Key | 说明 | +| -------- | ----------------------- | +| topic | 客户端请求的 topic | +| content | 客户端发送的 topic 的内容 | +| ttl | 客户端请求超时时间 | +| bizSeqNo | 客户端请求业务流水号 | +| uniqueId | 客户端请求消息唯一标识 | + +#### 2. Client 发起交互 + +| 场景 | Client 向 Server 发送消息请求码 | Server 回复 Client 消息的响应码 | 说明 | +| ------------ | ---------------------------- | --------------------------------------- | ---- | +| 心跳 | HEARTBEAT(203) | SUCCESS(0)/EVENTMESH_HEARTBEAT_ERROR(19) | | +| 订阅 | SUBSCRIBE(206) | SUCCESS(0)/EVENTMESH_SUBSCRIBE_ERROR(17) | | +| 取消订阅 | UNSUBSCRIBE(207) | SUCCESS(0)/EVENTMESH_UNSUBSCRIBE_ERROR(18) | | +| 发送异步事件 | MSG_SEND_ASYNC(104) | SUCCESS(0)/EVENTMESH_SEND_ASYNC_MSG_ERR(14) | | + +#### 3. Server 发起交互 + +| 场景 | Server 向 Client 发送消息请求码 | Client 回复 Server 消息响应码 | 说明 | +| ------------------ | ---------------------------- | -------------------------- | ---------------------- | +| 客户端接收异步事件 | HTTP_PUSH_CLIENT_ASYNC(105) | retCode | retCode 值为 0 时代表成功 | + +## gRPC 协议文档 + +#### 1. protobuf + +在 `eventmesh-protocol-gprc` 模块有 EventMesh gRPC 客户端的 protobuf 文件。the protobuf 文件路径是 `/src/main/proto/eventmesh-client.proto`. + +用 gradle build 生成 gRPC 代码在 `/build/generated/source/proto/main`. 生成代码用于 `eventmesh-sdk-java` 模块。 + +#### 2. gRPC 数据模型 + ++ 消息 + +以下消息数据模型用于 `publish()`, `requestReply()` 和 `broadcast()` APIs. + +``` +message RequestHeader { + string env = 1; + string region = 2; + string idc = 3; + string ip = 4; + string pid = 5; + string sys = 6; + string username = 7; + string password = 8; + string language = 9; + string protocolType = 10; + string protocolVersion = 11; + string protocolDesc = 12; +} + +message SimpleMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + string content = 4; + string ttl = 5; + string uniqueId = 6; + string seqNum = 7; + string tag = 8; + map properties = 9; +} + +message BatchMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + + message MessageItem { + string content = 1; + string ttl = 2; + string uniqueId = 3; + string seqNum = 4; + string tag = 5; + map properties = 6; + } + + repeated MessageItem messageItem = 4; +} + +message Response { + string respCode = 1; + string respMsg = 2; + string respTime = 3; +} +``` + ++ 订阅 + +以下订阅数据模型用于 `subscribe()` 和 `unsubscribe()` APIs. + +``` +message Subscription { + RequestHeader header = 1; + string consumerGroup = 2; + + message SubscriptionItem { + enum SubscriptionMode { + CLUSTERING = 0; + BROADCASTING = 1; + } + + enum SubscriptionType { + ASYNC = 0; + SYNC = 1; + } + + string topic = 1; + SubscriptionMode mode = 2; + SubscriptionType type = 3; + } + + repeated SubscriptionItem subscriptionItems = 3; + string url = 4; +} +``` + ++ 心跳 + +以下心跳数据模型用于 `heartbeat()` API. + +``` +message Heartbeat { + enum ClientType { + PUB = 0; + SUB = 1; + } + + RequestHeader header = 1; + ClientType clientType = 2; + string producerGroup = 3; + string consumerGroup = 4; + + message HeartbeatItem { + string topic = 1; + string url = 2; + } + + repeated HeartbeatItem heartbeatItems = 5; +} +``` + +#### 3. gRPC 服务接口 + ++ 事件生产端服务 APIs + +``` +service PublisherService { + # 异步事件生产 + rpc publish(SimpleMessage) returns (Response); + + # 同步事件生产 + rpc requestReply(SimpleMessage) returns (Response); + + # 批量事件生产 + rpc batchPublish(BatchMessage) returns (Response); +} +``` + ++ 事件消费端服务 APIs + +``` +service ConsumerService { + # 所消费事件通过 HTTP Webhook 推送事件 + rpc subscribe(Subscription) returns (Response); + + # 所消费事件通过 TCP stream 推送事件 + rpc subscribeStream(Subscription) returns (stream SimpleMessage); + + rpc unsubscribe(Subscription) returns (Response); +} +``` + ++ 客户端心跳服务 API + +``` +service HeartbeatService { + rpc heartbeat(Heartbeat) returns (Response); +} +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/02-https.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/02-https.md new file mode 100644 index 0000000000..5b6cfe9109 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/02-https.md @@ -0,0 +1,30 @@ +# HTTPS + +1. 在 eventmesh-runtime 中配置 + +``` +eventMesh.properties (添加如下配置) +eventMesh.server.useTls.enabled=true // 默认值 false + +config env varible +-Dssl.server.protocol=TLSv1.1 // 默认值 TLSv1.1 +-Dssl.server.cer=sChat2.jks // 把文件放到启动脚本 start.sh 指定的 conPath 目录下 +-Dssl.server.pass=sNetty +``` + +2. 在 eventmesh-sdk-java 中配置 + +``` +// 创建 producer +LiteClientConfig eventMeshHttpClientConfig = new eventMeshHttpClientConfig(); +... + +// 设置开启 TLS +eventMeshHttpClientConfig.setUseTls(true); +LiteProducer producer = new LiteProducer(eventMeshHttpClientConfig); + +// 配置环境变量 +-Dssl.client.protocol=TLSv1.1 // 默认值 TLSv1.1 +-Dssl.client.cer=sChat2.jks // 把文件放到应用指定的 conPath 目录下 +-Dssl.client.pass=sNetty +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/03-cloudevents.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/03-cloudevents.md new file mode 100644 index 0000000000..b446b903b4 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/03-cloudevents.md @@ -0,0 +1,102 @@ +# CloudEvents 集成 + +## 介绍 + +[CloudEvents](https://github.com/cloudevents/spec) 是一种描述事件数据的格式规范,它提供了跨服务、平台与系统的互操作性。 + +截止至 2021 年 5 月,EventMesh 包含了以下主要组件:`eventmesh-runtime`, `eventmesh-sdk-java` 和 `eventmesh-connector-rocketmq`。 + +对于使用 EventMesh 的用户,`eventmesh-runtime` 可以被部署为微服务来在生产者和消费者间传输用户的事件。 +用户的应用程序可以通过 `eventmesh-sdk-java` 来与 `eventmesh-runtime` 进行交互,即发布或订阅指定主题的事件。 + +EventMesh 的用户非常渴望能得到对 CloudEvents 的支持。有许多理由使得用户倾向于使用集成了 CloudEvents 支持的 SDK: + +- CloudEvents 是一种更为广泛接受和支持的描述事件的方式。目前,`eventmesh-sdk-java` 使用的是 `EventMeshMessage` 结构 + 来描述事件,其标准化程度较低。 +- CloudEvents 的 Java SDK 有更广泛的分发方式。比如,目前 EventMesh 的用户需要使用 SDK 的 tar 包,或对每个 EventMesh 的 + 发布版本从源码编译。有了 CloudEvents 的支持,用户可以更方便地通过 CloudEvents 的公开分发(比如,配置 Maven)来添加 + EventMesh SDK 依赖项。 +- CloudEvents 的 SDK 支持多种语言。尽管目前 EventMesh 只提供了 Java SDK,但在未来,如果要为更多语言提供支持,将 Java SDK + 与 CloudEvents 绑定的经验将使工作变得容易。 + +## 需求 + +### 功能需求 + +| 需求 ID | 需求描述 | 备注 | +| ------ | ------- | --- | +| F-1 | EventMesh 用户应能使用公共 SDK 依赖项来发布或订阅 CloudEvents 格式的事件 | 功能性 | +| F-2 | EventMesh 用户应能在提供了 CloudEvents 支持的 SDK 中继续使用现有的 EventMesh 客户端功能(如负载均衡) | 功能等价 | +| F-3 | EventMesh 的开发者应不需要付出特别多努力/痛苦来在 `eventmesh-sdk-java` 和提供了 CloudEvents 支持的 SDK 之间同步 | 可维护性 | +| F-4 | EventMesh 支持可插拔的协议,以便开发者整合其他协议(例如:CloudEvents / EventMesh MessageOpenMessage / MQTT...) | 功能性 | +| F-5 | EventMesh 支持统一的 API 以供从/向事件库发布或订阅事件 | 功能性 | + +### 性能需求 + +| 需求 ID | 需求描述 | 备注 | +| ------ | ------- | --- | +| P-1 | 提供了 CloudEvents 支持的 SDK 应具有与目前的 SDK 相近的客户端延迟 | | + +## 设计细节 + +与 CloudEvents 的 Java SDK 绑定(这与 Kafka 已经完成的工作类似,请在附录中的参考资料了解更多细节)是达成上述需求的一种简单方法。 + +### 可插拔协议 + +![可插拔协议](/images/design-document/cloudevents-pluggable-protocols.png) + +### EventMesh 集成 CloudEvents 进度表 + +#### TCP + +##### SDK 端发布 + +- 在 `package` 首部中添加 CloudEvents 标识符 +- 使用 `CloudEventBuilder` 构造 CloudEvent,并将其放入 `package` 体中 + +##### SDK 端订阅 + +- 在 `ReceiveMsgHook` 接口下添加 `convert` 函数,其用于将 `package` 体转换为具有 `package` 首部标识符的特定协议 +- 不同协议应实现 `ReceiveMsgHook` 接口 + +##### 服务端发布 + +- 设计包含 `decodeMessage` 接口的协议转换 API,其可以把包体转换为 CloudEvent +- 更新 `MessageTransferTask` 下的 `Session.upstreamMsg()`,将入参 `Message` 改为 `CloudEvent`,这使用了 + 上一步的 `decodeMessage` API 来进行对 CloudEvent 的转换 +- 更新 `SessionSender.send()`,将入参 `Message` 改为 `CloudEvent` +- 更新 `MeshMQProducer` API,支持在运行时发送 `CloudEvents` +- 在 `connector-plugin` 中实现支持向 EventStore 中发送 `CloudEvents` + +##### 服务端订阅 + +- 支持将连接器插件中的 `RocketMessage` 改为 `CloudEvent +- 重写 `AsyncMessageListener.consume()` 函数,将入参 `Message` 改为 `CloudEvent` +- 更新 `MeshMQPushConsumer.updateOffset()`,将入参 `Message` 改为 `CloudEvent` +- 更新 `DownStreamMsgContext`,将入参 `Message` 改为 `CloudEvent`,更新 `DownStreamMsgContext.ackMsg` + +#### HTTP + +##### SDK 端发布 + +- 支持 `LiteProducer.publish(cloudEvent)` +- 在 http 请求头中添加 CloudEvents 标识符 + +##### SDK 端订阅 + +##### 服务端发布 + +- 支持根据 `HttpCommand` 首部中的协议类型,通过可插拔的协议插件构造 `HttpCommand.body` +- 支持在消息处理器中发布 CloudEvent + +##### 服务端订阅 + +- 更新 `EventMeshConsumer.subscribe()` +- 更新 `HandleMsgContext`,将入参 `Message` 改为 `CloudEvent` +- 更新 `AsyncHttpPushRequest.tryHTTPRequest()` + +## 附录 + +### 参考资料 + +- diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/04-event-bridge.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/04-event-bridge.md new file mode 100644 index 0000000000..cb60956f21 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/04-event-bridge.md @@ -0,0 +1,156 @@ +# Event Bridge + +![event-bridge](/images/eventmesh-bridge.png) + +Event Bridge 可以支持跨 mesh 集群的消息投递,下面展示这一功能的详细设计与体验步骤 + +![event-bridge-detail](/images/design-document/event-bridge-detail.png) + +> 注:在本地体验这一功能时需要启动两台 EventMesh 实例,同时要修改`eventmesh-runtime`目录下的`eventmesh.properties`文件中的端口配置,避免端口冲突。便于下文描述,event-bridge 特性按照上图信息进行表述。 + +## 01 远程订阅 + +**描述**:向 cluster2 EventMesh 发起远程订阅指令,cluster2 EventMesh 收到指令后会携带订阅信息调用 cluster1 EventMesh 的本地订阅接口 + +**URL**: http://{cluster2 address}/eventmesh/subscribe/remote + +**请求方式**:POST + +**请求参数**:application/json 格式 + +| 参数名 | 类型 | 是否必填 | 说明 | +| ------------- | ------ | -------- | ------------------------------------------------------------ | +| url | String | 是 | 标识订阅 url 信息,暂时无用,后续可移除,目前仅为强校验,实际会被(/eventmesh/bridge/publish)替换 | +| consumerGroup | String | 是 | 标识消费组信息,实际会被 cluster2 的 EventMesh 配置信息替换 | +| topic | List | 是 | 标识订阅信息列表 | +| mode | String | 是 | 标识消费模式,分为集群模式和广播模式 | +| topic | String | 是 | 标识订阅的 topic | +| type | String | 是 | 标识消费类型,分为同步和异步 | +| remoteMesh | String | 否 | 标识远程 mesh 地址,优先根据 topic 从注册中心获取,获取不到使用该字段替换 | + +**请求样例:** + +```json +{ + "url": "http://127.0.0.1:8088/sub/test", + "consumerGroup": "TEST-GROUP", + "topic": [ + { + "mode": "CLUSTERING", + "topic": "TEST-TOPIC-HTTP-ASYNC", + "type": "ASYNC" + } + ], + "remoteMesh" : "http://127.0.0.1:10105/eventmesh/subscribe/local" +} +``` + +## 02 本地订阅 + +**描述**:向 cluster2 的 EventMesh 实例发起本地订阅指令,cluster2 的 EventMesh 收到订阅指令后会启动本地监听从 Event Store 收下来的消息,并推送给订阅信息中的 url。 + +**URL**: http://{cluster2 address}/eventmesh/subscribe/local + +**请求方式**:POST + +**请求参数**:application/json 格式 + +| 参数名 | 类型 | 是否必填 | 说明 | +| ------------- | ------ | -------- | ------------------------------------ | +| url | String | 是 | 标识订阅 url 信息 | +| consumerGroup | String | 是 | 标识消费组信息 | +| topic | List | 是 | 标识订阅信息列表 | +| mode | String | 是 | 标识消费模式,分为集群模式和广播模式 | +| topic | String | 是 | 标识订阅的 topic | +| type | String | 是 | 标识消费类型,分为同步和异步 | + +**请求样例:** + +```JSON +{ + "url": "http://127.0.0.1:8088/sub/test", + "consumerGroup": "TEST-GROUP", + "topic": [ + { + "mode": "CLUSTERING", + "topic": "TEST-TOPIC-HTTP-ASYNC", + "type": "ASYNC" + } + ] +} +``` + +## 03 发送消息 + +**描述**:向 cluster1 的 EventMesh 实例发送消息,cluster1 的 EventMesh 收到消息后会发送到 Event Store,再从 Event Store 收下来消息推送给 cluster2 的 EventMesh url `/eventmesh/bridge/publish`。 + +**URL**: http://{cluster1 address}/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC + +**请求方式**:POST + +**请求参数**:application/json 格式 + +**请求样例:** + +```json +{ + "name": "test", + "age": "19" +} +``` + +## 04 远程去订阅 + +**描述**:向 cluster2 的 EventMesh 实例发送去除订阅指令,cluster2 的 EventMesh 收到指令后会发送 cluster1 的 EventMesh,cluster1 的 EventMesh 会本地执行去除订阅 + +**URL**: http://{cluster2 address}/eventmesh/unsubscribe/remote + +**请求方式**:POST + +**请求参数**:application/json 格式 + +| 参数名 | 类型 | 是否必填 | 说明 | +| ------------- | ------ | -------- | ------------------------------------------------------------ | +| url | String | 是 | 标识要去除订阅 url 信息,暂时无用,后续可移除,目前仅为强校验,实际会被(/eventmesh/bridge/publish)替换 | +| consumerGroup | String | 是 | 标识要去除的消费组信息,实际会使用 EventMesh cluster2 的 group 信息替换 | +| topic | List | 是 | 标识订阅 topic 信息列表 | + +**请求样例:** + +```json +{ + "consumerGroup": "EventMeshTest-consumerGroup", + "url": "http://127.0.0.1:8088/sub/test", + "topic": [ + "TEST-TOPIC-HTTP-ASYNC" + ] +} +``` + +## 05 本地去订阅 + +**描述**:向 cluster2 的 EventMesh 实例发送去除订阅指令,cluster2 的 EventMesh 收到指令后会本地执行去除订阅 + +**URL**: http://{cluster2 address}/eventmesh/unsubscribe/local + +**请求方式**:POST + +**请求参数**:application/json 格式 + +| 参数名 | 类型 | 是否必填 | 说明 | +| ------------- | ------ | -------- | ---------------------- | +| url | String | 是 | 标识要去除订阅 url 信息 | +| consumerGroup | String | 是 | 标识要去除的消费组信息 | +| topic | List | 是 | 标识订阅 topic 信息列表 | + +**请求样例:** + +```json +{ + "consumerGroup": "EventMeshTest-consumerGroup", + "url": "http://127.0.0.1:8088/sub/test", + "topic": [ + "TEST-TOPIC-HTTP-ASYNC" + ] +} +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/05-webhook.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/05-webhook.md new file mode 100644 index 0000000000..20bf05ac74 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/05-webhook.md @@ -0,0 +1,334 @@ +# 使用 Webhook 订阅事件 + +## Webhook 使用流程 + +### 第一步:在 EventMesh 配置 Webhook 相关信息并且启动 + +配置说明: + +``` +# Webhook HTTP payload 监听端口 +eventMesh.server.http.port=10105 +# Webhook 配置管理端口 +eventMesh.server.admin.http.port=10106 + +# 是否启动 Webhook admin 服务 +eventMesh.webHook.admin.start=true + +# Webhook 事件配置存储模式。目前只支持 file 与 nacos +eventMesh.webHook.operationMode=file +# 文件存储模式的文件存放路径,如果写上#{eventMeshHome},在 eventMesh 根目录 +eventMesh.webHook.fileMode.filePath= #{eventMeshHome}/webhook + +# nacos 存储模式,配置命名规则是 eventMesh.webHook.nacosMode.{nacos 原生配置 key} 具体的配置请看 [nacos github api](https://github.com/alibaba/nacos/blob/develop/api/src/main/java/com/alibaba/nacos/api/SystemPropertyKeyConst.java) +## nacos 的地址 +eventMesh.webHook.nacosMode.serverAddr=127.0.0.1:8848 + +# Webhook CloudEvent 发送模式。与 eventMesh.connector.plugin.type 配置一样 +eventMesh.webHook.producer.connector=standalone +``` + +### 第二步:添加 Webhook 配置信息 + +配置信息说明: + +```java + /** + * 厂商发送事件时调用的地址。[http or https]://[domain or IP]:[port]/webhook/[callbackPath] + * 在厂商的 Webhook 配置中需要填写完整 url,比如:http://127.0.0.1:10105/webhook/test/event + * callbackPath 唯一 + * manufacturer callback path + */ + private String callbackPath; + + /** + * 厂商的名字 + * manufacturer name ,like github + */ + private String manufacturerName; + + /** + * 厂商的域名 + * manufacturer domain name, like www.github.com + */ + private String manufacturerDomain; + + /** + * 厂商的事件名 + * Webhook event name ,like rep-push + */ + private String manufacturerEventName; + + /** + * + * http header content type + */ + private String contentType = "application/json"; + + /** + * 说明 + * description of this WebHookConfig + */ + private String description; + + /** + * 有一些厂商使用验签方式, + * secret key ,for authentication + */ + private String secret; + + /** + * 有一些厂商使用验签方式,使用账户密码方式 + * userName ,for HTTP authentication + */ + private String userName; + + /** + * 有一些厂商使用验签方式,使用账户密码方式 + * password ,for HTTP authentication + */ + private String password; + + /** + * 事件发送到那个 topic + * roll out event name ,like topic to mq + */ + private String cloudEventName; + + /** + * roll out data format -> CloudEvent serialization mode + * If HTTP protocol is used, the request header contentType needs to be marked + */ + private String dataContentType = "application/json"; + + /** + * cloudEvent 事件对象唯一标识符识别方式,uuid 或者 manufacturerEventId(厂商 id) + * id of cloudEvent ,like uuid/manufacturerEventId + */ + private String cloudEventIdGenerateMode; + +``` + +#### 添加接口 + +路径: /webhook/insertWebHookConfig + +方法:POST + +contentType: application/json + +输入参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerDomain | 厂商的域名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 是 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名 | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent 事件对象唯一标识符识别方式,uuid 或者 manufacturerEventId(厂商 id) | string | 否 | manufacturerEventId | + +例子: + +```json +{ + "callbackPath":"/webhook/github/eventmesh/all", + "manufacturerName":"github", + "manufacturerDomain":"www.github.com", + "manufacturerEventName":"all", + "cloudEventName":"github-eventmesh", + "secret": "testSecret" +} +``` + +输出参数:1 成功,0 失败 + +#### 通过 callbackPath 查询 WebHookConfig + +路径: /webhook/queryWebHookConfigById + +方法:POST + +contentType: application/json + +输入参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 调用地址的提供方 | string | 是 | null | + +例子: + +```json +{ + "callbackPath":"/webhook/github/eventmesh/all", + "manufacturerName":"github" +} +``` + +输出参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerDomain | 厂商的域名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 是 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名() | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent 事件对象唯一标识符识别方式,uuid 或者 manufacturerEventId(厂商 id) | string | 否 | manufacturerEventId | + +#### 通过 manufacturer 查询 WebHookConfig 列表 + +路径: /webhook/queryWebHookConfigByManufacturer + +方法:POST + +contentType: application/json + +输入参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| manufacturerName | 厂商名 | string | 是 | null | +| pageNum | 分页查询中的页数 | string | 是 | null | +| pageSize | 每一页的结果数量 | string | 是 | null | + +例子: + +```json +{ + "manufacturerName":"github", + "pageNum":1, + "pageSize":2 +} +``` + +输出参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerDomain | 厂商的域名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 是 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名() | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent 事件对象唯一标识符识别方式,uuid 或者 manufacturerEventId(厂商 id) | string | 否 | manufacturerEventId | + +#### 更新接口 + +路径: /webhook/updateWebHookConfig + +方法:POST + +contentType: application/json + +输入参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| ------------------------ | ------------------------------------------------------------ | ------ | ---- | ------------------- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerDomain | 厂商的域名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 是 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名 | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent 事件对象唯一标识符识别方式,uuid 或者 manufacturerEventId(厂商 id) | string | 否 | manufacturerEventId | + +例子: + +```json +{ + "callbackPath":"/webhook/github/eventmesh/all", + "manufacturerName":"github", + "manufacturerDomain":"www.github.com", + "manufacturerEventName":"all", + "cloudEventName":"github-eventmesh", + "secret": "testSecret" +} +``` + +输出参数:1 成功,0 失败 + +#### 删除接口 + +路径: /webhook/deleteWebHookConfig + +方法:POST + +contentType: application/json + +输入参数: + +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| ---------------- | ------------------ | ------ | ---- | ------ | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 调用地址的提供方 | string | 是 | null | + +例子: + +```json +{ + "callbackPath":"/webhook/github/eventmesh/all", + "manufacturerName":"github" +} +``` + +输出参数:1 成功,0 失败 + +### 第三步:查看配置是否成功 + +1. file 存储模式。请到 eventMesh.webHook.fileMode.filePath 目录下查看。文件名为`/`转换为`.`的 callbackPath。 +2. nacos 存储模式。请到 eventMesh.webHook.nacosMode.serverAddr 配置的 nacos 服务中查看。 + +### 第四步:配置 cloudevent 的消费者 + +### 第五步:在厂商配置 Webhook 相关信息 + +> 厂商操作请看 [厂商 Webhook 操作说明](#厂商-Webhook-操作说明) + +## 厂商 Webhook 操作说明 + +### github 注册 + +#### 第一步:进入对应的项目 + +#### 第二步:点击 setting + +![](/images/design-document/webhook/webhook-github-setting.png) + +#### 第三步:点击 Webhooks + +![](/images/design-document/webhook/webhook-github-webhooks.png) + +#### 第四步:点击 Add webhook + +![](/images/design-document/webhook/webhook-github-add.png) + +#### 第五步:填写 webhook 信息 + +![](/images/design-document/webhook/webhook-github-info.png) + +Payload URL: EventMesh 服务地址和调用地址,需包含协议头。例如,当调用地址 `callbackPath` 为 `/webhook/github/eventmesh/all` 时,Payload URL 为 `http://www.example.com:10105/webhook/github/eventmesh/all` + +Content Type: http header content type + +Secret: 验签字符串 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/06-workflow.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/06-workflow.md new file mode 100644 index 0000000000..daf161f123 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/06-workflow.md @@ -0,0 +1,258 @@ +# EventMesh 工作流 + +## 业务场景 + +图中你正在构建一个简单的电商订单管理系统,系统能够接收和调配新的订单,调配流程需要处理所有的订单创建,付款处理以及发货处理。 + +为了实现高可用和高性能,你可以使用事件驱动架构(EDA)构建微服务应用去处理商店前端,订单管理,支付处理和发货管理。你可以在云上部署整个系统。要处理高并发,你可以利用消息系统缓冲,并扩展多个微服务实例。架构类似于: + +![Workflow Use Case](/images/design-document/workflow/workflow-use-case.jpg) + +当每个微服务都在自己的事件通道上运行时,EventMesh 在执行事件编排方面发挥着至关重要的作用。 + +我们使用 [CNCF Serverless 工作流](https://serverlessworkflow.io/) 来描述此事件工作流编排。 + +## CNCF Serverless 工作流 + +CNCF Serverless 工作流定义了一个厂商中立、开源和完全社区驱动的生态系统,用于定义和运行针对 Serverless 技术领域的基于 DSL 的工作流。 + +Serverless 工作流定义了一种领域特定语言(DSL)来描述有状态和无状态的基于工作流的 serverless 函数和微服务编排。 + +详见 [官方 github](https://github.com/serverlessworkflow/specification) + +## EventMesh 工作流 + +我们利用 Serverless 工作流 DSL 来描述 EventMesh 工作流。根据其规范,工作流由一系列用于描述控制流逻辑的工作流状态组成。目前,我们仅支持与事件相关的工作流状态。请参见 [工作流 DSL 设计](#workflow-dsl-design-wip) 中支持的状态。 + +`工作流状态`可以包含通用的`操作`,或在工作流执行期间应调用的服务/函数。这些`操作`可以引用可复用的`函数`定义(应如何调用这些函数/服务),还可以引用触发基于事件的服务调用的事件,以及要等待的事件,这些事件表示这种基于事件的服务调用完成。 + +在 EDA 解决方案中,我们通常使用 AsyncAPI 定义事件驱动的微服务。Serverless 工作流“函数”定义支持使用 AsyncAPI 定义调用语义。有关详细信息,请参见 [Using Funtions for AsyncAPI Service](https://github.com/serverlessworkflow/specification/blob/main/specification.md#using-functions-for-async-api-service-invocations)。 + +### AsyncAPI + +AsyncAPI 是一项开源计划,旨在改善事件驱动体系结构(EDA)的当前状态。我们的长期目标是让使用 EDA 和使用 REST API 一样容易。包括从文档到代码生成、发现到事件管理。现在应用于 REST API 的大多数流程也适用于事件驱动/异步 API。 + +详见 [AsyncAPI 官网](https://www.asyncapi.com/docs/guides) + +### 工作流示例 + +在本示例中,我们构建了上面订单管理系统的事件驱动工作流。 + +首先,我们需要为我们的微服务应用定义 AsyncAPI。 + +- 在线商店应用程序 + +```yaml +asyncapi: 2.2.0 +info: + title: Online Store application + version: '0.1.0' +channels: + store/order: + subscribe: + operationId: newStoreOrder + message: + $ref : '#/components/NewOrder' + +``` + +- 订单服务 + +```yaml +asyncapi: 2.2.0 +info: + title: Order Service + version: '0.1.0' +channels: + order/inbound: + publish: + operationId: sendOrder + message: + $ref : '#/components/Order' + order/outbound: + subscribe: + operationId: processedOrder + message: + $ref : '#/components/Order' +``` + +- 支付服务 + +```yaml +asyncapi: 2.2.0 +info: + title: Payment Service + version: '0.1.0' +channels: + payment/inbound: + publish: + operationId: sendPayment + message: + $ref : '#/components/OrderPayment' + payment/outbound: + subscribe: + operationId: paymentReceipt + message: + $ref : '#/components/OrderPayment' +``` + +- 物流服务 + +```yaml +asyncapi: 2.2.0 +info: + title: Shipment Service + version: '0.1.0' +channels: + shipment/inbound: + publish: + operationId: sendShipment + message: + $ref : '#/components/OrderShipment' +``` + +接下来,定义描述订单管理业务逻辑的订单工作流。 + +```yaml +id: storeorderworkflow +version: '1.0' +specVersion: '0.8' +name: Store Order Management Workflow +states: + - name: Receive New Order Event + type: event + onEvents: + - eventRefs: + - NewOrderEvent + actions: + - eventRef: + triggerEventRef: OrderServiceSendEvent + resultEventRef: OrderServiceResultEvent + - eventRef: + triggerEventRef: PaymentServiceSendEvent + resultEventRef: PaymentServiceResultEvent + transition: Check Payment Status + - name: Check Payment Status + type: switch + dataConditions: + - name: Payment Successfull + condition: "${ .payment.status == 'success' }" + transition: Send Order Shipment + - name: Payment Denied + condition: "${ .payment.status == 'denied' }" + end: true + defaultCondition: + end: true + - name: Send Order Shipment + type: operation + actions: + - eventRef: + triggerEventRef: ShipmentServiceSendEvent + end: true +events: + - name: NewOrderEvent + source: file://onlineStoreApp.yaml#newStoreOrder + type: asyncapi + kind: consumed + - name: OrderServiceSendEvent + source: file://orderService.yaml#sendOrder + type: asyncapi + kind: produced + - name: OrderServiceResultEvent + source: file://orderService.yaml#processedOrder + type: asyncapi + kind: consumed + - name: PaymentServiceSendEvent + source: file://paymentService.yaml#sendPayment + type: asyncapi + kind: produced + - name: PaymentServiceResultEvent + source: file://paymentService.yaml#paymentReceipt + type: asyncapi + kind: consumed + - name: ShipmentServiceSendEvent + source: file://shipmentService.yaml#sendShipment + type: asyncapi + kind: produced +``` + +对应的工作流图如下: + +![Workflow Diagram](/images/design-document/workflow/workflow-diagram.png) + +## EventMesh 工作流引擎 + +在下面的体系结构图中,EventMesh 目录,EventMesh 工作流引擎 和 EventMesh Runtime 在三个不同的处理器中运行。 + +![Workflow Architecture](/images/design-document/workflow/workflow-architecture.jpg) + +运行工作流的步骤如下: + +1. 在环境中部署发布者和订阅者应用程序。 + 使用 AsyncAPI 描述应用程序 API,生成 asyncAPI yaml。 + 使用 AsyncAPI 在 EventMesh 目录中注册发布者和订阅者应用程序。 + +2. 在 EventMesh 工作流引擎中注册 Serverless 工作流 DSL。 + +3. 工作流引擎从 EventMesh 目录查询发布服务器和订阅服务器的需要的工作流 DSL`函数`。 + +4. 事件驱动 App 将事件发布到 EventMesh Runtime 触发工作流。EventMesh 工作流引擎发布和订阅事件、编排事件。 + +### EventMesh Catalog 设计 + +EventMesh 目录存储发布者、订阅者和通道元数据。由以下模块组成: + +- AsyncAPI 解析器 + + 使用 AsyncAPI 社区提供的 SDK ([tool list](https://www.asyncapi.com/docs/community/tooling)), + 解析并验证 AsyncAPI yaml 输入,并生成 AsyncAPI 定义。 + +- 发布者,通道,订阅者模块 + + 从 AsyncAPI 定义存储发布者、订阅者和通道信息。 + +### EventMesh 工作流引擎设计 + +工作流引擎由以下模块组成: + +- 工作流解析器 + + 使用 Serverless Workflow 社区提供的 SDK([SDKs](https://github.com/serverlessworkflow/specification#sdks)), + 解析和验证工作流 DSL 输入,并生成工作流定义。 + +- 工作流模块 + + 管理工作流实例的生命周期,从创建、启动、停止到销毁。 + +- 状态模块 + + 管理工作流状态生命周期。支持与事件相关的状态,and the supported state list below is Work-in-Progress. + + | 工作流状态 | 描述 | + | --- | --- | + | Operation | 执行 Actions 中定义的 AsyncAPI 函数 | + | Event | 检查定义的事件是否匹配,如果匹配,执行定义的 AsyncAPI 函数 | + | Switch | 检查事件是否与事件条件匹配,并执行定义的 AsyncAPI 函数 | + | Parallel | 并行执行定义的 AsyncAPI 函数 | + | ForEach | 迭代输入集合并执行定义的 AsyncAPI 函数 | + +- 行为模块 + + 管理函数中的行为。 + +- 函数模块 + + 通过在 EventMesh Runtime 中创建发布者和/或订阅者来管理 AsyncAPI 函数,并管理发布者/订阅者生命周期。 + + | AsyncAPI 操作 | EventMesh Runtime | + | --- | --- | + | Publish | Publisher | + | Subscribe | Subscriber | + +- 事件模块 + + 使用工作流 DSL 中定义的规则管理 CloudEvent 数据模型,包括事件过滤器、关联和转换。 + +- 重试模块 + + 管理事件发布到 EventMesh Runtime 的重试逻辑。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/_category_.json new file mode 100644 index 0000000000..7706f45770 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-event-handling-and-integration/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Event Handling and Integration", + "collapsed": false +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-spi.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-spi.md new file mode 100644 index 0000000000..4b00610e02 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/01-spi.md @@ -0,0 +1,111 @@ +# EventMesh SPI + +## 介绍 + +为了提高扩展性,EventMesh 通过引入 SPI(Service Provider Interface)机制,能够在运行时自动寻找扩展接口的具体实现类,动态加载。 +在 EventMesh 中,一切扩展点都利用 SPI 采用插件的实现方式,用户可以通过实现扩展接口,开发自定义的插件,在运行时通过简单的配置,声明式的选择所需要运行的插件。 + +## eventmesh-spi 模块 + +SPI 相关的代码位于 eventmesh-spi 模块下,其中主要包括 EventMeshExtensionFactory, EventMeshSPI, ExtensionClassLoader 这三个类。 + +### EventMeshSPI + +EventMeshSPI 是 SPI 注解,所有需要采用 SPI 实现扩展的接口都需要使用@EventMeshSPI 注解标记。 + +```java +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface EventMeshSPI { + + /** + * If true, the spi instance is singleton + */ + boolean isSingleton() default false; + +} +``` + +这么做的原因是可以通过注解的方式声明接口为 SPI 扩展接口,提高代码的可读性。同时,@EventMeshSPI 注解中包含一个 isSingleton 属性, +用来声明该扩展接口是否采用单例的实现方式,如果为 true,那么该接口的实现类将会使用单例的实现方式,在一个 JVM 进程中全局唯一。 + +### EventMeshExtensionFactory + +EventMeshExtensionFactory 是 SPI 实现类的获取工厂,包含一个静态方法`getExtension(Class extensionType, String extensionName)`, +接收扩展接口字节码对象和扩展实例名称,用于获取扩展接口的具体实现类。 + +```java +public enum EventMeshExtensionFactory { + ; + /** + * @param extensionType extension plugin class type + * @param extensionName extension instance name + * @param the type of the plugin + * @return plugin instance + */ + public static T getExtension(Class extensionType, String extensionName) { + } +} +``` + +所有需要获取扩展实现的地方都应该通过 EventMeshExtensionFactory 获取。 + +### ExtensionClassLoader + +ExtensionClassLoader 是扩展接口实现类的加载接口,包含两个实现子类 MetaInfExtensionClassLoader 和 JarExtensionClassLoader。 + +```java +/** + * Load extension class + *
    + *
  • {@link MetaInfExtensionClassLoader}
  • + *
  • {@link JarExtensionClassLoader}
  • + *
+ */ +public interface ExtensionClassLoader { + + /** + * load + * + * @param extensionType extension type class + * @param extension type + * @return extension instance name to extension instance class + */ + Map> loadExtensionClass(Class extensionType); +} +``` + +MetaInfExtensionClassLoader 用于从 classPath 直接加载实现类,JarExtensionClassLoader 用于从配置目录下通过加载 Jar 包的方式加载实现类,未来可能还会提供通过从 Maven 仓库下加载实现类。 + +## SPI 使用示例 + +下面以 eventmesh-connector-plugin 为例,介绍 SPI 具体的使用过程。 + +首先定义一个 eventmesh-connector-api 模块,并且定义扩展接口 MeshMQProducer。在 MeshMQProducer 接口上使用@EventMeshSPI 注解进行声明,表明该接口是一个 SPI 扩展接口 + +```java +@EventMeshSPI(isSingleton = false) +public interface MeshMQProducer extends Producer { +... +} +``` + +eventmesh-connector-rocketmq 模块中包含采用 rocketmq 的具体实现方式 RocketMQProducerImpl。 + +```java +public class RocketMQProducerImpl implements MeshMQProducer { +... +} +``` + +同时,还需要在 eventmesh-connector-rocketmq 模块中 resource/META-INF/eventmesh 目录下创建文件名为 SPI 接口全限定名的文件 +org.apache.eventmesh.api.producer.Producer + +文件内容为扩展实例名和对应的实例全类名 + +```properties +rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl +``` + +至此,一个 SPI 扩展模块就完成了。在使用的时候只需要通过 EventMeshExtensionFactory.getExtension(MeshMQProducer.class, “rocketmq”) 就可以获取 RocketMQProducerImpl 实现类。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/01-metrics-export.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/01-metrics-export.md new file mode 100644 index 0000000000..8120cdbcb3 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/01-metrics-export.md @@ -0,0 +1,47 @@ +# EventMesh 指标(OpenTelemetry 和 Prometheus) + +## 介绍 + +[EventMesh](https://github.com/apache/eventmesh) 是一个动态的云原生事件基础设施。 + +## OpenTelemetry 概述 + +OpenTelemetry 是工具、API 和 SDK 的集合。您可以使用它来检测、生成、收集和导出遥测数据(指标、日志和跟踪)以进行分析,以便了解您的软件的性能和行为。 + +## 概述 Prometheus + +使用领先的开源监控解决方案为您的指标和警报提供支持。 + +- 尺寸数据 +- 强大的查询 +- 伟大的可视化 +- 高效存储 +- 操作简单 +- 精准预警 +- 许多客户端库 +- 许多集成 + +## 要求 + +### 功能要求 + +| Requirement ID | Requirement Description | Comments | +| :------------- | ------------------------------------------------------------ | ------------- | +| F-1 | EventMesh users should be able to observe HTTP metrics from Prometheus | Functionality | +| F-2 | EventMesh users should be able to observe TCP metrics from Prometheus | Functionality | + +## 设计 细节 + +使用由提供的儀表儀器 OpenTelemetry 觀察指標存在於 EventMesh 然後導出到 Prometheus. + +1、初始化儀表儀器 + +2、設置 Prometheus 服務器 + +3、创建了不同的指标观察者 + +## 附录 + +### 参考资料 + + diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/02-tracing.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/02-tracing.md new file mode 100644 index 0000000000..2611289645 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/02-tracing.md @@ -0,0 +1,87 @@ +# 分布式追踪 + +## OpenTelemetry 概述 + +OpenTelemetry 是一组 API 和 SDK 的工具,您可以使用它来仪器化、生成、收集和导出遥测数据(指标、日志和追踪),以便进行分析,以了解您的软件性能和行为。 + +## 需求 + +- 设置追踪器 +- 不同的导出器 +- 在服务器中开始和结束跨度 + +## 设计细节 + +- 跨度处理器:BatchSpanProcessor + +- 导出器:默认为日志,可以从属性中更改 + +```java +// Configure the batch spans processor. This span processor exports span in batches. +BatchSpanProcessor batchSpansProcessor = + BatchSpanProcessor.builder(exporter) + .setMaxExportBatchSize(512) // set the maximum batch size to use + .setMaxQueueSize(2048) // set the queue size. This must be >= the export batch size + .setExporterTimeout( + 30, TimeUnit.SECONDS) // set the max amount of time an export can run before getting + // interrupted + .setScheduleDelay(5, TimeUnit.SECONDS) // set time between two different exports + .build(); +OpenTelemetrySdk.builder() + .setTracerProvider( + SdkTracerProvider.builder().addSpanProcessor(batchSpansProcessor).build()) + .build(); +``` + +1. 当使用`EventMeshHTTPServer`类的`init()`方法时,类`AbstractHTTPServer`将获取跟踪器。 + +```java +super.openTelemetryTraceFactory = new OpenTelemetryTraceFactory(eventMeshHttpConfiguration); +super.tracer = openTelemetryTraceFactory.getTracer(this.getClass().toString()); +super.textMapPropagator = openTelemetryTraceFactory.getTextMapPropagator(); +``` + +2. 然后,在类`AbstractHTTPServer`中的跟踪将起作用。 + +## 问题 + +### 如何在类“OpenTelemetryTraceFactory”中设置不同的导出器?(已解决) + +在从属性中获取导出器类型之后,如何处理它。 + +`logExporter`只需要创建新实例即可。 + +但是,“zipkinExporter”需要新建并使用“getZipkinExporter()”方法。 + +## 解决方案 + +### 不同导出器的解决方案 + +使用反射获取导出器。 + +首先,不同的导出器必须实现接口“EventMeshExporter”。 + +然后,我们从配置中获取导出器名称,并反射到该类。 + +```java +//different spanExporter +String exporterName = configuration.eventMeshTraceExporterType; +//use reflection to get spanExporter +String className = String.format("org.apache.eventmesh.runtime.exporter.%sExporter",exporterName); +EventMeshExporter eventMeshExporter = (EventMeshExporter) Class.forName(className).newInstance(); +spanExporter = eventMeshExporter.getSpanExporter(configuration); +``` + +另外,这将包含 try catch。如果无法成功获取指定的导出器,则将使用默认的日志导出器。 + +#### 不同导出器的改进 + +SPI(待完成) + +## 附录 + +### 参考资料 + +- + +- diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/03-prometheus.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/03-prometheus.md new file mode 100644 index 0000000000..effc07ba88 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/03-prometheus.md @@ -0,0 +1,36 @@ +# 通过 Prometheus 观察 Metrics + +## 下载 Prometheus + +官网:https://prometheus.io/ + +本地下载 Prometheus:https://prometheus.io/download/ + +选择自己电脑对应的版本下载并解压缩 + +### 2、在 prometheus.yml 中添加配置 + +如果你是 Prometheus 的新手,可以直接复制 eventmesh-runtime/conf/prometheus.yml 替换 + +如果你十分了解 Prometheus,可以自行配置,EventMesh 默认的导出的端口为 19090。 + +ps:如果需要更换端口的话,请修改 eventmesh-runtime/conf/eventmesh.properties 中的 + +```properties +#prometheusPort +eventMesh.metrics.prometheus.port=19090 +``` + +## 运行 Prometheus 和 EventMesh + +双击 Prometheus.exe 运行 + +运行 eventmesh-starter(参考 [EventMesh Runtime QuickStart](../../instruction/03-runtime.md)) + +运行 eventmesh-example(参考 [eventmesh-sdk-java QuickStart](../../instruction/05-demo.md)) + +打开浏览器访问:http://localhost:9090/ + +### 输入想观察的 Metrics + +输入 `eventmesh_` 就会出现相关的指标的提示 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/04-zipkin.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/04-zipkin.md new file mode 100644 index 0000000000..1e7e86c4c3 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/04-zipkin.md @@ -0,0 +1,43 @@ +# 通过 Zipkin 观察 Trace + +### 1、下载和运行 Zipkin + +请参考 https://zipkin.io/pages/quickstart.html + +### 2、运行 EventMesh + +运行 eventmesh-starter(参考 [eventmesh-runtime-quickstart](../../instruction/03-runtime.md)) + +运行 eventmesh-example(参考 [eventmesh-sdk-java-quickstart](../../instruction/05-demo.md)) + +### 3、相关的设置 + +eventmesh-runtime/conf/eventmesh.properties 中: + +默认的 exporter 是 log,需要手动改成 Zipkin + +```properties +#trace exporter +eventmesh.trace.exporter.type=Zipkin +``` +下面是关于 Zipkin 的各种配置 +```properties +#set the maximum batch size to use +eventmesh.trace.exporter.max.export.size=512 +#set the queue size. This must be >= the export batch size +eventmesh.trace.exporter.max.queue.size=2048 +#set the max amount of time an export can run before getting(TimeUnit=SECONDS) +eventmesh.trace.exporter.export.timeout=30 +#set time between two different exports(TimeUnit=SECONDS) +eventmesh.trace.exporter.export.interval=5 + +#zipkin +eventmesh.trace.export.zipkin.ip=localhost +eventmesh.trace.export.zipkin.port=9411 +``` + +以上都是相关的配置,如果你十分熟悉 Zipkin 的话可以自行修改。 + +### 4、观察 + +浏览器打开 `localhost:9411` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/05-jaeger.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/05-jaeger.md new file mode 100644 index 0000000000..3edd5e710a --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/05-jaeger.md @@ -0,0 +1,44 @@ +# 通过 Jaeger 观察 Trace + +## Jaeger + +[Jaeger](https://www.jaegertracing.io/) 是 [Uber](https://uber.github.io/) 开发的分布式跟踪系统,现已成为 [CNCF](https://cncf.io/) 开源项目,其灵感来源于 Google 的 [Dapper](https://research.google.com/pubs/pub36356.html) 和 Twitter 的 [Zipkin](https://zipkin.io/),用于监控基于微服务的分布式系统。 + +Jaeger 的安装可以参考 [官方文档](https://www.jaegertracing.io/docs/latest/getting-started/),推荐使用官方的 Docker 镜像 `jaegertracing/all-in-one` 来快速搭建环境进行测试。 + +## 配置 + +为了启用 EventMesh Runtime 的 trace exporter,请将 `conf/eventmesh.properties` 文件中的 `eventMesh.server.trace.enabled` 字段设置为 true。 + +```properties +# Trace plugin +eventMesh.server.trace.enabled=true +eventMesh.trace.plugin=jaeger +``` + +为了定义 trace exporter 的行为,如超时时间或导出间隔,请编辑 `exporter.properties` 文件。 + +```properties +# Set the maximum batch size to use +eventmesh.trace.max.export.size=512 +# Set the queue size. This must be >= the export batch size +eventmesh.trace.max.queue.size=2048 +# Set the max amount of time an export can run before getting(TimeUnit=SECONDS) +eventmesh.trace.export.timeout=30 +# Set time between two different exports (TimeUnit=SECONDS) +eventmesh.trace.export.interval=5 +``` + +为了将导出的 trace 数据发送到 Jaeger,请编辑 `conf/jaeger.properties` 文件中的 `eventmesh.trace.jaeger.ip` 和 `eventmesh.trace.jaeger.port` 字段,来匹配 Jaeger 服务器的配置。 + +```properties +# Jaeger's IP and Port +eventmesh.trace.jaeger.ip=localhost +eventmesh.trace.jaeger.port=14250 +``` + +## 从 Zipkin 迁移 + +Jaeger 采集器服务暴露了与 Zipkin 兼容的 REST API,`/api/v1/spans` 可以接收 Thrift 和 JSON,`/api/v2/spans` 可以接收 JSON 和 Proto。 + +因此你也可以使用 `eventmesh-trace-zipkin` 插件来通过 Jaeger 观察 trace,具体配置细节请参考 `eventmesh-trace-zipkin` 的文档。默认情况下这个特性在 Jaeger 中是关闭的,可以通过 `--collector.zipkin.host-port=:9411` 启用。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/_category_.json new file mode 100644 index 0000000000..9a251b1a4d --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-observability/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Observability", + "collapsed": false +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-stream.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-stream.md new file mode 100644 index 0000000000..4869638c79 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/02-stream.md @@ -0,0 +1,115 @@ +# EventMesh Stream + +## 事件流概述 + +事件流是发布/订阅架构模式的一种实现,它包括以下几个部分 + +- 消息或事件:状态变化。 + +- 主题:消息中间件代理中的分区。 + +- 消费者:可以从代理主题订阅读取事件。 + +- 生产者:生成事件 + +事件流是事件的连续流动,为了维持事件之间的秩序,事件流应该以特定的方式从生产者流向消费者。 + +## 要求 + +### 功能要求 + +| 需求编号 | 需求描述 | 注释 | +| -------------- | ----------------------- | -------- | +| F-1 | EventMesh 用户应该能够在 EventMesh 中实现事件流功能 | 功能性 | +| F-2 | EventMesh 用户可以为路由、过滤、转换等应用动态用户特定逻辑 | 功能性 | + +## 设计细节 + +我们引入了 EventMesh Stream 组件,允许我们在 Apache Camel 中本地使用来自 Spring Cloud Stream 的编程模型和绑定器抽象。 + +[Spring-Cloud-Stream](https://spring.io/projects/spring-cloud-stream) Spring Cloud Stream 是一个用于构建 +与共享消息传递系统连接的、高度可扩展的事件驱动微服务框架。 + +[Apache Camel](https://camel.apache.org/) Camel 是一个开源集成框架,使您能够快速轻松地集成各种消费或生产数据的系统。 + +## 架构 + +![Stream Architecture](/images/design-document/stream-architecture.png) + +## 设计 + +### EventMesh-Stream 组件 + +- Event(事件) +- Event Channel(事件通道) +- Event EndPoint(事件端点) +- Event Pipes & Filters(事件管道和过滤器) +- Event Routes(事件路由器) +- Event Converter(事件转换器) + +#### Event(事件) + +> 事件是系统中传输数据的最小单位。它的结构分为标题、正文和附件。 + +#### Event Channel(事件通道) + +> 事件通道是系统中的逻辑通道,我们是通过 Spring Cloud Stream 编程模型实现的,它具有围绕消息通道的抽象功能(截至目前用的是 Spring `MessageChannel`)。 + +#### Event EndPoint(事件端点) + +> 事件端点是应用程序和消息传递系统之间的接口。我们可以定义两种类型的端点 + +- 消费者端点 - 出现在路由开始并从传入通道读取传入事件。 +- 生产者端点 - 出现在路由的末尾并将传入事件写入传出通道。 + +#### Event Pipes & Filters(事件管道和过滤器) + +> 我们可以通过创建过滤器链(Apache Camel `Processor`)来构建路由,其中一个过滤器的输出被用于管道中下一个过滤器的输入。管道的主要优点是可以创建复杂的事件处理逻辑。 + +#### Event Routes(事件路由器) + +> 事件路由器是消费者的一种过滤器,并根据决策标准将它们重定向到适当的目标端点。 + +#### Event Converter(事件转换器) + +> 事件转换器用于修改事件内容,将其转换为不同的格式(换而言之 cloudevents -> Event (Camel) -> Binder Message(Spring Message),反之亦然)。 + +## EventMesh-Stream 组件接口 + +### Component(组件) + +Component 接口是主要的入口点,您可以使用 Component 对象作为工厂来创建 EndPoint 对象。 + +![Stream Component Interface](/images/design-document/stream-component-interface.png) + +### EndPoint(端点) + +EndPoint 作为创建消费者、生产者和事件对象的工厂。 + +- `createConsumer()` — 创建消费者端点,该端点表示路由开始的源端点。 +- `createProducer()` — 创建生产者端点,该端点表示路由末端的目标端点。 + +![Stream Component Routes](/images/design-document/stream-component-routes.png) + +#### Producer(生产者) + +用户可以创建以下类型的生产者 +> 同步生产者:处理线程阻塞,直到生产者完成事件处理。 + +![Stream Sync Producer](/images/design-document/stream-sync-producer.png) + +未来将会实现的生产者类型: + +- 异步生产者 - 生产者在子线程中处理事件。 + +#### Consumer(消费者) + +用户可以创建以下类型的消费者 +> 事件驱动的消费者:当消息绑定器调用消费者中的方法时,开始处理传入请求。 + +![Stream Event-Driven Consumer](/images/design-document/stream-event-driven-consumer.png) + +未来将会实现的消费者类型: + +- 定时轮训消费者 +- 自定义轮询消费者 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/00-connectors.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/00-connectors.md new file mode 100644 index 0000000000..50e393a558 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/00-connectors.md @@ -0,0 +1,51 @@ +# 连接器简介 + +## 连接器类型 + +连接器是代表用户应用程序与特定外部服务或底层数据源(例如数据库)交互的镜像或实例。连接器的类型可以是源(Source)或汇(Sink)。 + +连接器通过 `main()` 作为一个独立服务运行。 + +## 数据源(Source 端) + +源连接器从底层数据生产者获取数据,并在原始数据被转换为 CloudEvents 后将其传递给目标。源连接器不限制源如何检索数据(例如,源可以从消息队列中获取数据,也可以充当等待接收数据的 HTTP 服务器)。 + +## 数据汇(Sink 端) + +汇连接器接收 CloudEvents 并执行特定的业务逻辑(例如,MySQL 的汇连接器从 CloudEvents 中提取有用的数据,并将其写入 MySQL 数据库)。 + +## CloudEvents + +CloudEvents 是一种以通用格式描述事件数据的规范,以提供服务、平台和系统之间的互操作性。 + +## 实现连接器 + +使用 [eventmesh-openconnect-java](https://github.com/apache/eventmesh/tree/master/eventmesh-openconnect/eventmesh-openconnect-java) 实现 Source/Sink 接口即可添加新的连接器。 + +## 技术方案 + +### 结构与处理流程 + +![source-sink connector architecture](../../../../../../static/images/design-document/connector-architecture.png) + +### 详细设计 + +![eventmesh-connect-detail](../../../../../../static/images/design-document/connector-design-detail.png) + +### 描述 + +#### Worker + +Worker 分为 Source Worker 与 Sink Worker,由`Application`类进行触发运行,分别实现了`ConnectorWorker`接口的方法,其中包含了 worker 的运行生命周期,worker 承载了 connector 的运行。Worker 可以通过镜像的方式轻量的独立运行,内部集成了 eventmesh-sdk-java 模块,采用 CloudEvents 协议与 EventMesh 进行交互,目前默认采用 TCP 客户端,后续可以考虑支持动态可配。 + +#### Connector + +Connector 分为 Source Connector 与 Sink Connector,connector 有各自的配置文件,以及独立运行的方式,通过 worker 进行反射加载与配置解析,完成 Connector 的初始化以及后续运行工作,其中 Source Connector 实现 poll 方法,Sink Connector 实现 put 方法,统一使用`ConnectorRecord`承载数据。Source Connector 与 Sink Connector 均可独立运行。 + +#### ConnectorRecord with CloudEvents + +`ConnectorRecord`为 connector 层数据协议,当 worker 与 EventMesh 进行交互时需开发协议适配器进行`ConnectorRecord`到 CloudEvents 的协议转换。 + +#### Registry + +`Registry`模块负责存储同步不同 Connector 实例的数据的同步进度,确保多个 Connector 镜像或实例之间的高可用。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/01-rabbitmq-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/01-rabbitmq-connector.md new file mode 100644 index 0000000000..b2c46aa68c --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/01-rabbitmq-connector.md @@ -0,0 +1,42 @@ +# RabbitMQ + +## RabbitMQSinkConnector:从 EventMesh 到 RabbitMQ + +1. 启动你的 RabbitMQ 和 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 启动你的 RabbitMQConnectorServer,它将订阅到 EventMesh Runtime 中 `pubSubConfig.subject` 中定义的主题,并将数据发送到 RabbitMQ 中的 `connectorConfig.queueName`。 +4. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息,然后你将在 RabbitMQ 中接收到该消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TopicTest + idc: FT + env: PRD + group: rabbitmqSink + appId: 5031 + userName: rabbitmqSinkUser + passWord: rabbitmqPassWord +connectorConfig: + connectorName: rabbitmqSink + host: your.rabbitmq.server + port: 5672 + username: coyrqpyz + passwd: passwd + virtualHost: coyrqpyz + exchangeType: TOPIC + # 使用内置的 exchangeName 或在连接到 RabbitMQ 后创建新的 exchangeName。 + exchangeName: amq.topic + # 如果在连接之前不存在,RabbitMQ 将自动创建 routingKey 和 queueName。 + routingKey: eventmesh + queueName: eventmesh + autoAck: true +``` + +## RabbitMQSourceConnector:从 RabbitMQ 到 EventMesh + +1. 启动你的 RabbitMQ 和 EventMesh Runtime。 +2. 启用 sourceConnector 并检查 `source-config.yml`(与 sink-config.yml 基本相同)。 +3. 启动你的 RabbitMQConnectorServer,它将订阅到 RabbitMQ 中的 `connectorConfig.queueName`,并将数据发送到 EventMesh Runtime 中的 `pubSubConfig.subject`。 +4. 向队列发送一个 CloudEvent 消息,然后你将在 EventMesh 中接收到该消息。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/02-http-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/02-http-connector.md new file mode 100644 index 0000000000..95287d5c9e --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/02-http-connector.md @@ -0,0 +1,67 @@ +# HTTP + +## HTTP Source Connector + +### 配置 + +使用 HTTP source connector 前,需要进行 server 的配置。 +- 请在 `/resource/server-config.yml` 中配置 `sourceEnable`为`true` 以开启 source 功能。 +- 请在 `/resource/source-config.yml`中配置 source connector, 在此仅说明 `connectorConfig` 下的配置: + - `connectorName`, connector 的名称 + - (必需) `path`, 接口的路径 + - (必需) `port`, 接口的端口 + - `idleTimeout`, 空闲 TCP 连接超时时间,单位为秒。超过 `idleTimeout` 秒没有进行数据接收或发送的连接将会发生超时并被关闭。默认为 0, 不会发生超时。 + +### 启动 + +1. 启动 EventMesh Runtime +2. 启动 eventmesh-connector-http + +完成后,HTTP source connector 会作为一个 HTTP 服务器对外提供服务。 + +### 发送消息 + +你可以通过 HTTP 向 source connector 发送消息。 + +```yaml +connectorConfig: + connectorName: httpSource + path: /test + port: 3755 + idleTimeout: 5 +``` + +上述的例子在`source-config.yml`中配置了一个 URL `http://localhost:3755/test`. + +你可以按照 [cloudevent-spec](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/bindings/http-protocol-binding.md) 中的规定,以`binary`模式或者`structured`模式发送消息。 + +这里是两个例子: + +以`binary`模式发送消息。 + +```shell +curl --location --request POST 'http://localhost:3755/test' \ +--header 'ce-id: 1' \ +--header 'ce-specversion: 1.0' \ +--header 'ce-type: com.example.someevent' \ +--header 'ce-source: /mycontext' \ +--header 'ce-subject: test_topic' \ +--header 'Content-Type: text/plain' \ +--data-raw 'testdata' +``` + +以`structured`模式发送消息。 + +```shell +curl --location --request POST 'http://localhost:3755/test' \ +--header 'Content-Type: application/cloudevents+json' \ +--data-raw '{ + "id": "1", + "specversion": "1.0", + "type": "com.example.someevent", + "source": "/mycontext", + "subject":"test_topic", + "datacontenttype":"text/plain", + "data": "testdata" +}' +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/03-redis-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/03-redis-connector.md new file mode 100644 index 0000000000..cf56c33b64 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/03-redis-connector.md @@ -0,0 +1,33 @@ +# Redis + +## RedisSinkConnector:从 EventMesh 到 Redis 的消息队列 + +1. 启动你的 Redis 实例和 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 启动你的 `RedisConnectServer`,它将订阅到 EventMesh Runtime 中 `pubSubConfig.subject` 中定义的主题,并将数据发送到 Redis 中的 `connectorConfig.topic`。 +4. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息,然后你将在 Redis 中接收到该消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TopicTest + idc: FT + env: PRD + group: redisSink + appId: 5031 + userName: redisSinkUser + passWord: redisPassWord +connectorConfig: + connectorName: redisSink + server: redis://127.0.0.1:6379 + # Redis 中的主题 + topic: SinkTopic +``` + +## RedisSourceConnector:从 Redis 的消息队列 到 EventMesh + +1. 启动你的 Redis 实例和 EventMesh Runtime。 +2. 启用 sourceConnector 并检查 `source-config.yml`(与 sink-config.yml 基本相同)。 +3. 启动你的 RedisConnectServer,它将订阅到 Redis 中的 `connectorConfig.topic`,并将数据发送到 EventMesh Runtime 中的 `pubSubConfig.subject` +4. 向 Redis 的主题发送一个 CloudEvent 消息,然后你将在 EventMesh 中接收到该消息。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/04-mongodb-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/04-mongodb-connector.md new file mode 100644 index 0000000000..028fea6ba0 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/04-mongodb-connector.md @@ -0,0 +1,36 @@ +# MongoDB + +## MongoDBSinkConnector:从 EventMesh 到 MongoDB + +1. 启动你的 MongoDB 服务和 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 启动你的 MongoDBConnectorServer,它将订阅到 EventMesh Runtime 中 `pubSubConfig.subject` 中定义的主题,并将数据发送到 MongoDB 中的 `connectorConfig.collection`。 +4. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息,然后你将在 MongoDB 中接收到该消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TopicTest + idc: FT + env: PRD + group: rabbitmqSink + appId: 5031 + userName: rabbitmqSinkUser + passWord: rabbitmqPassWord +connectorConfig: + connectorName: mongodbSink + # 支持 REPLICA_SET 和 STANDALONE + connectorType: STANDALONE + # mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 + url: mongodb://127.0.0.1:27018 + database: yourDB + collection: yourCol +``` + +## MongoDBSourceConnector:从 MongoDB 到 EventMesh + +1. 启动你的 MongoDB 服务和 EventMesh Runtime。 +2. 启用 sourceConnector 并检查 `source-config.yml`(与 sink-config.yml 基本相同)。 +3. 启动你的 MongoDBSourceConnector,它将订阅到 MongoDB 中的 `connectorConfig.collection`,并将数据发送到 EventMesh Runtime 中的 `pubSubConfig.subject`。 +4. 向 MongoDB 中 `yourDB` 的 `yourCol` 写入一个 CloudEvent 消息,然后你将在 EventMesh 中接收到该消息。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/05-knative-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/05-knative-connector.md new file mode 100644 index 0000000000..5554a67c72 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/05-knative-connector.md @@ -0,0 +1,116 @@ +# Knative + +>随着 Knative Connector 设计的变动,这篇文档目前暂时过时了。 + +## 准备 + +### 创建 Knative Source 和 Sink + +我们使用 *cloudevents-player* [Knative 服务](https://knative.dev/docs/serving/) 作为例子。如果您不知道如何创建 *cloudevents-player* Knative 服务作为 source 和 sink,请按照这个 [链接](https://knative.dev/docs/getting-started/first-source/#creating-your-first-source) 的步骤进行创建。 + +### EventMesh 配置文件 + +- 将以下配置加入 [eventmesh-starter/build.gradle](https://github.com/apache/eventmesh/blob/master/eventmesh-starter/build.gradle) 文件 + +```bash +plugins { + id 'application' +} + +application { + mainClass = project.hasProperty("mainClass") ? project.getProperty("mainClass") : 'org.apache.eventmesh.starter.StartUp' + applicationDefaultJvmArgs = [ + '-Dlog4j.configurationFile=../eventmesh-runtime/conf/log4j2.xml', '-Deventmesh.log.home=../eventmesh-runtime/logs', '-Deventmesh.home=../eventmesh-runtime', '-DconfPath=../eventmesh-runtime/conf' + ] +} + +dependencies { + implementation project(":eventmesh-connector-plugin:eventmesh-connector-knative") + implementation project(":eventmesh-runtime") +} +``` + +- 将以下配置加入 [eventmesh-examples/build.gradle](https://github.com/apache/eventmesh/blob/master/eventmesh-examples/build.gradle) 文件 + +```bash +plugins { + id 'application' +} + +application { + mainClass = project.hasProperty("mainClass") ? project.getProperty("mainClass") : 'NULL' +} +``` + +- 在 [eventmesh-runtime/conf/eventmesh.properties](https://github.com/apache/eventmesh/blob/master/eventmesh-runtime/conf/eventmesh.properties) 文件中设置`eventMesh.connector.plugin.type=knative`变量 + +## 演示 + +### Knative 发布事件消息 / EventMesh 订阅 + +#### 步骤 1:启动一台 EventMesh 服务器 + +```bash +$ cd eventmesh-starter +$ ../gradlew -PmainClass=org.apache.eventmesh.starter.StartUp run +``` + +#### 步骤 2:从 Knative Source 发布一条消息 + +```bash +$ curl -i http://cloudevents-player.default.127.0.0.1.sslip.io -H "Content-Type: application/json" -H "Ce-Id: 123456789" -H "Ce-Specversion: 1.0" -H "Ce-Type: some-type" -H "Ce-Source: command-line" -d '{"msg":"Hello CloudEvents!"}' +``` + +#### 步骤 3:从 EventMesh 订阅 + +- 在 [ExampleConstants.java](https://github.com/apache/eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/common/ExampleConstants.java) 文件中设置 `public static final String EVENTMESH_HTTP_ASYNC_TEST_TOPIC = "messages";`变量 + +```bash +$ cd eventmesh-examples +$ ../gradlew -PmainClass=org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication run +``` + +#### 预期结果 + +以下`data`为`Hello CloudEvents!`的消息将会打印在 EventMesh 服务器的控制台上。 + +```bash +2022-09-05 16:37:58,237 INFO [eventMesh-clientManage-] DefaultConsumer(DefaultConsumer.java:60) - \ +[{"event":{"attributes":{"datacontenttype":"application/json","id":"123456789","mediaType":"application/json",\ +"source":"command-line","specversion":"1.0","type":"some-type"},"data":{"msg":"Hello CloudEvents!"},"extensions":{}},\ +"id":"123456789","receivedAt":"2022-09-05T10:37:49.537658+02:00[Europe/Madrid]","type":"RECEIVED"}] +``` + +### EventMesh 发布事件消息 / Knative 订阅 + +#### 步骤 1:启动一台 EventMesh 服务器 + +```bash +$ cd eventmesh-starter +$ ../gradlew -PmainClass=org.apache.eventmesh.starter.StartUp run +``` + +#### 步骤 2:从 EventMesh 发布一条消息 + +我们用 Knative Connector 的测试程序来演示这个功能。 + +```bash +$ cd eventmesh-connector-plugin/eventmesh-connector-knative +$ ../../gradlew clean test --tests KnativeProducerImplTest.testPublish +``` + +#### 步骤 3:从 Knative 订阅 + +```bash +$ curl http://cloudevents-player.default.127.0.0.1.sslip.io/messages +``` + +#### 预期结果 + +以下`data`为`Hello Knative from EventMesh!`的消息将会打印在 EventMesh 服务器的控制台上。 + +```bash +2022-09-05 16:52:41,633 INFO [eventMesh-clientManage-] DefaultConsumer(DefaultConsumer.java:60) - \ +[{"event":{"attributes":{"datacontenttype":"application/json","id":"1234","mediaType":"application/json",\ +"source":"java-client","specversion":"1.0","type":"some-type"},"data":{"msg":["Hello Knative from EventMesh!"]},"extensions":{}},"id":"1234","receivedAt":"2022-09-05T10:52:32.999273+02:00[Europe/Madrid]","type":"RECEIVED"}] +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/06-lark-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/06-lark-connector.md new file mode 100644 index 0000000000..06dc81f08e --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/06-lark-connector.md @@ -0,0 +1,36 @@ +# 飞书/Lark + +## Lark Sink Server 的配置与启动 + +使用 eventmesh-connector-lark 下沉事件之前,需要进行 server 的配置。 + +- 请在`/resource/server-config.yml`中自定义`sinkEnable`=`true`/`false`以开启/关闭 sink 功能。 +- 关于`/resource/sink-config.yml`,在此仅说明`sinkConnectorConfig`下的配置: + - `connectorName`, 指定 connector 名称 + - (必需)`appId`, lark 中获取的 appId + - (必需)`appSecret`, lark 中获取的 appSecret + - `receiveIdType`,接收 Id 的类型,默认且推荐使用`open_id`。可选 open_id/user_id/union_id/email/chat_id。 + - (必需)`receiveId`, 接收 Id,需要和`receiveIdType`对应。 + - `sinkAsync`, 是否异步下沉事件 + - `maxRetryTimes`, sink 事件失败时,最大重传的次数。默认 3 次。 + - `retryDelayInMills`, sink 事件失败时,重传事件的时间间隔。默认 1s,单位为毫秒。 + +## 可下沉飞书的 CLoudEvent + +使用 eventmesh-connector-lark 下沉事件时,需要在 CloudEvent 中添加对应的 extension filed: + +- 当 key=`templatetype4lark`时,value=`text`/`markdown`,表明该事件的文本类型。 +- 当文本类型 `templatetype4lark` 为 markdown 时,可以为文本设置标题。添加 extension:key=`markdownmessagetitle4lark`,value 为该事件的标题。 +- 当 key=`atusers4lark`时,value=`id-0,name-0;id-1,name-1`,表明该事件需要`@`某些用户。 + - id 推荐使用 **open_id**。 + - 当文本属于 text 类型时,id 可以是 **open_id/union_id/user_id**; 当文本属于 markdown 类型时,id 可以是 **open_id/user_id**。特别地,当应用类型为 [自定义机器人](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN) 且文本属于 markdown 类型,则仅支持使用 **open_id** 来`@`用户。 + - 当文本属于 text 类型且 id 无效时,将利用 name 代替展示;当文本属于 markdown 类型时且 id 无效时,直接抛出异常(您应该尽量保证 id 的正确性,而 name 则可以考虑省略)。 +- 当 key=`atall4lark`时,value=`true`/`false`,表明该事件需要`@`所有人。 + +## 飞书开放平台 API + +有关该模块涉及到的飞书开放平台 API,请点击以下链接: + +- **发送消息**,请 [查看这里](https://open.feishu.cn/document/server-docs/im-v1/message/create?appId=cli_a5e1bc31507ed00c) +- **text**,请 [查看这里](https://open.feishu.cn/document/server-docs/im-v1/message-content-description/create_json#c9e08671) +- **markdown**,请 [查看这里](https://open.feishu.cn/document/common-capabilities/message-card/message-cards-content/using-markdown-tags) \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/07-dingtalk-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/07-dingtalk-connector.md new file mode 100644 index 0000000000..1228a9ea29 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/07-dingtalk-connector.md @@ -0,0 +1,34 @@ +# 钉钉 + +## DingtalkSinkConnector:从 EventMesh 到钉钉 + +1. 启动你的 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TEST-TOPIC-DINGTALK + idc: FT + env: PRD + group: dingTalkSink + appId: 5034 + userName: dingTalkSinkUser + passWord: dingTalkPassWord +sinkConnectorConfig: + connectorName: dingTalkSink + # 以下配置参考 https://open.dingtalk.com/document/orgapp/the-robot-sends-a-group-message + appKey: dingTalkAppKey + appSecret: dingTalkAppSecret + openConversationId: dingTalkOpenConversationId + robotCode: dingTalkRobotCode +``` + +### CloudEvent 属性 + +使用 eventmesh-connector-dingtalk 下沉事件时,需要在 CloudEvent 中添加对应的 extension filed: + +- 当 key=`dingtalktemplatetype`时,value=`text`/`markdown`,表明该事件的文本类型。 +- 当文本类型 `dingtalktemplatetype` 为 markdown 时,可以为文本设置标题。添加 extension:key=`dingtalkmarkdownmessagetitle`,value 为该事件的标题。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/08-wecom-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/08-wecom-connector.md new file mode 100644 index 0000000000..334a51eaad --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/08-wecom-connector.md @@ -0,0 +1,30 @@ +# 企业微信 + +## WecomSinkConnector:从 EventMesh 到企业微信 + +1. 启动你的 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TEST-TOPIC-WECOM + idc: FT + env: PRD + group: weComSink + appId: 5034 + userName: weComSinkUser + passWord: weComPassWord +sinkConnectorConfig: + connectorName: weComSink + # 以下配置请参考文档:https://developer.work.weixin.qq.com/document/path/90236 + robotWebhookKey: weComRobotWebhookKey +``` + +### CloudEvent 属性 + +使用 eventmesh-connector-wecom 下沉事件时,需要在 CloudEvent 中添加对应的 extension filed: + +- 当 key=`wecomtemplatetype`时,value=`text`/`markdown`,表明该事件的文本类型。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/09-slack-connector.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/09-slack-connector.md new file mode 100644 index 0000000000..ede3d66b03 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/09-slack-connector.md @@ -0,0 +1,25 @@ +# Slack + +## SlackSinkConnector:从 EventMesh 到 Slack + +1. 启动你的 EventMesh Runtime。 +2. 启用 sinkConnector 并检查 `sink-config.yml`。 +3. 使用在 `pubSubConfig.subject` 中指定的 Topic,向 EventMesh 发送消息。 + +```yaml +pubSubConfig: + # 默认端口 10000 + meshAddress: your.eventmesh.server:10000 + subject: TEST-TOPIC-SLACK + idc: FT + env: PRD + group: slackSink + appId: 5034 + userName: slackSinkUser + passWord: slackPassWord +sinkConnectorConfig: + connectorName: slackSink + # 以下配置请参考文档:https://api.slack.com/messaging/sending + appToken: slackAppToken + channelId: slackChannelId +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/_category_.json new file mode 100644 index 0000000000..b47c4291f5 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-connect/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Connect", + "collapsed": false +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-schema-registry.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-schema-registry.md new file mode 100644 index 0000000000..209d24f8fa --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/03-schema-registry.md @@ -0,0 +1,134 @@ +# EventMesh 模式注册中心 (OpenSchema) + +## Schema 和 Schema 注册概述 + +### Schema + +模式代表对序列化实例(字符串/流/s 文件/……)的描述,具有两个属性。首先,它也是序列化类型的格式。其次,它定义了这些序列化实例应满足的要求。 + +除了描述序列化实例,模式还可用于验证实例是否合法。因为它定义了序列化实例的 `type`(和其他属性)以及内部的键。以 JSON 模式为例,它不仅可用于描述 JSON 字符串,还可用于验证字符串是否满足模式 [[1]](#参考文献) 中定义的属性。 + +常见的模式有 JSON 模式、Protobuf 模式和 Avro 模式。 + +### Schema 注册中心 + +模式注册中心是一个提供 RESTful 接口的服务器。它可以接收和存储来自客户端的模式,并为其他客户端从中检索模式提供接口。 + +它可用于验证过程和(去)序列化过程 + +### 不同项目中 Schema 注册表的比较 + +项目 | 应用程序 +:---: | :--- +EMQ[[2]](#参考文献) | 主要用于(去)序列化过程。使用 "模式注册表 "和 "规则匹配 "将信息从一种序列化格式传输到另一种序列化格式。serialization format to another. +Pulsar[[3]](#参考文献) | 主要用于验证过程。使用 "模式注册表 "验证报文。 +Confluentinc[[4]](#参考文献) | 在验证和(去)序列化过程中。 + +## OpenSchema 概览 + +OpenSchema[[5]](#参考文献) 提出了在越来越多的现代云原生应用程序中交换消息和事件时的数据模式规范。它从三个方面(主题/模式/兼容性)设计了用于存储和检索 Avro、JSON Schema 和 Protobuf3 模式的 RESTful 接口。 + +## 需求(目标) + +| 需求 ID | 需求描述 | 评价 | +| :------------- | ------------------------------------------------------------ | ------------- | +| F-1 | 在传输过程中,信息无需包含模式信息,从而提高效率。| 功能性 | +| F-2 | 可根据模式验证来自生产者的信息内容是否正确序列化。 | 功能性 | + +## 详细设计 + +### 架构设计 + +![OpenSchema](/images/design-document/schema-registry-architecture.png) + +### Schema Registry 下的信息传输过程 + +![Process](/images/design-document/schema-registry-process.jpg) + +信息传输的高级流程包括以下 10 个步骤: + +- 1: 消费者从 EventMesh 订阅 "主题 "信息。 +- 2: 生产者向 EventMesh 注册模式。 +- 3: EventMesh 向模式注册中心注册模式。 +- 4: 模式注册中心返回新创建模式的 ID;EventMesh 缓存该 ID 和模式。 +- 5: EventMesh 将模式的 ID 返回给生产者。 +- 6: Producer 在信息前面修补 ID,并将信息发送到 EventMesh。 +- 7: EventMesh 验证入口端口中的报文并将其发送到 EventStore;EventMesh 从 EventStore 中检索报文。 +- 8: EventMesh 解封 id 并将其发送至模式注册表(如果本地缓存中不存在此类``)。 +- 9: Schema Registry 返回模式,EventMesh 对其进行缓存。 +- 10: EventMesh 在消息前修补模式,并将其推送给消费者。 + +## 当前进度 + +### 状态 + +**当前状态**: 开发中 + +**讨论 issue**: ISSUE #339 + +### 修改建议 + +该提案有两个方面。 + +首先是一个独立的开放模式注册表,其中包括模式的存储和兼容性检查。 +该提案正在制定中。 + +其次是 EventMesh 中 Open Schema 的集成,其中包括架构验证。该提案有待制定。 + +对于第一个提案,一些进展情况如下。 + +#### 状态代码和异常代码 + +No. | 状态码 | 异常码 | 描述 | 状态 +--- | :---: | :---: | :---: | :---: +1 | 401 | 40101 | 未授权异常 | ✔ +2 | 404 | 40401 | Schema 不存在异常 | ✔ +3 | ^ | 40402 | Subject 不存在异常 | ✔ +4 | ^ | 40403 | 版本不存在异常 | ✔ +5 | 409 | 40901 | 兼容性异常 | ✔ +6 | 422 | 42201 | Schema 格式异常 | ✔ +7 | ^ | 42202 | Subject 格式异常 | ✔ +8 | ^ | 42203 | 版本格式异常 | ✔ +9 | ^ | 42204 | 兼容性格式异常 | ✔ +10 | 500 | 50001 | 存储服务异常 | ✔ +11 | ^ | 50002 | 超时异常 | ✔ + +#### API 开发状态 + +No. | 类型 | URL | 响应 | 异常 | 代码是否完成 | 测试是否完成 +--- | --- | --- | --- | --- | --- | --- +1 | GET | /schemas/ids/{string: id} | `Schema.class` | 40101\40401\50001 | ✔ | ❌ +2 | GET | /schemas/ids/{string: id}/subjects | `SubjectAndVersion.class` | 40101\40401\50001 | ✔ | ❌ +3 | GET | /subjects | `List\` | 40101\50001 | ✔ | ❌ +4 | GET | /subjects/{string: subject}/versions | `List\` | 40101\40402\50001 | ✔ | ❌ +5 | DELETE | /subjects/(string: subject) | `List\` | 40101\40402\50001 | ✔ | ❌ +6 | GET | /subjects/(string: subject) | `Subject.class` | 40101\40402\50001 | ✔ | ❌ +7 | GET | /subjects/(string: subject)/versions/(version: version)/schema | `SubjectWithSchema.class` | 40101\40402\40403\50001 | ✔ | ❌ +8 | POST | /subjects/(string: subject)/versions | `SchemaIdResponse.class` | 40101\40901\42201\50001\50002 | - | ❌ +9 | POST | /subjects/(string: subject)/ | `Subject.class` | 40101\40901\42202\50001\50002 | ✔ | ❌ +10 | DELETE | /subjects/(string: subject)/versions/(version: version) | `int` | 40101\40402\40403\40901\50001| - | ❌ +11 | POST | /compatibility/subjects/(string: subject)/versions/(version: version) | `CompatibilityResultResponse.class` | 40101\40402\40403\42201\42203\50001| - | ❌ +12 | GET | /compatibility/(string: subject) | `Compatibility.class` | 40101\40402\50001 | ✔ | ❌ +13 | PUT | /compatibility/(string: subject) | `Compatibility.class` | 40101\40402\40901\42204\50001 | - | ❌ + +#### 项目总体结构 + +```SchemaController.java```+```SchemaService.java``` : ```OpenSchema 7.1.1~7.1.2 (API 1~2)``` + +```SubjectController.java```+```SubjectService.java``` : ```OpenSchema 7.2.1~7.2.8 (API 3~10)``` + +```CompatibilityController.java```+```CompatibilityService.java``` : ```OpenSchema 7.3.1~7.3.3 (API 11~13)``` + ```Check for Compatibility``` + +![项目结构](/images/design-document/schema-registry-project-structure.png) + +## 参考文献 + +[1] [Schema 验证器 (github.com)](https://github.com/search?q=schema+validator) + +[2] [EMQ: Schema Registry](https://www.jianshu.com/p/33e0655c642b) + +[3] [Pulsar: Schema Registry](https://mp.weixin.qq.com/s/PaB66-Si00cX80py5ig5Mw) + +[4] [confluentinc/schema-registry](https://github.com/confluentinc/schema-registry) + +[5] [openmessaging/openschema](https://github.com/openmessaging/openschema) diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/_category_.json new file mode 100644 index 0000000000..2a0150571e --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/design-document/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 6, + "label": "开发文档", + "collapsed": false +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/01-store.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/01-store.md new file mode 100644 index 0000000000..6a9a3894d2 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/01-store.md @@ -0,0 +1,49 @@ +# Event Store 事件存储 + +## 1 前提 + +- 建议使用 64 位的 Linux / Unix 系统 +- 64 位 JDK 8 或 JDK 11 +- 4GB+ 可用磁盘,用于 Event Store 服务器。 + +本文将以 RocketMQ 事件存储为例,您也可以选择其它 [EventMesh 支持的事件存储](../roadmap.md#事件存储实现状态)。EventMesh 在非 standalone 模式下,依赖 RocketMQ 作为存储层。若您保持默认的 standalone 模式,则可跳过该步,直接进行 EventMesh Runtime 的部署。 + +在生产环境应使用 standalone 之外的事件存储,以支持更大的吞吐量和更高的可用性。 + +## 2 下载 + +从 [RocketMQ 官方网站](https://rocketmq.apache.org/download/) 下载 Binary 代码(推荐使用 4.9.* 版本),这里以 4.9.4 为例: + +```shell +unzip rocketmq-all-4.9.4-bin-release.zip +cd rocketmq-all-4.9.4-bin-release/ +``` + +![rocketmq_1](/images/install/rocketmq_1.png) + +## 3 启动 + +启动 Name Server: + +```shell +nohup sh bin/mqnamesrv & tail -f ~/logs/rocketmqlogs/namesrv.log +``` + +如果在看到 The Name Server boot success...,则说明 Name Server 启动成功。 + +![rocketmq_2](/images/install/rocketmq_2.png) + +启动 Broker: + +```shell +nohup sh bin/mqbroker -n localhost:9876 & +tail -f ~/logs/rocketmqlogs/broker.log +``` + +如果看到 The broker boot success...,则说明 Broker 启动成功 + +至此 Event Store 的部署已完成,请转至下一步完成 [EventMesh Runtime](./03-runtime.md) 的部署 + +## 参考 + +关于 RocketMQ 的其他更多资料,请参考 https://rocketmq.apache.org/docs/quick-start/. diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/02-store-with-docker.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/02-store-with-docker.md new file mode 100644 index 0000000000..bc1c450e04 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/02-store-with-docker.md @@ -0,0 +1,69 @@ +# Event Store Docker 部署 + +## 1. 前提 + +- 建议使用 64 位的 Linux / Unix 系统 +- 4GB+ 可用磁盘,用于 Event Store 服务器。 + +本文将以 RocketMQ 事件存储为例,您也可以选择其它 [EventMesh 支持的事件存储](../roadmap.md#事件存储实现状态)。EventMesh 在非 standalone 模式下,依赖 RocketMQ 作为存储层。若您保持默认的 standalone 模式,则可跳过该步,直接进行 EventMesh Runtime 的部署。 + +在生产环境应使用 standalone 之外的事件存储,以支持更大的吞吐量和更高的可用性。 + +## 2. Docker 部署 + +### 2.1 拉取镜像 + +在命令行输入如下命令直接从 Docker Hub 上获取 RocketMQ 镜像: + +```shell +#获取 rocketmq 镜像 +sudo docker pull apache/rocketmq:4.9.4 +``` + +您可以使用以下命令列出并查看本地已有的镜像: + +```shell +sudo docker images +``` + +如果终端显示如下所示的镜像信息,则说明 RocketMQ 镜像已经成功下载到本地。 + +```shell +REPOSITORY TAG IMAGE ID CREATED SIZE +apache/rocketmq 4.9.4 a2a50ca263c3 13 months ago 548MB +``` + +![rocketmq_docker_1](/images/install/rocketmq_docker_1.png) + +### 2.2 运行容器 + +运行 namesrv 容器和 broker 容器: + +```shell +sudo docker run -d -p 9876:9876 \ + -v `pwd`/data/namesrv/logs:/root/logs \ + -v `pwd`/data/namesrv/store:/root/store \ + --name rmqnamesrv \ + apache/rocketmq:4.9.4 \ + sh mqnamesrv +``` + +运行 broker 容器: + +```shell +sudo docker run -d -p 10911:10911 -p 10909:10909 \ + -v `pwd`/data/broker/logs:/root/logs \ + -v `pwd`/data/broker/store:/root/store \ + --name rmqbroker \ + --link rmqnamesrv:namesrv \ + -e "NAMESRV_ADDR=namesrv:9876" \ + apache/rocketmq:4.9.4 \ + sh mqbroker -c ../conf/broker.conf + +``` + +![rocketmq_docker_2](/images/install/rocketmq_docker_2.png) + +请注意 `rocketmq-broker ip` 是 `pod ip`, 如果你想修改这个 ip, 可以通过挂载容器中 `broker.conf` 文件的方式并修改文件中的 `brokerIP1` 配置项为自定义值。 + +至此 Event Store 的部署已完成,请转至下一步完成 [EventMesh Runtime](04-runtime-with-docker.md) 的部署。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/03-runtime.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/03-runtime.md new file mode 100644 index 0000000000..52bddeedb6 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/03-runtime.md @@ -0,0 +1,274 @@ +# EventMesh Runtime 快速开始 + +EventMesh Runtime 是 EventMesh 集群中有状态的 Mesh 节点,负责 Source Connector 与 Sink Connector 之间的事件传输,并可以使用 Event Store 作为事件的存储队列。 + +![EventMesh Runtime](../../../../../static/images/design-document/runtime.png) + +## 1. 部署二进制发行版 + +### 1.1 环境 + +- 建议使用 64 位的 Linux / Unix 系统 +- 64 位 JDK 8 或 JDK 11 + +### 1.2 下载 + +从 [EventMesh Download](https://eventmesh.apache.org/download) 页面下载最新版本的 Binary Distribution 发行版并解压: + +```shell +wget https://dlcdn.apache.org/eventmesh/1.10.0/apache-eventmesh-1.10.0-bin.tar.gz +tar -xvzf apache-eventmesh-1.10.0-bin.tar.gz +cd apache-eventmesh-1.10.0 +``` + +### 1.3 配置 + +本文将以 RocketMQ 事件存储为例,您也可以选择其它 [EventMesh 支持的事件存储](../roadmap.md#事件存储实现状态)。若您选择非 standalone 模式,请确保 [RocketMQ 已成功启动](https://rocketmq.apache.org/docs/quick-start/) 并且可以使用 IP 地址访问到;若您保持默认的 standalone 模式,则无需启动 RocketMQ。 + +#### 1.3.1 EventMesh Runtime 配置 + +此配置文件中包含 EventMesh Runtime 环境和集成的插件的配置。 + +```shell +vim conf/eventmesh.properties +``` + +指定事件存储为 RocketMQ: + +```properties +# storage plugin +eventMesh.storage.plugin.type=rocketmq +``` + +请检查配置文件里的默认端口是否已被占用,如果被占用,请修改为未被占用的端口: + +| 属性 | 默认值 | 备注 | +| -------------------------------- | ------ | ------------- | +| eventMesh.server.tcp.port | 10000 | TCP 监听接口 | +| eventMesh.server.http.port | 10105 | HTTP 监听接口 | +| eventMesh.server.grpc.port | 10205 | gRPC 监听接口 | +| eventMesh.server.admin.http.port | 10106 | HTTP 管理接口 | + +#### 1.3.2 事件存储配置 + +以 RocketMQ 为例,配置文件中包含连接 RocketMQ namesrv 所需的参数。 + +编辑 `rocketmq-client.properties`: + +```shell +vim conf/rocketmq-client.properties +``` + +如果您正在运行的 namesrv 地址不是配置文件中的默认值,请将其修改为实际正在运行的 namesrv 地址。 + +| 属性 | 默认值 | 备注 | +| ------------------------------------- | ----------------------------- | ------------------------ | +| eventMesh.server.rocketmq.namesrvAddr | 127.0.0.1:9876;127.0.0.1:9876 | RocketMQ namesrv address | + +### 1.4 启动 + +执行 `start.sh` 脚本启动 EventMesh Runtime: + +```shell +bash bin/start.sh +``` + +若脚本仅打印以下三行,未输出其它错误信息,则代表脚本执行成功: + +```shell +EventMesh using Java version: 8, path: /usr/local/openjdk-8/bin/java +EVENTMESH_HOME : /data/app/eventmesh +EVENTMESH_LOG_HOME : /data/app/eventmesh/logs +``` + +接着,查看 EventMesh Runtime 输出的日志,检查 EventMesh 的运行状态: + +```shell +tail -n 50 -f logs/eventmesh.out +``` + +当日志输出`server state:RUNNING`,则代表 EventMesh Runtime 启动成功了。 + +停止 EventMesh Runtime: + +```shell +bash bin/stop.sh +``` + +脚本打印`shutdown server ok!`时,代表 EventMesh Runtime 已停止。 + +> 在此版本,你可能需要使用`dos2unix`将脚本的 CRLF 换行转换到 LF 换行。 + +## 2. 构建二进制分发包 + +### 2.1 环境 + +- 建议使用 64 位的 Linux / Unix 系统 +- 64 位 JDK 8 或 JDK 11 +- [Gradle](https://docs.gradle.org/current/userguide/installation.html) 7.0+(可选),本文档中给出的构建命令使用 Gradle Wrapper,无需用户自行配置 Gradle 环境。您也可以于 `gradle/wrapper/gradle-wrapper.properties` 文件中查看您使用的 EventMesh 版本所推荐的 Gradle 版本,使用您本机的 Gradle 编译。 + +### 2.2 下载 + +从 [EventMesh Download](https://eventmesh.apache.org/download) 下载 Source Code 源代码并解压: + +```shell +wget https://dlcdn.apache.org/eventmesh/1.10.0/apache-eventmesh-1.10.0-source.tar.gz +tar -xvzf apache-eventmesh-1.10.0-source.tar.gz +cd apache-eventmesh-1.10.0-src/ +``` + +您也可以选择从 GitHub 拉取代码: + +```shell +git clone https://github.com/apache/eventmesh.git +cd eventmesh/ +``` + +### 2.3 构建 + +EventMesh 基于 JDK8 开发,二进制发行版也基于 JDK8 构建。推荐在 JDK8 环境下运行 EventMesh Runtime。 + +#### 在 JDK8 环境运行 + +部分源代码需要在 JDK11 下生成: + +```shell +./gradlew clean generateGrammarSource --parallel --daemon +``` + +`generateGrammarSource`任务会在`org.apache.eventmesh.connector.jdbc.antlr4.autogeneration`包下生成`ANTLR`所需的源代码。 + +接着,在 JDK8 下构建 EventMesh Runtime: + +```shell +./gradlew clean dist -x spotlessJava -x generateGrammarSource --parallel --daemon +``` + +构建完成后,请前往 [2.4 打包插件](#24-打包插件)。 + +> 您可以使用`update-alternatives`或`JAVA_HOME`等方式切换 JDK 版本,并使用`java -version`查看当前 JDK 版本。 + +#### 在 JDK11 环境运行 + +如果您希望以 JDK11 作为 EventMesh Runtime 的运行环境,则执行: + +```shell +./gradlew clean dist --parallel --daemon +``` + +构建完成后,请前往 [2.4 打包插件](#24-打包插件)。 + +### 2.4 打包插件 + +`installPlugin` 任务会将构建完毕的插件复制到 `dist` 目录中: + +```shell +./gradlew installPlugin +``` + +EventMesh 会根据 `eventmesh.properties` 中的配置,加载 `plugin` 目录下的插件。 + +构建成功后,项目根目录下的 `dist` 目录即为 EventMesh 的二进制文件目录。配置与启动请参考 [部署二进制发行版](#1-部署二进制发行版)。 + +## 3. 从源代码启动 + +### 3.1 依赖 + +- 建议使用 64 位的 Linux / Unix 系统 +- 64 位 JDK 8 或 JDK 11 +- [Gradle](https://docs.gradle.org/current/userguide/installation.html) 7.0+(可选),本文档中给出的构建命令使用 Gradle Wrapper,无需用户自行配置 Gradle 环境。您也可以于 `gradle/wrapper/gradle-wrapper.properties` 文件中查看您使用的 EventMesh 版本所推荐的 Gradle 版本,使用您本机的 Gradle 编译。 +- 推荐使用 IDE(集成开发环境)导入 EventMesh。推荐使用`Intellij IDEA`作为 IDE。 + +### 3.2 下载 + +从 GitHub 拉取代码: + +```shell +git clone https://github.com/apache/eventmesh.git +cd eventmesh/ +``` + +您也可以从 [EventMesh Download](https://eventmesh.apache.org/download) 下载 Source Code 源代码发行版并解压: + +```shell +wget https://dlcdn.apache.org/eventmesh/1.10.0/apache-eventmesh-1.10.0-source.tar.gz +tar -xvzf apache-eventmesh-1.10.0-source.tar.gz +cd apache-eventmesh-1.10.0-src/ +``` + +### 3.3 项目结构说明 + +| 主要模块 | 描述 | +| ------------------------ | ------------------------------------------------------------ | +| eventmesh-starter | 本地运行 EventMesh 项目的入口 | +| eventmesh-runtime | EventMesh Runtime 运行时模块 | +| eventmesh-connectors | 用于连接事件源与事件汇的 [Connector](../design-document/03-connect/00-connectors.md),支持[多种服务和平台](../roadmap.md#连接器实现状态) | +| eventmesh-storage-plugin | EventMesh Runtime 的[事件存储](../roadmap.md#事件存储实现状态)插件 | +| eventmesh-sdks | EventMesh 的多语言客户端 SDK,包括 Java、Go、C、Rust 等 | +| eventmesh-examples | SDK 使用示例 | +| eventmesh-spi | EventMesh SPI 加载模块 | +| eventmesh-common | 公共类与方法模块 | + +> 插件模块遵循 EventMesh 定义的 SPI 规范,自定义的 SPI 接口需要使用注解 `@EventMeshSPI` 标识。 +> +> 插件实例需要在对应模块中的 `/main/resources/META-INF/eventmesh` 下配置相关接口与实现类的映射文件,文件名为 SPI 接口的全限定类名。 +> +> 文件内容为插件实例名到插件实例的映射,具体可以参考 `eventmesh-storage-rocketmq` 插件模块。 + +### 3.4 插件说明 + +#### 3.4.1 安装插件 + +EventMesh 具有 SPI 机制,使 EventMesh 能够发现并加载插件。有两种方式安装插件: + +- Classpath 加载:本地开发时可以通过在 `eventmesh-starter` 模块的 `build.gradle` 中添加依赖,例如添加 Kafka Storage Plugin: + +```gradle +dependencies { + implementation project(":eventmesh-runtime") + // 示例:加载 Kafka Storage Plugin + implementation project(":eventmesh-storage-plugin:eventmesh-storage-kafka") +} +``` + +- 文件加载:通过将插件安装到插件目录,EventMesh 在运行时会根据条件自动加载插件目录下的插件。请参考 [2.3 构建](#23-构建) 和 [2.4 打包插件](#24-打包插件)。 + +>当您对源代码作出更改后,建议在 [2.3 构建](#23-构建) 给出的命令中添加`build`任务,以重新编译和运行单元测试。如: +> +>```shell +>./gradlew clean build dist -x spotlessJava -x generateGrammarSource --parallel --daemon +>``` + +#### 3.4.2 使用插件 + +EventMesh 会默认加载 `dist/plugin` 目录下的插件,可以通过`-DeventMeshPluginDir=your_plugin_directory`来改变插件目录。运行时需要使用的插件实例可以在 +`confPath`目录下面的`eventmesh.properties`中进行配置。例如通过以下设置声明使用 RocketMQ 作为 Event Store: + +```properties +# storage plugin +eventMesh.storage.plugin.type=rocketmq +``` + +### 3.5 配置 VM 参数 + +```properties +-Dlog4j.configurationFile=eventmesh-runtime/conf/log4j2.xml +-Deventmesh.log.home=eventmesh-runtime/logs +-Deventmesh.home=eventmesh-runtime +-DconfPath=eventmesh-runtime/conf +``` + +如果操作系统为 Windows,需要将斜杠替换为反斜杠`\`。 + +### 3.6 启动 + +运行`eventmesh-starter`模块下`org.apache.eventmesh.starter.StartUp`类的`main()`方法即可启动 EventMesh Runtime。 + +### 3.7 停止 + +控制台打印以下日志时,EventMesh Runtime 已停止。 + +```log +DEBUG StatusConsoleListener Shutdown hook enabled. Registering a new one. +WARN StatusConsoleListener Unable to register Log4j shutdown hook because JVM is shutting down. Using SimpleLogger +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/04-runtime-with-docker.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/04-runtime-with-docker.md new file mode 100644 index 0000000000..c7fd3dc209 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/04-runtime-with-docker.md @@ -0,0 +1,169 @@ +# EventMesh Runtime Docker 快速开始 + +您可以使用 Docker 部署 EventMesh Runtime。本文将以 RocketMQ 事件存储为例,您也可以选择其它 [EventMesh 支持的事件存储](../roadmap.md#事件存储实现状态)。 + +## 1. 前提 + +1. 建议使用 64 位的 Linux / Unix 系统。 +2. 请预先安装 Docker Engine。Docker 的安装过程可以参考 [Docker 官方文档](https://docs.docker.com/engine/install/)。 +3. 建议掌握基础的 Docker 概念和命令行,例如注册中心、挂载等等。不过这不是必须的,因为本次操作所需的命令都已为您列出。 +4. 若您选择非 standalone 模式,请确保 [RocketMQ 已成功启动](https://rocketmq.apache.org/docs/quick-start/) 并且可以使用 IP 地址访问到;若您保持默认的 standalone 模式,则无需启动 RocketMQ。 + +## 2. 获取 EventMesh Runtime 镜像 + +首先,您可以打开一个命令行,并且使用下面的 `pull` 命令从 [Docker Hub](https://hub.docker.com/r/apache/eventmesh/tags) 中下载 [最新版本的 EventMesh](https://eventmesh.apache.org/events/release-notes/) 。 + +```shell +sudo docker pull apache/eventmesh:latest +``` + +您可以使用以下命令列出并查看本地已有的镜像。 + +```shell +sudo docker images +``` + +如果终端显示如下所示的镜像信息,则说明 EventMesh 镜像已经成功下载到本地。 + +```shell +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +apache/eventmesh latest f32f9e5e4694 2 days ago 917MB +``` + +## 3. 挂载配置文件 + +如果您使用 standalone 模式启动 EventMesh Runtime,并且没有自定义配置,可以跳转至下一步骤。 + +首先,在宿主机上创建 EventMesh 的配置文件目录。此目录可以自由指定: + +```shell +sudo mkdir -p /data/eventmesh/conf +cd /data/eventmesh/conf +``` + +### 3.1 EventMesh Runtime 配置 + +此配置文件中包含 EventMesh Runtime 环境和集成的插件的配置。 + +下载配置文件(替换下载链接中的`1.10.0`为您正在使用的版本): + +```shell +sudo wget https://raw.githubusercontent.com/apache/eventmesh/1.10.0-prepare/eventmesh-runtime/conf/eventmesh.properties +``` + +编辑 `eventmesh.properties`: + +```shell +sudo vim eventmesh.properties +``` + +指定事件存储为 RocketMQ: + +```properties +# storage plugin +eventMesh.storage.plugin.type=rocketmq +``` + +请检查配置文件里的默认端口是否已被占用,如果被占用,请修改为未被占用的端口: + +| 属性 | 默认值 | 备注 | +| -------------------------------- | ------ | ------------- | +| eventMesh.server.tcp.port | 10000 | TCP 监听接口 | +| eventMesh.server.http.port | 10105 | HTTP 监听接口 | +| eventMesh.server.grpc.port | 10205 | gRPC 监听接口 | +| eventMesh.server.admin.http.port | 10106 | HTTP 管理接口 | + +### 3.2 事件存储配置 + +以 RocketMQ 为例,配置文件中包含连接 RocketMQ namesrv 所需的参数。 + +下载配置文件(替换下载链接中的`1.10.0`为您正在使用的版本): + +```shell +sudo wget https://raw.githubusercontent.com/apache/eventmesh/1.10.0-prepare/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/resources/rocketmq-client.properties +``` + +编辑 `rocketmq-client.properties`: + +```shell +sudo vim rocketmq-client.properties +``` + +如果您正在运行的 namesrv 地址不是配置文件中的默认值,请将其修改为实际正在运行的 namesrv 地址。 + +| 属性 | 默认值 | 备注 | +| ------------------------------------- | ----------------------------- | ------------------------ | +| eventMesh.server.rocketmq.namesrvAddr | 127.0.0.1:9876;127.0.0.1:9876 | RocketMQ namesrv address | + +>如果您无法使用给出的链接下载配置文件,您可以在 EventMesh 二进制发行版的`conf`路径下找到所有的配置文件。 + +## 4. 运行 EventMesh Runtime 容器 + +使用以下命令启动 EventMesh 容器: + +```shell +sudo docker run -d --name eventmesh -p 10000:10000 -p 10105:10105 -p 10205:10205 -p 10106:10106 -v /data/eventmesh/conf/eventmesh.properties:/data/app/eventmesh/conf/eventmesh.properties -v /data/eventmesh/conf/rocketmq-client.properties:/data/app/eventmesh/conf/rocketmq-client.properties -t apache/eventmesh:latest +``` + +`docker run`命令参数介绍: + +- `-p <宿主机端口>:<容器端口>`:绑定容器端口和宿主机端口。如果您修改过 EventMesh Runtime 配置中的默认端口,或者宿主机的端口已被占用,请相应地修改为您指定的端口。 + +- `-v <宿主机路径>:<容器路径>`:将宿主机中的配置文件挂载到容器中。如果您存放 EventMesh 配置文件的路径不是`/data/eventmesh/conf`,请修改宿主机路径为您指定的路径。如果您没有自定义配置文件,请删除此参数。 +- `--name eventmesh`:自定义的容器名称。此名称是唯一的。 +- `-t apache/eventmesh:latest`:容器使用的镜像。 + +执行`docker run`命令后,将会返回容器的 ID。使用此命令查看所有正在运行的容器的状态: + +```shell +sudo docker ps +``` + +将会打印: + +```shell +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +b7a1546ee96a apache/eventmesh:latest "bash bin/start.sh" 10 seconds ago Up 8 seconds 0.0.0.0:10000->10000/tcp, :::10000->10000/tcp, 0.0.0.0:10105-10106->10105-10106/tcp, :::10105-10106->10105-10106/tcp, 0.0.0.0:10205->10205/tcp, :::10205->10205/tcp eventmesh +``` + +如果 EventMesh Runtime 容器不在此命令打印的列表中,则代表容器未能成功启动。您可以使用以下命令查看启动时的日志(将`eventmesh`替换为您指定的容器名称或 ID): + +```shell +sudo docker logs eventmesh +``` + +## 5. 查看 EventMesh 日志 + +成功启动 EventMesh 容器后,您可以通过以下步骤查看 EventMesh Runtime 输出的日志,检查 EventMesh 的运行状态。 + +进入容器(将`eventmesh`替换为您指定的容器名称或 ID): + +```shell +sudo docker exec -it eventmesh /bin/bash +``` + +查看日志: + +```shell +cd logs +tail -n 50 -f eventmesh.out +``` + +当日志输出`server state:RUNNING`,则代表 EventMesh Runtime 启动成功了。 + +## 6. 构建 EventMesh Runtime 镜像(可选) + +EventMesh 基于 JDK8 开发,二进制发行版和容器镜像基于 JDK8 构建。 + +要在 JDK8 环境下运行容器,请在 EventMesh 源代码的项目根目录下执行: + +```shell +sudo docker build -t yourname/eventmesh:yourtag -f docker/Dockerfile_jdk8 . +``` + +如果您希望以 JDK11 作为容器的运行环境,则执行: + +```shell +sudo docker build -t yourname/eventmesh:yourtag -f docker/Dockerfile_jdk11 . +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/05-demo.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/05-demo.md new file mode 100644 index 0000000000..935bf09e29 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/05-demo.md @@ -0,0 +1,247 @@ +# 运行 Java SDK Demo + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +> eventmesh-sdk-java 作为客户端,与 EventMesh Runtime 通信,用于完成消息的发送和接收。 +> +> eventmesh-sdk-java 支持异步消息和广播消息。异步消息表示生产者只发送消息,不关心回复消息。广播消息表示生产者发送一次消息,所有订阅广播主题的消费者都将收到消息。 +> +> eventmesh-sdk-java 支持 HTTP、TCP 和 GRPC 协议。 + +TCP、HTTP 和 GRPC 示例都在`eventmesh-examples`模块下。 + +## 1. TCP + +### 1.1 异步消息 + +- 创建主题 TEST-TOPIC-TCP-ASYNC,可以通过 rocketmq-console 或者 rocketmq tools 命令 + +- 启动消费者,订阅上一步骤已经创建的 Topic + +``` +运行 org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribe 的 main 方法 +``` + +- 启动发送端,发送消息 + +``` +运行 org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublish 的 main 方法 +``` + +### 1.2 广播消息 + +- 创建主题 TEST-TOPIC-TCP-BROADCAST,可以通过 rocketmq-console 或者 rocketmq tools 命令 + +- 启动消费端,订阅上一步骤已经创建的 Topic + +``` +运行 org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribeBroadcast 的 main 方法 +``` + +- 启动发送端,发送广播消息 + +``` +运行 org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublishBroadcast 的 main 方法 +``` + +更多关于 TCP 部分的内容,请参考 [EventMesh TCP](../sdk-java/03-tcp.md) + +## 2. HTTP + +> 对于 HTTP,eventmesh-sdk-java 对异步事件实现了发送与订阅。 +> +> 在 Demo 中,Java 类`EventMeshMessage`的`content`字段表示一个特殊的协议。因此,如果您要使用 eventmesh-sdk-java 的 http-client,则只需设计协议的内容并在同一时间提供消费者的应用程序。 + +### 2.1 异步事件 + +> 生产者将事件发送给下游即可,无需等待响应。 + +- 创建主题 TEST-TOPIC-HTTP-ASYNC,可以通过 rocketmq-console 或者 rocketmq tools 命令 + +- 启动消费端,订阅 Topic + + 异步事件消费端为 SpringBoot Demo,运行 Demo 即可启动服务并完成 Topic 订阅 + +``` +运行 org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication 的 main 方法 +``` + +- 启动发送端,发送消息 + +``` +运行 org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance 的 main 方法 +``` + +更多关于 HTTP 部分的内容,请参考 [EventMesh HTTP](../sdk-java/02-http.md)。 + +## 3. GRPC + +> eventmesh-sdk-java 实现了 gRPC 协议。它能异步或同步地发送事件到 EventMesh Runtime。 +> +> 它可以通过 Webhook 和事件流方式订阅消费事件,同时也支持 CNCF CloudEvents 协议。 + +### 3.1 异步事件发送 和 Webhook 订阅 + +> 生产者可以异步地发送事件到 EventMesh Runtime,不需要等待事件储存到 Event Store。 +> +> 对于 Webhook 消费者,事件会推送到消费者的 HTTP Endpoint URL,即消费者的`subscribeUrl`。此方法和前面的 Http EventMesh client 类似。 + +- 在 rocketmq 创建主题 TEST-TOPIC-GRPC-ASYNC +- 启动 publisher 发送事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.AsyncPublishInstance 的 main 方法 +``` + +- 启动 webhook 消费者 + +``` +运行 org.apache.eventmesh.grpc.sub.app.SpringBootDemoApplication 的 main 方法 +``` + +### 3.2 同步事件发送和事件流订阅 + +> 生产者同步地发送事件到 EventMesh Runtime,同时等待事件储存到 Event Store。 +> +> 对于事件流消费者,事件以流的形式推送到 `ReceiveMsgHook` 客户端。此方法类似于 EventMesh client。 + +- 在 rocketmq 创建主题 TEST-TOPIC-GRPC-RR +- 启动 Request-Reply publisher 发送事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.RequestReplyInstance 的 main 方法 +``` + +- 启动 stream subscriber + +``` +运行 org.apache.eventmesh.grpc.sub.EventmeshAsyncSubscribe 的 main 方法 +``` + +### 3.3 批量事件发布 + +> 异步地批量发布多个事件到 EventMesh Runtime。 + +- 在 rocketmq 创建主题 TEST-TOPIC-GRPC-ASYNC +- 启动 publisher 来批量发布事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.BatchPublishInstance 的 main 方法 +``` + +更多关于 gRPC 部分的内容,请参考 [EventMesh gRPC](../sdk-java/04-grpc.md)。 + +## 4. 使用 Shell 脚本运行 Demo + +请参考 [Event Store](./01-store.md) 和 [EventMesh Runtime](./03-runtime.md) 完成运行环境的部署 + +完成 Store 和 Runtime 的部署后,就可以在 eventmesh-examples 模块下运行我们的 Demo 来体验 EventMesh 了: + +gradle 编译: + +```shell +cd apache-eventmesh-1.9.0-src/eventmesh-examples +gradle clean dist + +cd ./dist/bin +``` + +![demo_1](/images/install/demo_1.png) + +### 4.1 TCP + +#### TCP Sub + +```shell +bash tcp_eventmeshmessage_sub.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_tcp_pub.out +``` + +![demo_2](/images/install/demo_2.png) + +#### TCP Pub + +```shell +bash tcp_pub_eventmeshmessage.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_tcp_sub.out +``` + +![demo_3](/images/install/demo_3.png) + +### 4.2 TCP Broadcast + +#### TCP Sub Broadcast + +```shell +sh tcp_sub_eventmeshmessage_broadcast.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_tcp_sub_broadcast.out +``` + +![demo_4](/images/install/demo_3.png) + +#### TCP Pub Broadcast + +```shell +sh tcp_pub_eventmeshmessage_broadcast.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_tcp_pub_broadcast.out +``` + +![demo_5](/images/install/demo_5.png) + +### 4.3 HTTP + +#### HTTP Sub + +```shell +sh http_sub.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_http_sub.out +``` + +![demo_6](/images/install/demo_6.png) + +#### HTTP Pub + +```shell +sh http_pub_eventmeshmessage.sh +``` + +打开对应 log 文件查看日志: + +``` +cd /root/apache-eventmesh-1.9.0-src/eventmesh-examples/dist/logs +tail -f demo_http_pub.out +``` + +![demo_7](/images/install/demo_7.png) + +你可以在 `/logs` 目录下面看到不同模式的运行日志。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/06-operator.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/06-operator.md new file mode 100644 index 0000000000..8f3ae3593c --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/06-operator.md @@ -0,0 +1,97 @@ +# EventMesh 与 K8S 集成 + +### 1. 依赖 + +``` +docker +golang (version 1.19) +kubernetes (kubectl) +kubernetes 和 docker 之间有一定的兼容性,请检查它们之间的版本兼容性,并下载相应的版本,以确保它们能一起正常工作。 +``` + +### 2. 启动 + +进入 eventmesh-operator 目录。 + +```shell +cd eventmesh-operator +``` + +将 CRD 安装到 k8s 集群。 + +```shell +make install + +# Uninstall CRDs from the K8s cluster +make uninstall +``` + +如果出现错误`eventmesh-operator/bin/controller-gen: No such file or directory`,运行以下命令: + +```shell +# 如有必要,在本地下载 controller-gen. +make controller-gen +# 如有必要,在本地下载 kustomize. +make kustomize +``` + +查看 crds 信息: + +``` shell +# 运行以下命令查看 crds 信息: +kubectl get crds +NAME CREATED AT +connectors.eventmesh-operator.eventmesh 2023-11-28T01:35:21Z +runtimes.eventmesh-operator.eventmesh 2023-11-28T01:35:21Z +``` + +创建和删除 CRs: + +自定义资源对象位于:/config/samples + +删除 CR,只需将`create`替换为`delete`即可。 + +```shell +# 为 eventmesh-runtime、eventmesh-connector-rocketmq 创建 CR, 创建 clusterIP 可让 eventmesh-runtime 与其他组件通信。 +make create + +#success: +configmap/runtime-config created +runtime.eventmesh-operator.eventmesh/eventmesh-runtime created +service/runtime-cluster-service created +configmap/connector-rocketmq-config created +connectors.eventmesh-operator.eventmesh/connector-rocketmq created + +# 查看创建的 service. +kubectl get service +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +runtime-cluster-service ClusterIP 10.109.209.72 10000/TCP 17s + +# Delete CR +make delete +``` + +运行 eventmesh-operator 创建 pods。 + +```shell +# run controller +make run +# log +go fmt ./... +go vet ./... +go run ./main.go +INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":9020"} +INFO setup starting manager +INFO Starting server {"kind": "health probe", "addr": "[::]:8081"} +INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:9020"} +INFO runtime Creating a new eventMeshRuntime StatefulSet. {"StatefulSet.Namespace": "default", "StatefulSet.Name": "eventmesh-runtime-0-a"} +INFO connector Creating a new Connector StatefulSet. {"StatefulSet.Namespace": "default", "StatefulSet.Name": "connector-rocketmq"} +INFO runtime Successful reconciliation! +INFO connector Successful reconciliation! + +# 成功启动 pod 后,运行以下命令查看 pod。 +kubectl get pods +NAME READY STATUS RESTARTS AGE +connector-rocketmq-0 1/1 Running 0 12m +eventmesh-runtime-0-a-0 1/1 Running 0 12m +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/07-faq.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/07-faq.md new file mode 100644 index 0000000000..3c315bb2a5 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/07-faq.md @@ -0,0 +1,41 @@ +# 常见问题 + +## 导入 Eclipse + +我们推荐使用 `Intellij IDEA` 进行开发,如果您希望使用 `Eclipse`,可以参考下面的步骤导入项目。 + +### 前提 + +- 64 位 JDK 1.8+ +- Gradle 7.0+,Eclipse 已安装 Gradle 插件 + +### 下载 + +```shell +git clone https://github.com/apache/eventmesh.git +``` + +### 项目编译环境 + +打开命令行终端,运行 `./gradlew cleanEclipse eclipse`。 + +### 配置修改 + +修改工程名称和 `settings.gradle` 配置文件参数、`rootProject.name` 参数一致 + +### 修改 eclipse.init 配置文件 + +配置 lombok,以 1.18.8 版本为例: + +``` +-javaagent:lombok-1.18.8.jar +-XBootclasspath/a:lombok-1.18.8.jar +``` + +### 202106 版本 Eclipse 配置 + +`eclipse.init` 增加配置参数:`--illegal-access=permit` + +### 导入 + +打开 Eclipse,导入 EventMesh 项目到 IDE 中。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/_category_.json new file mode 100644 index 0000000000..bc305c5ad5 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/instruction/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "安装部署", + "collapsed": false +} + diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/introduction.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/introduction.md new file mode 100644 index 0000000000..11e9b6ae60 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/introduction.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 0 +--- + +# Apache EventMesh + +[![CI status](https://img.shields.io/github/actions/workflow/status/apache/eventmesh/ci.yml?logo=github&style=for-the-badge)](https://github.com/apache/eventmesh/actions/workflows/ci.yml) +[![CodeCov](https://img.shields.io/codecov/c/gh/apache/eventmesh/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/apache/eventmesh) +[![License](https://img.shields.io/github/license/apache/eventmesh?style=for-the-badge)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![GitHub Release](https://img.shields.io/github/v/release/apache/eventmesh?style=for-the-badge)](https://github.com/apache/eventmesh/releases) +[![Slack Status](https://img.shields.io/badge/slack-join_chat-blue.svg?logo=slack&style=for-the-badge)](https://join.slack.com/t/the-asf/shared_invite/zt-1y375qcox-UW1898e4kZE_pqrNsrBM2g) + +**Apache EventMesh** 是一个动态的云原生事件驱动架构基础设施,用于分离应用程序和后端中间件层,它支持广泛的用例,包括复杂的混合云、使用了不同技术栈的分布式架构。 + +## 特性 + +- **通信协议**:EventMesh 可以使用 TCP、HTTP 或 gRPC 与客户端通信。 +- **CloudEvents**: EventMesh 支持 [CloudEvents](https://cloudevents.io) 规范作为事件的格式。CloudEvents 是一种描述事件数据的公共格式的规范,用于在服务、平台和系统之间提供互操作性。 +- **Schema 注册**: EventMesh 实现了 schema 注册,该 schema 注册可以接收并存储来自客户端的模式,并提供其他客户端检索模式的接口。 +- **可观察性**: EventMesh 暴露了一系列 metrics,例如 HTTP 协议的平均延迟和传递消息数。这些 metrics 可以使用 Prometheus 或 OpenTelemetry 收集和分析。 +- **事件工作流程编排**:EventMesh Workflow 可以接收事件,并根据工作流定义和当前工作流状态决定触发哪个命令。工作流定义可以使用 [Serverless Workflow](https://serverlessworkflow.io) DSL 编写。 + +## 组件 + +Apache EventMesh 由多个组件组成,这些组件集成了不同的中间件和消息协议,以增强应用程序运行时的功能。 + +- **eventmesh-runtime**:中间件,在生产者和消费者之间传输事件,支持云原生应用程序和微服务。 +- **eventmesh-sdk-java**:支持 HTTP,TCP 和 [gRPC](https://grpc.io/) 协议的 Java SDK。 +- **eventmesh-connector-plugin**:插件集合,连接中间件,例如 [Apache Kafka](https://kafka.apache.org/),[Apache RocketMQ](https://rocketmq.apache.org/),[Apache Pulsar](https://pulsar.apache.org/) 和 [Redis](https://redis.io/)。 +- **eventmesh-registry-plugin**:插件集合,集成服务注册表,例如 [Nacos](https://nacos.io/) 和 [etcd](https://etcd.io/)。 +- **eventmesh-security-plugin**:插件集合,实现安全机制,例如 ACL(访问控制列表),身份验证和授权。 +- **eventmesh-protocol-plugin**:插件集合,实现消息协议,例如 [CloudEvents](https://cloudevents.io/) 和 [MQTT](https://mqtt.org/)。 +- **eventmesh-admin**:控制面板,管理客户端,主题和订阅。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/roadmap.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/roadmap.md new file mode 100644 index 0000000000..733aeee43e --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/roadmap.md @@ -0,0 +1,92 @@ +--- +sidebar_position: 1 +--- + +# EventMesh 产品路线图 + +下表列出了 EventMesh 的新特性和 Bug 修复情况,详情请参考 [Release Notes](https://eventmesh.apache.org/events/release-notes/v1.10.0/)。 + +## List of Features and Milestones + +| Status | Description | Reference | +|-------------------------------------------|---------------------------------| --- | +| **Implemented in 1.0.0** | Support HTTP | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.0.0** | Support TCP | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.0.0** | Support Pub/Sub Event | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.1.1** | Provide Java SDK | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.1.1** | Support HTTPS | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.2.0** | Support RocketMQ as EventStore | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.2.0** | Support Heartbeat | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.3.0** | Integrate with OpenSchema | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.3.0** | Integrate with OpenTelemetry | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.3.0** | Support CloudEvents | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.4.0** | Support gRPC | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.5.0** | Provide Golang SDK | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.5.0** | Support Nacos Registry | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.5.0** | Support Mesh Bridge | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.5.0** | Support Federal Government | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.6.0 (to be released)** | Integrate with Consul | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.6.0 (to be released)** | Support Webhook | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **Implemented in 1.6.0 (to be released)** | Support etcd | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **In Progress** | Knative Eventing Infrastructure | [GitHub Issue](https://github.com/apache/eventmesh/issues/790), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-463) | +| **In Progress** | Dashboard | [GitHub Issue](https://github.com/apache/eventmesh/issues/700), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-465) | +| **In Progress** | Support Kafka as EventStore | [GitHub Issue](https://github.com/apache/eventmesh/issues/676) | +| **In Progress** | Support Pulsar as EventStore | [GitHub Issue](https://github.com/apache/eventmesh/issues/676) | +| **In Progress** | Support Dledger | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **In Progress** | Workflow | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **In Progress** | Support Redis | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **In Progress** | Support Mesh Bridge | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| **In Progress** | Support Zookeeper | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| Planned | Provide NodeJS SDK | [GitHub Issue](https://github.com/apache/eventmesh/issues/417) | +| Planned | Transaction Event | [GitHub Issue](https://github.com/apache/eventmesh/issues/697) | +| Planned | Event Query Language (EQL) | [GitHub Issue](https://github.com/apache/eventmesh/issues/778) | +| Planned | Metadata consistency persistent | [GitHub Issue](https://github.com/apache/eventmesh/issues/817) | +| Planned | Rust SDK | [GitHub Issue](https://github.com/apache/eventmesh/issues/815) | +| Planned | WebAssembly Runtime | [GitHub Issue](https://github.com/apache/eventmesh/issues/576) | +| Planned | Filter Chain | [GitHub Issue](https://github.com/apache/eventmesh/issues/664) | + +## 连接器实现状态 + +| 服务和中间件 | 源 | 汇 | +|:------------------------------------------:|:------:|:------:| +| [RocketMQ](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-rocketmq) | ✅ | ✅ | +| [Kafka](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-kafka) | ✅ | ✅ | +| [Pulsar](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-pulsar) | ✅ | ✅ | +| [RabbitMQ](./design-document/connect/rabbitmq-connector) | ✅ | ✅ | +| [HTTP](./design-document/connect/http-connector) | ✅ | ⬜ | +| [JDBC](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-jdbc) | ⬜ | ✅ | +| [Spring](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-spring) | ✅ | ✅ | +| [OpenFunction](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-openfunction) | ✅ | ✅ | +| [文件](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-file) | ✅ | ✅ | +| 邮件 | ⬜ | ⬜ | +| [Redis](./design-document/connect/redis-connector) | ✅ | ✅ | +| [S3 存储](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-s3) | ⬜ | ✅ | +| ClickHouse | ⬜ | ⬜ | +| [MongoDB](./design-document/connect/mongodb-connector) | ✅ | ✅ | +| [Prometheus](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-prometheus) | ✅ | ⬜ | +| [Knative](./design-document/connect/knative-connector) | ✅ | ✅ | +| [Pravega](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-pravega) | ✅ | ✅ | +| 更多连接器正在计划中 ... | N/A | N/A | + +| 平台和产品 | 源 | 汇 | +|:------------------------------------------:|:------:|:------:| +| [飞书/Lark](./design-document/connect/lark-connector) | ⬜ | ✅ | +| [钉钉](./design-document/connect/dingtalk-connector) | ⬜ | ✅ | +| [企业微信](./design-document/connect/wecom-connector) | ⬜ | ✅ | +| [微信](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors/eventmesh-connector-wechat) | ⬜ | ✅ | +| GitHub | ⬜ | ⬜ | +| ChatGPT | ⬜ | ⬜ | +| [Slack](./design-document/connect/slack-connector) | ⬜ | ✅ | +| 更多连接器正在计划中 ... | N/A | N/A | + +## 事件存储实现状态 + +| 服务和中间件 | 接入 | Topic 管理 | +|:------------------------------------------:|:------:|:------:| +| RocketMQ | ✅ | ✅ | +| Kafka | ✅ | ✅ | +| Standalone | ✅ | ✅ | +| Pulsar | ✅ | ⬜ | +| RabbitMQ | ✅ | ⬜ | +| Redis | ✅ | ⬜ | +| 支持实现更多事件存储 ... | N/A | N/A | diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/01-intro.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/01-intro.md new file mode 100644 index 0000000000..c50dad549a --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/01-intro.md @@ -0,0 +1,37 @@ +# 安装 SDK + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg?style=for-the-badge)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +EventMesh Java SDK 是在一个 Java 应用中集成 EventMesh 所需的 Java 组件集合。SDK 支持使用 TCP、HTTP 和 gRPC 协议来发送和接收同步消息、异步消息和广播消息。SDK 实现了 EventMesh 消息、CloudEvents 和 OpenMessaging 形式。您可以在 [`eventmesh-example`](https://github.com/apache/eventmesh/tree/master/eventmesh-examples) 模块中查看示例项目。 + + + + +​ 使用 Gradle 安装 EventMesh Java SDK,您需要在模块的 `build.gradle` 文件的依赖块中将 `org.apache.eventmesh:eventmesh-sdk-java` 声明为 `implementation`。 + +```gradle +dependencies { + implementation 'org.apache.eventmesh:eventmesh-sdk-java:1.10.0' +} +``` + + + + +使用 Maven 安装 EventMesh Java SDK,您需要在项目 `pom.xml` 文件的依赖块中声明 `org.apache.eventmesh:eventmesh-sdk-java`。 + +```xml + + + org.apache.eventmesh + eventmesh-sdk-java + 1.10.0 + + +``` + + + \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/02-http.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/02-http.md new file mode 100644 index 0000000000..a42016918d --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/02-http.md @@ -0,0 +1,116 @@ +# HTTP 协议 + +EventMesh Java SDK 实现了 HTTP 异步消息的生产者和消费者。二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh HTTP 客户端的配置信息。其中的 `liteEventMeshAddr`、`userName` 和 `password` 字段需要和 EventMesh Runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +public class HTTP { + public static void main(String[] args) throws Exception { + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("localhost:10105") + .producerGroup("TEST_PRODUCER_GROUP") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())) + .userName("eventmesh") + .password("password") + .build(); + /* ... */ + } +} +``` + +## HTTP 消费者 + +类 `EventMeshHttpConsumer` 实现了 `heartbeat`、`subscribe` 和 `unsubscribe` 方法。`subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的话题和回调的 URL 地址。 + +```java +import org.apache.eventmesh.client.http.consumer.EventMeshHttpConsumer; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import com.google.common.collect.Lists; + +public class HTTP { + final String url = "http://localhost:8080/callback"; + final List topicList = Lists.newArrayList( + new SubscriptionItem("eventmesh-async-topic", SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC) + ); + + public static void main(String[] args) throws Exception { + /* ... */ + eventMeshHttpConsumer = new EventMeshHttpConsumer(eventMeshClientConfig); + eventMeshHttpConsumer.heartBeat(topicList, url); + eventMeshHttpConsumer.subscribe(topicList, url); + /* ... */ + eventMeshHttpConsumer.unsubscribe(topicList, url); + } +} +``` + +EventMesh Runtime 将发送一个包含 [CloudEvents 格式](https://github.com/cloudevents/spec) 信息的 POST 请求到这个回调的 URL 地址。类 [SubController.java](https://github.com/apache/eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java) 实现了 Spring Boot controller,它将接收并解析回调信息。 + +## HTTP 生产者 + +类 `EventMeshHttpProducer` 实现了 `publish` 方法。`publish` 方法接收将被发布的消息和一个可选的 timeout 值。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` +- `io.openmessaging.api.Message` + +```java +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.JsonUtils; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class HTTP { + public static void main(String[] args) throws Exception { + /* ... */ + EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject("eventmesh-async-topic") + .withSource(URI.create("/")) + .withDataContentType("application/cloudevents+json") + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + eventMeshHttpProducer.publish(event); + } +} +``` + +## 使用 Curl 命令 + +本段落介绍通过 Curl 命令体验事件的收发功能。 + +### 事件发送 + +启动 EventMesh Runtime 服务后,可以使用 Curl 命令将事件用 HTTP POST 方法发布到指定的主题,Body 内容必须是 JSON 格式,执行命令示例如下: + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"name": "admin", "pass":"12345678"}' http://127.0.0.1:10105/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC +``` + +### 事件订阅 + +启动 EventMesh Runtime 服务后,可以使用 Curl 命令用 HTTP POST 方法订阅指定的主题列表,Body 内容必须是 JSON 格式,执行命令示例如下: + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"url": "http://127.0.0.1:8088/sub/test", "consumerGroup":"TEST-GROUP", "topic":[{"mode":"CLUSTERING","topic":"TEST-TOPIC-HTTP-ASYNC","type":"ASYNC"}]}' http://127.0.0.1:10105/eventmesh/subscribe/local +``` + +你可以在项目`eventmesh-examples`模块中看到这个例子。 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/03-tcp.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/03-tcp.md new file mode 100644 index 0000000000..4e8f36b971 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/03-tcp.md @@ -0,0 +1,118 @@ +# TCP 协议 + +EventMesh Java SDK 实现了同步、异步和广播 TCP 消息的生产者和消费者。二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh TCP 客户端的配置信息。其中的 `host` 和 `port` 字段需要和 EventMesh Runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class AsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + /* ... */ + } +} +``` + +## TCP 消费者 + +消费者应该实现 `ReceiveMsgHook` 类,其被定义在 [ReceiveMsgHook.java](https://github.com/apache/eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java)。 + +```java +public interface ReceiveMsgHook { + Optional handle(ProtocolMessage msg); +} +``` + +类 `EventMeshTCPClient` 实现了 `subscribe` 方法。该方法接收话题、`SubscriptionMode` 和 `SubscriptionType`。`handle` 方法将会在消费者从订阅的话题中收到消息时被调用。如果 `SubscriptionType` 是 `SYNC`,`handle` 的返回值将被发送回生产者。 + +```java +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class TCPConsumer implements ReceiveMsgHook { + public static TCPConsumer handler = new TCPConsumer(); + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, + CloudEvent.class + ); + client.init(); + + client.subscribe( + "eventmesh-sync-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.SYNC + ); + + client.registerSubBusiHandler(handler); + client.listen(); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.of(message); + } +} +``` + +## TCP 生产者 + +### 异步生产者 + +类 `EventMeshTCPClient` 实现了 `public` 方法。该方法接收将被发布的消息和一个可选的 timeout 值,并返回来自消费者的响应消息。 + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +client.publish(event, 1000); +``` + +### 同步生产者 + +类 `EventMeshTCPClient` 实现了 `rr` 方法。该方法接收将被发布的消息和一个可选的 timeout 值,并返回来自消费者的响应消息。 + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + +Package response = client.rr(event, 1000); +CloudEvent replyEvent = EventFormatProvider + .getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(response.getBody().toString().getBytes(StandardCharsets.UTF_8)); +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/04-grpc.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/04-grpc.md new file mode 100644 index 0000000000..cf0b92029e --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/04-grpc.md @@ -0,0 +1,174 @@ +# gRPC 协议 + +EventMesh Java SDK 实现了 gRPC 同步、异步和广播消息的生产者和消费者。二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh gRPC 客户端的配置信息。其中的 `liteEventMeshAddr`、`userName` 和 `password` 字段需要和 EventMesh Runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr("localhost") + .serverPort(10205) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + /* ... */ + } +} +``` + +## gRPC 消费者 + +### 流消费者 + +EventMesh Runtime 会将来自生产者的信息作为一系列事件流向流消费者发送。消费者应实现 `ReceiveHook` 类,其被定义在 [ReceiveMsgHook.java](https://github.com/apache/eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java)。 + +```java +public interface ReceiveMsgHook { + Optional handle(T msg) throws Throwable; + String getProtocolType(); +} +``` + +类 `EventMeshGrpcConsumer` 实现了 `registerListener`、`subscribe` 和 `unsubscribe` 方法。`subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的话题。`registerListener` 接收一个实现了 `ReceiveMsgHook` 的实例。`handle` 方法将会在消费者收到订阅的主题消息时被调用。如果 `SubscriptionType` 是 `SYNC`,`handle` 的返回值将被发送回生产者。 + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static CloudEventsAsyncSubscribe handler = new CloudEventsAsyncSubscribe(); + public static void main(String[] args) throws InterruptedException { + /* ... */ + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + eventMeshGrpcConsumer.registerListener(handler); + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + } +} +``` + +### Webhook 消费者 + +类 `EventMeshGrpcConsumer` 的 `subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的主题和一个可选的 timeout 值。如果提供了回调 URL,EventMesh Runtime 将向回调 URL 地址发送一个包含 [CloudEvents 格式](https://github.com/cloudevents/spec) 消息的 POST 请求。[SubController.java](https://github.com/apache/eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java) 实现了一个接收并解析回调信息的 Spring Boot controller。 + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; + +@Component +public class SubService implements InitializingBean { + final String url = "http://localhost:8080/callback"; + + public void afterPropertiesSet() throws Exception { + /* ... */ + eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + eventMeshGrpcConsumer.init(); + + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem), url); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem), url); + } +} +``` + +## gRPC 生产者 + +### 异步生产者 + +类 `EventMeshGrpcProducer` 实现了 `publish` 方法。`publish` 方法接收将被发布的消息和一个可选的 timeout 值。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); +eventMeshGrpcProducer.init(); + +Map content = new HashMap<>(); +content.put("content", "testAsyncMessage"); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +eventMeshGrpcProducer.publish(event); +``` + +### 同步生产者 + +类 `EventMeshGrpcProducer` 实现了 `requestReply` 方法。`requestReply` 方法接收将被发布的消息和一个可选的 timeout 值。方法会返回消费者返回的消息。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +### 批量生产者 + +类 `EventMeshGrpcProducer` 重写了 `publish` 方法,该方法接收一个将被发布的消息列表和一个可选的 timeout 值。列表中的消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +List cloudEventList = new ArrayList<>(); +for (int i = 0; i < 5; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + cloudEventList.add(event); +} + +eventMeshGrpcProducer.publish(cloudEventList); +/* ... */ +``` \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/_category_.json new file mode 100644 index 0000000000..9d0a27c562 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/sdk-java/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "EventMesh SDK for Java", + "collapsed": false +} diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/01-upgrade-guide.md b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/01-upgrade-guide.md new file mode 100644 index 0000000000..b8d79ec607 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/01-upgrade-guide.md @@ -0,0 +1,15 @@ +# EventMesh 升级指引 + +> 本文简单介绍 EventMesh 从 1.2.0 版本升级到最新版本的注意事项。 + +## 1. 注意事项 + +**如果您是首次接触并使用 EventMesh,您可以忽略该章节。** + +## 2. 服务升级安装 + +EventMesh 运行时模块的升级和启动可以按照 [部署指南](https://eventmesh.apache.org/docs/instruction/runtime) 完成。 + +版本之间的差异和变化,请参考不同版本的 [Release Notes](https://eventmesh.apache.org/events/release-notes)。可以满足不同版本间的兼容性。 + +如果需要使用最新的功能,按照版本说明升级到相应的版本即可,不同的插件模块组件可以单独打包配置。可以参考相应的 [功能设计文档和指南](https://eventmesh.apache.org/docs/design-document/)。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/_category_.json b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/_category_.json new file mode 100644 index 0000000000..af764643e9 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/version-v1.11.0/upgrade-guide/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 7, + "label": "Upgrade Guide", + "collapsed": false +} diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index 19d04cd726..e21c5b073f 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -3,7 +3,7 @@ import clsx from 'clsx'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './Hero.module.css'; -import ArchitectureImg from '../../static/images/eventmesh-architecture-4.png'; +import ArchitectureImg from '../../static/images/eventmesh-architecture-5.png'; import Translate, {translate} from '@docusaurus/Translate'; const Hero = (): JSX.Element => { diff --git a/static/images/eventmesh-architecture-5.png b/static/images/eventmesh-architecture-5.png new file mode 100644 index 0000000000..40e1750707 Binary files /dev/null and b/static/images/eventmesh-architecture-5.png differ