๐_๊ถ๊ทน์_Web_Framework_์๋_๋๊ฒฐ
Source: Dev.to
๋ฒ์ญํ๋ ค๋ ์ ์ฒด ํ ์คํธ๋ฅผ ์ ๊ณตํด ์ฃผ์๋ฉด, ์์ฒญํ์ ๋๋ก ๋งํฌ๋ค์ด ํ์๊ณผ ์ฝ๋ ๋ธ๋ก, URL์ ๊ทธ๋๋ก ์ ์งํ๋ฉด์ ํ๊ตญ์ด๋ก ๋ฒ์ญํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
10๋ ๊ฒฝ๋ ฅ์ ํ์คํ ์์ง๋์ด๋ก์
์๋ง์ ์น ํ๋ ์์ํฌ์ ํฅ๋ง์ฑ์ ๋ฅผ ๋ชฉ๊ฒฉํ์ต๋๋คโ์ด๊ธฐ jQuery ์๋๋ถํฐ ์ค๋๋ ์ ๊ณ ์ฑ๋ฅ Rust ํ๋ ์์ํฌ๊น์ง. ์๋๋ ์ ๋ฅผ ์ถฉ๊ฒฉ์ ๋น ๋จ๋ฆฌ๊ณ ์น ํ๋ ์์ํฌ ์ฑ๋ฅ์ ๋ํ ์ดํด๋ฅผ ์์ ํ ๋ฐ๊ฟ๋์ ์ฑ๋ฅ ๋น๊ต ํ ์คํธ์ ๋๋ค.
๐ก ํ ์คํธ ๋ฐฐ๊ฒฝ
2024๋ ํ์ฌ, ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ์ฑ๋ฅ ์๊ตฌ์ฌํญ์ ๊ทธ ์ด๋ ๋๋ณด๋ค ๋์ต๋๋ค. ์ฌ์ฉ์๋ ๋ฐ๋ฆฌ์ด ์์ค์ ์๋ต ์๊ฐ์ ์ ์์๊ฑฐ๋ ์ฌ์ดํธ, ์์ ํ๋ซํผ, ์ํฐํ๋ผ์ด์ฆ ์ฑ์์ ๊ธฐ๋ํฉ๋๋ค. ์ ๋ ์ฃผ์ ์น ํ๋ ์์ํฌ(Tokio, Rocket, Gin, Go์ Rust ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ, Node.js ๋ฑ)๋ฅผ ๋์์ผ๋ก ํ ๋ฌ ๋์ ํฌ๊ด์ ์ธ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ์ํํ์ต๋๋ค.
ํ ์คํธ ํ๊ฒฝ
| ๊ตฌ์ฑ ์์ | ์ฌ์ |
|---|---|
| ์๋ฒ | Intel XeonโฏE5โ2686โฏv4 @โฏ2.30โฏGHz |
| ๋ฉ๋ชจ๋ฆฌ | 32โฏGB DDR4 |
| ๋คํธ์ํฌ | ๊ธฐ๊ฐ๋นํธ ์ด๋๋ท |
| OS | Ubuntuโฏ20.04โฏLTS |
๐ ์ ์ฒด ์ฑ๋ฅ ๋น๊ต ๋ฐ์ดํฐ
๐ KeepโAlive ํ์ฑํ ํ ์คํธ ๊ฒฐ๊ณผ
wrk ์คํธ๋ ์ค ํ ์คํธ โ ๋์ ์ฐ๊ฒฐ 360๊ฐ, ์ง์ ์๊ฐ 60โฏ์ด
| ํ๋ ์์ํฌ | QPS | ๋ ์ดํด์ | ์ ์ก ์๋ | ์์ |
|---|---|---|---|---|
| Tokio | 340,130.92 | 1.22โฏms | 30.17โฏMB/s | ๐ฅ |
| Hyperlane | 334,888.27 | 3.10โฏms | 33.21โฏMB/s | ๐ฅ |
| Rocket | 298,945.31 | 1.42โฏms | 68.14โฏMB/s | ๐ฅ |
| Rust std lib | 291,218.96 | 1.64โฏms | 25.83โฏMB/s | 4๏ธโฃ |
| Gin | 242,570.16 | 1.67โฏms | 33.54โฏMB/s | 5๏ธโฃ |
| Go std lib | 234,178.93 | 1.58โฏms | 32.38โฏMB/s | 6๏ธโฃ |
| Node std lib | 139,412.13 | 2.58โฏms | 19.81โฏMB/s | 7๏ธโฃ |
ab ์คํธ๋ ์ค ํ ์คํธ โ ๋์ ์ฐ๊ฒฐ 1โฏ000๊ฐ, 1โฏM ์์ฒญ
| ํ๋ ์์ํฌ | QPS | ๋ ์ดํด์ | ์ ์ก ์๋ | ์์ |
|---|---|---|---|---|
| Hyperlane | 316,211.63 | 3.162โฏms | 32,115.24โฏKB/s | ๐ฅ |
| Tokio | 308,596.26 | 3.240โฏms | 28,026.81โฏKB/s | ๐ฅ |
| Rocket | 267,931.52 | 3.732โฏms | 70,907.66โฏKB/s | ๐ฅ |
| Rust std lib | 260,514.56 | 3.839โฏms | 23,660.01โฏKB/s | 4๏ธโฃ |
| Go std lib | 226,550.34 | 4.414โฏms | 34,071.05โฏKB/s | 5๏ธโฃ |
| Gin | 224,296.16 | 4.458โฏms | 31,760.69โฏKB/s | 6๏ธโฃ |
| Node std lib | 85,357.18 | 11.715โฏms | 4,961.70โฏKB/s | 7๏ธโฃ |
๐ KeepโAlive ๋นํ์ฑํ ํ ์คํธ ๊ฒฐ๊ณผ
wrk ์คํธ๋ ์ค ํ ์คํธ โ ๋์ ์ฐ๊ฒฐ 360๊ฐ, ์ง์ ์๊ฐ 60โฏ์ด
| ํ๋ ์์ํฌ | QPS | ๋ ์ดํด์ | ์ ์ก ์๋ | ์์ |
|---|---|---|---|---|
| Hyperlane | 51,031.27 | 3.51โฏms | 4.96โฏMB/s | ๐ฅ |
| Tokio | 49,555.87 | 3.64โฏms | 4.16โฏMB/s | ๐ฅ |
| Rocket | 49,345.76 | 3.70โฏms | 12.14โฏMB/s | ๐ฅ |
| Gin | 40,149.75 | 4.69โฏms | 5.36โฏMB/s | 4๏ธโฃ |
| Go std lib | 38,364.06 | 4.96โฏms | 5.12โฏMB/s | 5๏ธโฃ |
| Rust std lib | 30,142.55 | 13.39โฏms | 2.53โฏMB/s | 6๏ธโฃ |
| Node std lib | 28,286.96 | 4.76โฏms | 3.88โฏMB/s | 7๏ธโฃ |
ab ์คํธ๋ ์ค ํ ์คํธ โ ๋์ ์ฐ๊ฒฐ 1โฏ000๊ฐ, 1โฏM ์์ฒญ
| ํ๋ ์์ํฌ | QPS | ๋ ์ดํด์ | ์ ์ก ์๋ | ์์ |
|---|---|---|---|---|
| Tokio | 51,825.13 | 19.296โฏms | 4,453.72โฏKB/s | ๐ฅ |
| Hyperlane | 51,554.47 | 19.397โฏms | 5,387.04โฏKB/s | ๐ฅ |
| Rocket | 49,621.02 | 20.153โฏms | 11,969.13โฏKB/s | ๐ฅ |
| Go std lib | 47,915.20 | 20.870โฏms | 6,972.04โฏKB/s | 4๏ธโฃ |
| Gin | 47,081.05 | 21.240โฏms | 6,436.86โฏKB/s | 5๏ธโฃ |
| Node std lib | 44,763.11 | 22.340โฏms | 4,983.39โฏKB/s | 6๏ธโฃ |
| Rust std lib | 31,511.00 | 31.735โฏms | 2,707.98โฏKB/s | 7๏ธโฃ |
๊น์ด ์๋ ์ฑ๋ฅ ๋ถ์
๐ KeepโAlive ํ์ฑํ
- Tokio๊ฐ 340,130.92โฏQPS๋ก ์ ๋์ ์์ง๋ง, Hyperlane์ด ๊ทผ์ํ๊ฒ ๋ค๋ฐ๋ฆ ๋๋ค (334,888.27โฏQPS, 1.5โฏ% ์ ๋ ๋๋ฆผ).
- ์ ์ก ์๋: Hyperlane์ด Tokio๋ณด๋ค ์ฐ์ํฉ๋๋ค (33.21โฏMB/s vs. 30.17โฏMB/s), ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํจ์จ์ด ๋ ๋ฐ์ด๋จ์ ์์ฌํฉ๋๋ค.
- ab ํ ์คํธ์์ Hyperlane์ด ๋ค์ ์์๊ฐ๋๋ค (316,211.63โฏQPS vs. 308,596.26โฏQPS), ์ง์ ๋ถํ ํ์์ ์ง์ ํ ์ฑ๋ฅ ์์ผ๋ก ๋ถ์ํฉ๋๋ค.
๐ KeepโAlive ๋นํ์ฑํ
- ์งง์ ์๋ช ์ ์ฐ๊ฒฐ์์๋ Hyperlane์ด wrk ํ ์คํธ์์ ๋ค์ 1์๋ฅผ ์ฐจ์งํฉ๋๋ค (51,031.27โฏQPS), Tokio๋ฅผ ์ด์ง ์์ญ๋๋ค.
- ab ํ ์คํธ์์๋ Tokio๊ฐ ๋ค์ 1์๋ฅผ ์ฐจ์งํ์ง๋ง, Hyperlane๊ณผ์ ์ฐจ์ด (โโฏ270โฏQPS)๋ ๋ฌด์ํ ์์ค์ด๋ฉฐ, ์ค์ง์ ์ผ๋ก ํ ์คํธ ๋ณ๋ ๋ฒ์ ๋ด์ ์์ต๋๋ค.
์ฝ๋ ๊ตฌํ ๋น๊ต
๐ข Node.js ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ
// node.js โ standard library HTTP server
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello');
});
server.listen(60000, '127.0.0.1');
๊ฐ๊ฒฐํ์ง๋ง, ์ด๋ฒคํธ ๋ฃจํ ๋ชจ๋ธ์ ๋๊ท๋ชจ ๋์์ฑ์์ ์ฝ๋ฐฑ ์ง์ฅ๊ณผ ๋ฉ๋ชจ๋ฆฌ ๋์ ์ํ์ ์ด๋ํฉ๋๋ค. ํ ์คํธ์์ Node.js ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋์ ๋ถํ์์ 811,908๊ฐ์ ์คํจ ์์ฒญ์ ๋ฐ์์์ผฐ์ต๋๋ค.
๐น Go ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ
// go โ standard library HTTP server
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":60000", nil)
}
Go์ ๊ณ ๋ฃจํด ์ค์ผ์ค๋ฌ๋ ๋ ๋์ ๋์์ฑ์ ์ ๊ณตํ์ง๋ง, ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ GC ์ค๋ฒํค๋ ๋๋ฌธ์ ์์ง ๊ฐ์ ์ฌ์ง๊ฐ ์์ต๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ 234,178.93โฏQPS๋ฅผ ๋ฌ์ฑํ์ผ๋ฉฐ, ์ต์์ Rust ๊ธฐ๋ฐ ํ๋ ์์ํฌ์ ๋นํด ํฌ๊ฒ ๋ค์ฒ์ง๋๋ค.
๐ Rust ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ
(๊ตฌํ์ ๊ฐ๊ฒฐํจ์ ์ํด ์๋ต๋์์ต๋๋ค; Rust ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ด๋ถ์์ hyper ๋๋ tokio๋ฅผ ์ฌ์ฉํ๋ฉฐ, ํ
์คํธ๋ ์ธ์ด ์ค ๊ฐ์ฅ ๋์ ์์ ์ฒ๋ฆฌ๋์ ์ ๊ณตํฉ๋๋ค.)
์ฃผ์ ๋ด์ฉ
- Hyperlane์ ์ ์ก ์๋ ํจ์จ์ฑ ๋ฉด์์ ์ ์๋ ค์ง Tokio์ Rocket ํ๋ ์์ํฌ์ ์ง์์ ์ผ๋ก ๋์ ํ๊ฑฐ๋ ์ด๋ฅผ ๋ฅ๊ฐํฉ๋๋ค.
- KeepโAlive๋ ์์์ ํฐ ์ํฅ์ ๋ฏธ์นฉ๋๋ค; ์ฐ๊ฒฐ ์ฌ์ฌ์ฉ์ ์ต์ ํํ ํ๋ ์์ํฌ(Tokio, Hyperlane)๋ ์ด๋ฅผ ํ์ฑํํ์ ๋ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค.
- ์ธ์ด ๋ฐํ์๋ ์ค์ํฉ๋๋ค: Node.js๋ Go์ Rust์ ๋นํด ํฌ๊ฒ ๋ค์ฒ์ง๋ฉฐ, Rust ๊ธฐ๋ฐ ์๋ฃจ์ ์ด ์์ QPS์์ ์ฐ์๋ฅผ ์ ํฉ๋๋ค.
์ด ๊ฒฐ๊ณผ๋ ์์ ์ฑ๋ฅ์ด ์ต์ฐ์ ๋ชฉํ์ผ ๋ Hyperlane(๋๋ ์ ์ฌํ๊ฒ ์ค๊ณ๋ Rust ํ๋ ์์ํฌ)์ด ์ฒซ ๋ฒ์งธ ์ ํ์ด์ด์ผ ํจ์ ์์ฌํฉ๋๋ค.
... allowed closely by **Tokio**. For teams already invested in Go, the standard library still offers respectable performance, but a move to Rust could unlock a **~30โฏ%** QPS boost.
Source:
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ตฌํ
Rust์ ๊ตฌํ์ ์์คํ ์์ค ์ฑ๋ฅ ์ต์ ํ์ ๊ฐ๋ฅ์ฑ์ ๋ณด์ฌ์ค๋๋ค:
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
fn handle_client(mut stream: TcpStream) {
let response = "HTTP/1.1 200 OK\r\n\r\nHello";
stream.write_all(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:60000").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_client(stream);
}
}
Rust์ ์์ ๊ถ ์์คํ ๊ณผ ์ ๋กโ์ฝ์คํธ ์ถ์ํ๋ ๋ฐ์ด๋ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ํ ์คํธ ๊ฒฐ๊ณผ์ ๋ฐ๋ฅด๋ฉด Rust ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ 291,218.96โฏQPS๋ฅผ ๋ฌ์ฑํ์ผ๋ฉฐ, ์ด๋ ์ด๋ฏธ ๋งค์ฐ ์ธ์์ ์ ๋๋ค. ๊ทธ๋ฌ๋ ํนํ ์ฐ๊ฒฐ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๊ณ ๋์์ฑ ์๋๋ฆฌ์ค์์๋ ์์ง ์ต์ ํ ์ฌ์ง๊ฐ ์์ต๋๋ค.
Source:
PerformanceโOptimization Strategy Analysis
๐ง ConnectionโManagement Optimization
๋น๊ต ํ ์คํธ๋ฅผ ํตํด ํต์ฌ ์ต์ ํ ํฌ์ธํธ๊ฐ ์ฐ๊ฒฐ ๊ด๋ฆฌ์์ด ๋ฐํ์ก์ต๋๋ค. Hyperlane ํ๋ ์์ํฌ๋ ์ฐ๊ฒฐ ์ฌ์ฌ์ฉ์ ๋ฐ์ด๋๋ฉฐ, ์ด๋ KeepโAlive ํ ์คํธ์์ ๋์ ์ฑ๋ฅ์ ๋ณด์ด๋ ์ด์ ์ ๋๋ค.
- ๊ธฐ์กด ์น ํ๋ ์์ํฌ๋ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ ๋ ๋ง์ ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด GC ์๋ ฅ์ ์ฆ๊ฐ์ํต๋๋ค.
- Hyperlane์ ๊ฐ์ฒด ํ ๊ธฐ์ ์ ๋์ ํด ๋ฉ๋ชจ๋ฆฌ ํ ๋น ์ค๋ฒํค๋๋ฅผ ํฌ๊ฒ ์ค์ ๋๋ค.
๐ MemoryโManagement Optimization
๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ ์ญ์ ์ค์ํ ์์์ ๋๋ค. Rust์ ์์ ๊ถ ๋ชจ๋ธ์ด ์ด๋ฏธ ๋ฐ์ด๋ ์ฑ๋ฅ์ ์ ๊ณตํ์ง๋ง, ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๋ณต์กํ ์๋ช (lifetime) ๋ฌธ์ ๊ฐ ์์ฃผ ๋ฐ์ํฉ๋๋ค.
- Hyperlane์ Rust์ ์์ ๊ถ ๋ชจ๋ธ์ ๋ง์ถคํ ๋ฉ๋ชจ๋ฆฌ ํ์ ๊ฒฐํฉํด ์ ๋กโ์นดํผ ๋ฐ์ดํฐ ์ ์ก์ ๊ตฌํํฉ๋๋ค.
- ์ด ๋ฐฉ์์ ํนํ ๋์ฉ๋ ํ์ผ ์ ์ก์ ํจ๊ณผ์ ์ ๋๋ค.
โก AsynchronousโProcessing Optimization
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ํ๋ ์น ํ๋ ์์ํฌ์ ํต์ฌ ๊ธฐ๋ฅ์ ๋๋ค. Tokio๋ ์ฑ๋ฅ์ด ์ฐ์ํ์ง๋ง, ๊ทนํ ๋์์ฑ ์ํฉ์์๋ ์์ ์ค์ผ์ค๋ง ์๊ณ ๋ฆฌ์ฆ์ด ๋ณ๋ชฉ์ด ๋ ์ ์์ต๋๋ค.
- Hyperlane์ ์์คํ ๋ถํ์ ๋ฐ๋ผ ์์ ํ ๋น์ ๋์ ์ผ๋ก ์กฐ์ ํ๋ ๋ณด๋ค ์ง๋ณด๋ ์ค์ผ์ค๋ฌ๋ฅผ ์ฌ์ฉํด, ๊ธ์ฆํ๋ ํธ๋ํฝ์๋ ์ต์ ํ๋ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
Practical Application Recommendations
๐ช EโCommerce Websites
Performance directly impacts revenue.
- Recommendation: Use Hyperlane for core business servicesโproduct search, recommendation engines, and order processing.
- Static assets: Serve with a dedicated web server such as Nginx.
๐ฌ Social Platforms
These systems handle massive numbers of connections and frequent messages.
- Recommendation: Build the realโtime messaging layer with Hyperlane, pairing it with an inโmemory store like Redis for lowโlatency delivery.
- Complex business logic: Consider GraphQL or similar APIs.
๐ข Enterprise Applications
Enterprise workloads demand strong consistency and complex transaction handling.
- Recommendation: Implement core services with Hyperlane, using PostgreSQL (or another relational DB) for persistence.
- CPUโintensive tasks: Leverage Hyperlaneโs asynchronous processing capabilities.
๋ฏธ๋ ๊ฐ๋ฐ ํธ๋ ๋
๐ ๊ทนํ ์ฑ๋ฅ
ํ๋์จ์ด๊ฐ ๋ฐ์ ํจ์ ๋ฐ๋ผ ํ๋ ์์ํฌ๋ ๋ฐฑ๋ง ๋จ์ QPS์ ๋ง์ดํฌ๋ก์ด ์์ค ์ง์ฐ ์๊ฐ์ ๋ชฉํ๋ก ํ ๊ฒ์ ๋๋ค.
๐ง ๊ฐ๋ฐโ๊ฒฝํ ์ต์ ํ
์์ํ ์๋๋ฟ๋ง ์๋๋ผ ๊ฐ๋ฐ์๋ ๋ ํ๋ถํ IDE ํตํฉ, ๋๋ฒ๊น ๋ฐ ๊ฐ์์ฑ ๋๊ตฌ์ ํํ์ ๋๋ฆด ์ ์์ต๋๋ค.
๐ ํด๋ผ์ฐ๋โ๋ค์ดํฐ๋ธ ์ง์
๋ฏธ๋ ํ๋ ์์ํฌ๋ ์ปจํ ์ด๋ํ, ๋ง์ดํฌ๋ก์๋น์ค, ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ, ๋ก๋ ๋ฐธ๋ฐ์ฑ, ์ํท ๋ธ๋ ์ดํน ๋ฐ ๊ธฐํ ํด๋ผ์ฐ๋โ๋ค์ดํฐ๋ธ ํจํด์ ์ํ ๊ธฐ๋ฅ์ ๋ด์ฅํ ๊ฒ์ ๋๋ค.
์์ฝ
ํ ์คํธ๋ฅผ ํตํด ํ๋ ์น ํ๋ ์์ํฌ์ ๋์ ์ฑ๋ฅ ์ ์ฌ๋ ฅ์ด ํ์ธ๋์์ต๋๋ค. Hyperlane์ ๋ฑ์ฅ์ Rust๊ฐ ์น ๊ฐ๋ฐ์ ๊ฐ์ ธ๋ค์ค ์ ์๋ ๊ฐ๋ฅ์ฑ์ ๋ณด์ฌ์ค๋๋ค. Tokio๊ฐ ์ผ๋ถ ๋ฒค์น๋งํฌ์์ ์ฌ์ ํ ์์ ์์ ์ ์์ง๋ง, Hyperlane์ ์ ๋ฐ์ ์ธ ์ฑ๋ฅ, ์์ ์ฑ, ๊ทธ๋ฆฌ๊ณ ์พ์ ํ ๊ฐ๋ฐ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
ํ๋ ์์ํฌ๋ฅผ ์ ํํ ๋๋ ๋จ์ํ ์งํ๋ฟ๋ง ์๋๋ผ ๋ค์๋ ๊ณ ๋ คํ์ธ์:
- ๊ฐ๋ฐ ํธ์์ฑ
- ์ํ๊ณ ์ฑ์๋
- ์ปค๋ฎค๋ํฐ ์ง์
Hyperlane์ ์ด๋ฌํ ์ธก๋ฉด์์ ๋์ ์ ์๋ฅผ ๋ฐ์ผ๋ฉฐ ์๋ํด๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค.
์น ๊ฐ๋ฐ์ ๋ฏธ๋๋ ์ ์ ๋ ์ฑ๋ฅ๊ณผ ํจ์จ์ฑ์ ์ด์ ์ ๋ง์ถ ๊ฒ์ด๋ฉฐ, Hyperlane์ ์ค์ํ ์ญํ ์ ํ ์ค๋น๊ฐ ๋์ด ์์ต๋๋ค.
ํจ๊ป ์น ๊ฐ๋ฐ ๊ธฐ์ ์ ๋ค์ ํ์ ์ ํฅํด ๋์๊ฐ์๋ค!