Skip to content

Instantly share code, notes, and snippets.

@johnlanni
Last active September 19, 2023 03:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save johnlanni/aac7480c17b0fde05fa64a20fc93b165 to your computer and use it in GitHub Desktop.
Save johnlanni/aac7480c17b0fde05fa64a20fc93b165 to your computer and use it in GitHub Desktop.
gRPC:Envoy vs Nginx
docker-compose up
k6 run --vus 500 ./script.js --duration 60s
version: '3'
services:
nginx:
image: nginx:1.23.4
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 50080:8080
networks:
- grpc_network
envoy:
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/envoy:1.20
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
ports:
- 50081:8081
command: ["envoy", "-c", "/etc/envoy/envoy.yaml", "--concurrency", "2"]
networks:
- grpc_network
grpc_server:
image: docker.io/moul/grpcbin:latest
networks:
- grpc_network
networks:
grpc_network:
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8081
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: http
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: route_config_0
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: backend_cluster
clusters:
- name: backend_cluster
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
circuit_breakers:
thresholds:
max_connections: 2
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: backend_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpc_server
port_value: 9000
admin:
access_log_path: /dev/null
address:
socket_address:
address: 0.0.0.0
port_value: 8001
syntax = "proto3";
package grpcbin;
service GRPCBin {
rpc Index(EmptyMessage) returns (IndexReply) {}
// 无参数调用的方法,调用后回返回一个空响应
rpc Empty(EmptyMessage) returns (EmptyMessage) {}
// 响应会返回请求的参数
rpc DummyUnary(DummyMessage) returns (DummyMessage) {}
// 响应为流式的调用,会分10次响应消息
rpc DummyServerStream(DummyMessage) returns (stream DummyMessage) {}
// 请求为流式的调用,会接受10次请求并返回最后一次的body
rpc DummyClientStream(stream DummyMessage) returns (DummyMessage) {}
// 请求响应都为流式的方法
rpc DummyBidirectionalStreamStream(stream DummyMessage) returns (stream DummyMessage) {}
// 该方法会返回指定的grpc错误
rpc SpecificError(SpecificErrorRequest) returns (EmptyMessage) {}
// 该方法调用会随机返回一个错误
rpc RandomError(EmptyMessage) returns (EmptyMessage) {}
// 该方法调用会返回header
rpc HeadersUnary(EmptyMessage) returns (HeadersMessage) {}
// 该方法调用不会返回响应
rpc NoResponseUnary(EmptyMessage) returns (EmptyMessage) {}
}
message HeadersMessage {
message Values {
repeated string values = 1;
}
map<string, Values> Metadata = 1;
}
message SpecificErrorRequest {
uint32 code = 1;
string reason = 2;
}
message EmptyMessage {}
message DummyMessage {
message Sub {
string f_string = 1;
}
enum Enum {
ENUM_0 = 0;
ENUM_1 = 1;
ENUM_2 = 2;
}
string f_string = 1;
repeated string f_strings = 2;
int32 f_int32 = 3;
repeated int32 f_int32s = 4;
Enum f_enum = 5;
repeated Enum f_enums = 6;
Sub f_sub = 7;
repeated Sub f_subs = 8;
bool f_bool = 9;
repeated bool f_bools = 10;
int64 f_int64 = 11;
repeated int64 f_int64s= 12;
bytes f_bytes = 13;
repeated bytes f_bytess = 14;
float f_float = 15;
repeated float f_floats = 16;
}
message IndexReply {
message Endpoint {
string path = 1;
string description = 2;
}
string description = 1;
repeated Endpoint endpoints = 2;
}
worker_processes 2;
events {
accept_mutex off;
worker_connections 102400;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
upstream grpc_backend {
keepalive 2;
server grpc_server:9000;
}
server {
listen 8080 backlog=20480 reuseport http2;
location / {
grpc_pass grpc://grpc_backend;
}
}
}
import grpc from 'k6/net/grpc';
import { check, sleep } from 'k6';
const client = new grpc.Client();
client.load([], './grpcbin.proto');
export default () => {
// nginx: 127.0.0.1:50080, envoy: 127.0.0.1:50081
client.connect('127.0.0.1:50080', {
plaintext: true
});
const data = {};
const response = client.invoke('grpcbin.GRPCBin/Index', data);
check(response, {
'status is OK': (r) => r && r.status === grpc.StatusOK,
});
client.close();
};
@johnlanni
Copy link
Author

johnlanni commented May 23, 2023

envoy:
image

nginx:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment