Skip to content

Commit 8463d2b

Browse files
committed
Feat: Monolake graphs and minor fixes
1 parent d3ac52a commit 8463d2b

22 files changed

+156
-51
lines changed

content/en/docs/monolake/Architecture/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Architecture"
33
linkTitle: "Architecture"
44
weight: 3
55
keywords: ["Proxy", "Rust", "io_uring", "Architecture"]
6-
description: "This doc covers architecture design and features"
6+
description: "Architecture and design deep dive"
77
---
88

99

content/en/docs/monolake/Architecture/context.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
title: "Context Management"
33
linkTitle: "Context"
44
weight: 4
5-
description: "Deep dive into Monolake's io_uring-based runtime and performance characteristics compared to traditional event-based runtimes"
65
---
76

8-
# Context Management with `certain_map`
7+
# `certain_map`
98

109
In a service-oriented architecture, managing the context data that flows between different services is a critical aspect of the system design. The [`certain_map`](https://docs.rs/certain-map/latest/certain_map/) crate provides a powerful way to define and work with typed context data, ensuring the existence of required information at compile-time.
1110

content/en/docs/monolake/Architecture/runtime.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ One of the defining characteristics of Monoio is its thread-per-core architectur
2020
When working with asynchronous I/O in Rust, understanding the underlying mechanisms of different runtimes is crucial. Two prominent approaches are the io-uring-based runtimes(Monolake) and the traditional event notification based runtimes (Tokio, async-std) which use mechanisms like kequeue and epoll. The fundamental difference between these two models lies in how they manage resource ownership and I/O operations.
2121

2222
io_uring operates on a submission-based model, where the ownership of resources (such as buffers) is transferred to the kernel upon submission of an I/O request. This model allows for high performance and reduced context switching, as the kernel can process the requests asynchronously. When an I/O operation is completed, the ownership of the buffers is returned to the caller. This ownership transfer leads to several implications:
23-
1. Ownership Semantics: In io-uring, since the kernel takes ownership of the buffers during the operation, it allows for more efficient memory management. The caller does not need to manage the lifecycle of the buffers while the operation is in progress.
2423

25-
2. Concurrency Model: The submission-based model allows for a more straightforward handling of concurrency, as multiple I/O operations can be submitted without waiting for each to complete. This can lead to improved throughput, especially in I/O-bound applications.
24+
1. **Ownership Semantics**: In io-uring, since the kernel takes ownership of the buffers during the operation, it allows for more efficient memory management. The caller does not need to manage the lifecycle of the buffers while the operation is in progress.
25+
26+
2. **Concurrency Model**: The submission-based model allows for a more straightforward handling of concurrency, as multiple I/O operations can be submitted without waiting for each to complete. This can lead to improved throughput, especially in I/O-bound applications.
2627

2728
In contrast, Tokio employs systems like kequeue and epoll. In this model, the application maintains ownership of the buffers throughout the lifetime of the I/O operation. Instead of transferring ownership, Tokio merely borrows the buffers, which has several implications:
2829

29-
1. Buffer Management: Since Tokio borrows buffers, the application is responsible for managing their lifecycle. This can introduce complexity, especially when dealing with concurrent I/O operations, as developers must ensure that buffers are not inadvertently reused while still in use.
30+
1. **Buffer Management**: Since Tokio borrows buffers, the application is responsible for managing their lifecycle. This can introduce complexity, especially when dealing with concurrent I/O operations, as developers must ensure that buffers are not inadvertently reused while still in use.
3031

31-
2. Polling Mechanism: The polling model in Tokio requires the application to actively wait for events, which can result in increased context switches and potentially less efficient use of system resources compared to the submission-based model of io-uring.
32+
2. **Polling Mechanism**: The polling model in Tokio requires the application to actively wait for events, which can result in increased context switches and potentially less efficient use of system resources compared to the submission-based model of io-uring.
3233

3334
## Async IO Trait divergence
3435

content/en/docs/monolake/Architecture/service.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ description: "Overview of Monolake's service architecture, factory patterns, and
77

88
## Services
99

10-
{{< figure src="/img/docs/monolake_service.jpeg" width="1000" height="600" caption="Service Architecture" >}}
10+
<style>
11+
.figure-caption {
12+
text-align: center;
13+
}
14+
</style>
15+
16+
{{< figure src="/img/docs/monolake_service.jpeg" width="1000" height="600" caption="Service Architecture" class="figure-caption" >}}
1117

1218
The Service pattern is a fundamental abstraction in network programming, popularized by the Tower library in the Rust ecosystem. At its core, a Service represents an asynchronous function that processes requests and returns responses. This pattern is particularly powerful for building networking applications as it enables:
1319

content/en/docs/monolake/Config Guide/_index.md

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
title: "Config Guide"
33
linkTitle: "Config Guide"
44
weight: 5
5-
date: 2023-07-3
65
description: "Comphrensive guide to configuring monolake proxy"
76
---
87

content/en/docs/monolake/FAQ/_index.md

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
title: "FAQ"
33
linkTitle: "FAQ"
4-
date: 2023-07-03
54
weight: 7
65
keywords: ["Monolake", "HTTP", "Proxy", "Q&A"]
76
description: "Monolake Frequently Asked Questions and Answers."

content/en/docs/monolake/Getting Started/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description: "This page provides a quick start guide for setting up and running
88

99
## Prerequisites
1010

11-
- **Linux Kernel Support**: IO-uring requires a Linux kernel version that has io_uring support. Generally, kernel versions 5.1 and above provide the necessary support. Ensure that your target system has an appropriate kernel version installed. Monolake will fall back to epoll on Mac OS.
11+
- **Linux Kernel Support**: io_uring requires linux kernel support. Generally, kernel versions 5.1 and above provide the necessary support. Ensure that your target system has an appropriate kernel version installed. Monolake will fall back to epoll on Mac OS.
1212
- **Rust nightly**: See the "Rust installation section" below
1313

1414
## Quick Start

content/en/docs/monolake/Overview/_index.md

+19-30
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ title: "Overview"
33
linkTitle: "Overview"
44
weight: 1
55
keywords: ["Proxy", "Rust", "io-uring"]
6-
description: "This doc provides an overview of Monolake, a high-performance network service framework."
76
---
87

98
## Monolake
@@ -27,25 +26,19 @@ By focusing on cutting-edge Rust and io_uring, Monolake aims to provide develope
2726

2827
## Performance
2928

30-
HAR TODO: Move performance section from benchmarks to here
31-
32-
### Test environment
29+
#### Request Per Second (RPS) vs. Body Size
30+
| RPS | TP99 |
31+
| :------------------------------------------------- | :-------------------------------------------------: |
32+
| ![image](/img/docs/https_req_per_sec_vs_body_size.png) | ![image](/img/docs/https_tp99_latency_vs_body_size.png) |
33+
| |
34+
| ![image](/img/docs/http_req_per_sec_vs_body_size.png) | ![image](/img/docs/http_tp99_latency_vs_body_size.png) |
3335

3436
### Concurrency performance
35-
36-
HAR TODO: Update with latest benchmarks
37-
38-
| QPS | TP99 | TP999 |
39-
| :------------------------------------------------- | :-------------------------------------------------: | :--------------------------------------------------: |
40-
| ![image](/img/docs/performance_concurrent_qps.png) | ![image](/img/docs/performance_concurrent_tp99.png) | ![image](/img/docs/performance_concurrent_tp999.png) |
41-
42-
### Throughput performance
43-
44-
Change packet size with a fixed concurrency of 100.
45-
46-
| QPS | TP99 | TP999 |
47-
| :----------------------------------------------- | :-----------------------------------------------: | :------------------------------------------------: |
48-
| ![image](/img/docs/performance_bodysize_qps.png) | ![image](/img/docs/performance_bodysize_tp99.png) | ![image](/img/docs/performance_bodysize_tp999.png) |
37+
| RPS | TP99 |
38+
| :------------------------------------------------- | :-------------------------------------------------: |
39+
| ![image](/img/docs/https_req_per_sec_vs_worker_threads.png) | ![image](/img/docs/https_tp99_latency_vs_worker_threads.png) |
40+
| |
41+
| ![image](/img/docs/http_req_per_sec_vs_worker_threads.png) | ![image](/img/docs/http_tp99_latency_vs_worker_threads.png) |
4942

5043
## Related Projects
5144

@@ -57,15 +50,11 @@ Change packet size with a fixed concurrency of 100.
5750

5851
| Crate | Description |
5952
|-------|-------------|
60-
| [monoio-transports](https://github.com/monoio-rs/monoio-transports) | A foundational crate that provides high-performance, modular networking capabilities, including connectors and utilities for efficient network communications |
61-
| [service-async](https://github.com/ihciah/service-async) | A foundational crate that introduces a refined Service trait with efficient borrowing and zero-cost abstractions, as well as utilities for service composition and state management |
62-
| [certain-map](https://github.com/ihciah/certain-map) | A foundational crate that provides a typed map data structure, ensuring the existence of specific items at compile-time, useful for managing data dependencies between services |
63-
| [monoio-thrift](https://github.com/monoio-rs/monoio-thrift) | Monoio native, io_uring compatible thrift implementation |
64-
| [monoio-http](https://github.com/monoio-rs/monoio-http) | Monoio native, io_uring compatible HTTP/1.1 and HTTP/2 implementation |
65-
| [monoio-nativetls](https://github.com/monoio-rs/monoio-tls) | The native-tls implementation compatible with monoio |
66-
| [monoio-rustls](https://github.com/monoio-rs/monoio-tls) | The rustls implementation compatible with monoio |
67-
68-
## Blogs
69-
70-
- [Monolake: How ByteDance Developed Its Own Rust Proxy to Save Hundreds of Thousands of CPU Cores](TODO)
71-
- [Monolake open source summit](TODO)
53+
| [monoio-transports](https://crates.io/crates/monoio-transports) | A foundational crate that provides high-performance, modular networking capabilities, including connectors and utilities for efficient network communications |
54+
| [service-async](https://crates.io/crates/service-async) | A foundational crate that introduces a refined Service trait with efficient borrowing and zero-cost abstractions, as well as utilities for service composition and state management |
55+
| [certain-map](https://crates.io/crates/certain-map) | A foundational crate that provides a typed map data structure, ensuring the existence of specific items at compile-time, useful for managing data dependencies between services |
56+
| [monoio-thrift](https://crates.io/crates/monoio-thrift) | Monoio native, io_uring compatible thrift implementation |
57+
| [monoio-http](https://crates.io/crates/monoio-http) | Monoio native, io_uring compatible HTTP/1.1 and HTTP/2 implementation |
58+
| [monoio-nativetls](https://crates.io/crates/monoio-native-tls) | The native-tls implementation compatible with monoio |
59+
| [monoio-rustls](https://crates.io/crates/monoio-rustls) | The rustls implementation compatible with monoio |
60+

content/en/docs/monolake/Tutorial/_index.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ title: "Tutorial"
33
linkTitle: "Tutorial"
44
weight: 4
55
keywords: ["Proxy", "Rust", "io_uring", "Architecture"]
6-
description: "This is a developer guide"
76
---
87

9-
In this guide, we'll walk through the process of implementing a HTTP routing service using the [monolake-services](TODO) crate. This service will handle incoming HTTP requests and route them to appropriate upstream servers based on the configured routes and their associated endpoints.
8+
In this guide, we'll walk through the process of implementing an HTTP routing service using the `monolake-services` crate. This service will handle incoming HTTP requests and route them to appropriate upstream servers based on the configured routes and their associated endpoints.

content/en/docs/monolake/Tutorial/code.md

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
title: "Putting it all together"
33
linkTitle: "Putting it all together"
44
weight: 3
5-
description: "This doc covers how to manage configuration and context"
65
---
76

87
## Putting it all together

content/en/docs/monolake/Tutorial/config.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: "This doc covers how to manage configuration and context"
99

1010
When building a service-oriented application using the `monolake-services` crate, you'll need to define the necessary configuration fields in your main `ServerConfig` struct. These fields will be used by the service factories to construct the services that make up your application.
1111

12-
The specific fields you'll need to add will depend on the services you're using. For example, if you're implementing a routing HTTP service, you'll need to add a routes field to hold the routing configuration.
12+
The specific fields you'll need to add will depend on the services you're using. For example, if you're implementing a routing HTTP service, you'll probably want to add a routes field to hold the routing configuration.
1313

1414
To configure the routing service, you'll need to add the routes field to your `ServerConfig` struct. This field will hold the RouteConfig structures that define the routing rules.
1515
```rust
@@ -51,9 +51,7 @@ certain_map::certain_map! {
5151
}
5252
```
5353

54-
In this example, the Context struct has a single field: peer_addr of type PeerAddr. The #[empty(EmptyContext)] and #[full(FullContext)] attributes define the type aliases for the empty and full versions of the context, respectively.
55-
56-
It's important to note that the fields in the Context struct should correspond to the data that the `RoutingHandler` service expects to be available. In this case, the RoutingHandler requires the peer_addr information to be set in the context.
54+
In this example, the Context struct has a single field: peer_addr of type `PeerAddr`. It's important to note that the fields in the Context struct should correspond to the data that the `RoutingHandler` service expects to be available. In this case, the RoutingHandler requires the peer_addr information to be set in the context.
5755

5856
By defining the Context using the certain_map crate, you can ensure that the necessary data is available at compile-time, preventing runtime errors and simplifying the implementation of your services.
5957

content/en/docs/monolake/Tutorial/service.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ linkTitle: "Creating Service and Factory"
44
weight: 2
55
---
66

7-
## Prerequisites
8-
For a better
97
## Defining the Service and Factory
108
The `RoutingHandlerFactory` is responsible for creating and updating the `RoutingHandler` service instances. This factory implements the AsyncMakeService trait, allowing it to be used in a FactoryStack for service composition.
119

@@ -57,7 +55,7 @@ In this implementation, the RoutingHandlerFactory takes two parameters:
5755

5856
The AsyncMakeService implementation for the RoutingHandlerFactory defines how to create a new RoutingHandler instance. It first creates a Router from the configured RouteConfig instances, and then creates the RoutingHandler by calling the make_via_ref method in the inner service factory.
5957

60-
Note that in this case, we don't rely on any state from the previous RoutingHandler instance, as the routing configuration is fully defined by the RouteConfig instances. If the inner service factory had some stateful resources (like a connection pool) that needed to be preserved, we could clone those resources when creating the new RoutingHandler.
58+
Note that in this case, we don't rely on any state from the previous RoutingHandler instance, as the routing configuration is fully defined by the RouteConfig instances. If the inner service factory had some stateful resources (like a connection pool) that needed to be preserved, we could clone those resources when creating the new RoutingHandler. For a more detailed example involving resource transfer, see [UpstreamHandler](https://github.com/cloudwego/monolake/blob/fd2cbe1a8708c379d6355b3cc979540ec49fdb4f/monolake-services/src/http/handlers/upstream.rs#L338), which involves transfer of a HTTP connection pool from the previous UpstreamHandler instance.
6159

6260
To integrate the `RoutingHandler` into a service stack, we can use the layer function provided by the `RoutingHandler` type:
6361

content/en/docs/monolake/_index.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
title: 'Monolake'
33
linkTitle: 'Monolake'
44
weight: 7
5+
Description: "Monolake is a framework for developing high-performance networks services like proxies and gateways in Rust."
56
menu:
67
main:
78
weight: 6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: "Getting Started"
3+
linkTitle: "Getting Started"
4+
weight: 2
5+
keywords: ["Monolake", "Rust", "Proxy", "Getting Started"]
6+
description: "This page provides a quick start guide for setting up and running Monolake"
7+
---
8+
9+
## Prerequisites
10+
11+
- **Linux Kernel Support**: IO-uring requires a Linux kernel version that includes IO-uring support. Generally, kernel versions 5.1 and above provide the necessary support. Ensure that your target system has an appropriate kernel version installed. Monolake will fall back to epoll on Mac OS.
12+
- **Rust nightly**: See the "Rust installation section" below
13+
14+
## Quick Start
15+
16+
This chapter will get you started with Monolake using a simple example config
17+
18+
### Rust installation
19+
20+
To download and install Rust, and set `rustup` to nightly, you can follow these instructions:
21+
22+
1. Download and install Rust by running the following command in your terminal:
23+
24+
```markup
25+
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
26+
```
27+
28+
This command will download the Rust installation script and initiate the installation process.
29+
30+
3. Close the terminal and open a new terminal window to ensure the changes take effect.
31+
32+
4. Set `rustup` to nightly by running the following command:
33+
34+
```markup
35+
$ rustup default nightly
36+
```
37+
38+
This command sets the default Rust toolchain to the nightly version.
39+
40+
5. Verify the installation and check the Rust version by running:
41+
42+
```markup
43+
$ rustc --version
44+
```
45+
46+
This command will display the installed Rust version, which should now be set to nightly.
47+
48+
### Setup an HTTP upstream server
49+
50+
1. **Install Nginx**: Install Nginx using the package manager of your Linux distribution.
51+
52+
2. **Start Nginx**: Start Nginx using the following command:
53+
54+
```shell
55+
sudo service nginx start
56+
```
57+
58+
3. **Configure Port**: Open the Nginx configuration file using a text editor:
59+
60+
```shell
61+
sudo nano /etc/nginx/nginx.conf
62+
```
63+
64+
Inside the file, locate the `http` block and add or modify the `listen` directive to use port 9080:
65+
66+
```nginx
67+
http {
68+
...
69+
server {
70+
listen 9080;
71+
...
72+
}
73+
...
74+
}
75+
```
76+
77+
Save the changes and exit the text editor.
78+
79+
4. **Restart Nginx**: Restart Nginx for the changes to take effect:
80+
81+
```shell
82+
sudo service nginx restart
83+
```
84+
85+
### Build Monolake
86+
87+
1. Clone the monolake repository `git clone https://github.com/cloudwego/monolake.git`.
88+
2. Build the binary:
89+
90+
```markup
91+
$ cargo build --release
92+
```
93+
3. Generate the certificates
94+
```markup
95+
$ sh examples/gen_cert.sh
96+
```
97+
### Run the example
98+
1. Make sure your endpoints are up and certificates are generated
99+
2. Start the proxy
100+
101+
```markup
102+
$ ./target/release/monolake -c examples/config.toml
103+
```
104+
3. Send a request to the socket based listener on server_basic.
105+
106+
```markup
107+
$ curl -vvv http://127.0.0.1:9081/
108+
```
109+
4. Send a request to the server_tls.
110+
111+
```markup
112+
$ curl --resolve gateway.monolake.rs:8081:127.0.0.1 --cacert examples/certs/rootCA.crt -vvv https://gateway.monolake.rs:8081/
113+
```
114+
115+
### Detail configuration
116+
117+
Please check [Configuration](_config.md) for more details.
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)