diff --git a/Cargo.lock b/Cargo.lock index ad3076094f17..bf72d45a941f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6499,6 +6499,7 @@ dependencies = [ "humantime-serde", "itertools 0.10.5", "lazy_static", + "local-ip-address", "once_cell", "parking_lot 0.12.3", "prometheus", @@ -10892,6 +10893,7 @@ dependencies = [ "json5", "jsonb", "lazy_static", + "local-ip-address", "log-query", "loki-api", "mime_guess", diff --git a/Cargo.toml b/Cargo.toml index 91b05578d101..f478eca843d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,6 +135,7 @@ humantime-serde = "1.1" itertools = "0.10" jsonb = { git = "https://github.com/databendlabs/jsonb.git", rev = "8c8d2fc294a39f3ff08909d60f718639cfba3875", default-features = false } lazy_static = "1.4" +local-ip-address = "0.6" meter-core = { git = "https://github.com/GreptimeTeam/greptime-meter.git", rev = "a10facb353b41460eeb98578868ebf19c2084fac" } mockall = "0.11.4" moka = "0.12" diff --git a/config/config.md b/config/config.md index 759d34364c2c..a1f8b1e36230 100644 --- a/config/config.md +++ b/config/config.md @@ -214,7 +214,7 @@ | `http.body_limit` | String | `64MB` | HTTP request body limit.
The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
Set to 0 to disable limit. | | `grpc` | -- | -- | The gRPC server options. | | `grpc.addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. | -| `grpc.hostname` | String | `127.0.0.1` | The hostname advertised to the metasrv,
and used for connections from outside the host | +| `grpc.hostname` | String | `127.0.0.1:4001` | The hostname advertised to the metasrv,
and used for connections from outside the host | | `grpc.runtime_size` | Integer | `8` | The number of server worker threads. | | `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. | | `grpc.tls.mode` | String | `disable` | TLS mode. | @@ -378,7 +378,7 @@ | `http.body_limit` | String | `64MB` | HTTP request body limit.
The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
Set to 0 to disable limit. | | `grpc` | -- | -- | The gRPC server options. | | `grpc.addr` | String | `127.0.0.1:3001` | The address to bind the gRPC server. | -| `grpc.hostname` | String | `127.0.0.1` | The hostname advertised to the metasrv,
and used for connections from outside the host | +| `grpc.hostname` | String | `127.0.0.1:3001` | The hostname advertised to the metasrv,
and used for connections from outside the host | | `grpc.runtime_size` | Integer | `8` | The number of server worker threads. | | `grpc.max_recv_message_size` | String | `512MB` | The maximum receive message size for gRPC server. | | `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. | diff --git a/config/datanode.example.toml b/config/datanode.example.toml index a329cb4f3aba..9d9ff5925dc5 100644 --- a/config/datanode.example.toml +++ b/config/datanode.example.toml @@ -59,7 +59,7 @@ body_limit = "64MB" addr = "127.0.0.1:3001" ## The hostname advertised to the metasrv, ## and used for connections from outside the host -hostname = "127.0.0.1" +hostname = "127.0.0.1:3001" ## The number of server worker threads. runtime_size = 8 ## The maximum receive message size for gRPC server. diff --git a/config/frontend.example.toml b/config/frontend.example.toml index b8e6c5cd8b9e..ade1b9169a04 100644 --- a/config/frontend.example.toml +++ b/config/frontend.example.toml @@ -38,7 +38,7 @@ body_limit = "64MB" addr = "127.0.0.1:4001" ## The hostname advertised to the metasrv, ## and used for connections from outside the host -hostname = "127.0.0.1" +hostname = "127.0.0.1:4001" ## The number of server worker threads. runtime_size = 8 diff --git a/src/cmd/src/datanode.rs b/src/cmd/src/datanode.rs index 3737b9266a7b..bb5948edfa61 100644 --- a/src/cmd/src/datanode.rs +++ b/src/cmd/src/datanode.rs @@ -276,7 +276,8 @@ impl StartCommand { info!("Datanode options: {:#?}", opts); let plugin_opts = opts.plugins; - let opts = opts.component; + let mut opts = opts.component; + opts.grpc.detect_hostname(); let mut plugins = Plugins::new(); plugins::setup_datanode_plugins(&mut plugins, &plugin_opts, &opts) .await diff --git a/src/cmd/src/flownode.rs b/src/cmd/src/flownode.rs index e629edf2510d..04950975549a 100644 --- a/src/cmd/src/flownode.rs +++ b/src/cmd/src/flownode.rs @@ -222,7 +222,8 @@ impl StartCommand { info!("Flownode start command: {:#?}", self); info!("Flownode options: {:#?}", opts); - let opts = opts.component; + let mut opts = opts.component; + opts.grpc.detect_hostname(); // TODO(discord9): make it not optionale after cluster id is required let cluster_id = opts.cluster_id.unwrap_or(0); diff --git a/src/cmd/src/frontend.rs b/src/cmd/src/frontend.rs index 36bd37a51980..264411943fea 100644 --- a/src/cmd/src/frontend.rs +++ b/src/cmd/src/frontend.rs @@ -268,7 +268,8 @@ impl StartCommand { info!("Frontend options: {:#?}", opts); let plugin_opts = opts.plugins; - let opts = opts.component; + let mut opts = opts.component; + opts.grpc.detect_hostname(); let mut plugins = Plugins::new(); plugins::setup_frontend_plugins(&mut plugins, &plugin_opts, &opts) .await diff --git a/src/cmd/src/metasrv.rs b/src/cmd/src/metasrv.rs index b97d0710a582..6af4e599e08f 100644 --- a/src/cmd/src/metasrv.rs +++ b/src/cmd/src/metasrv.rs @@ -272,7 +272,8 @@ impl StartCommand { info!("Metasrv options: {:#?}", opts); let plugin_opts = opts.plugins; - let opts = opts.component; + let mut opts = opts.component; + opts.detect_server_addr(); let mut plugins = Plugins::new(); plugins::setup_metasrv_plugins(&mut plugins, &plugin_opts, &opts) .await diff --git a/src/cmd/src/standalone.rs b/src/cmd/src/standalone.rs index e3675a7db7c1..d72ec5ef43fd 100644 --- a/src/cmd/src/standalone.rs +++ b/src/cmd/src/standalone.rs @@ -461,7 +461,8 @@ impl StartCommand { let mut plugins = Plugins::new(); let plugin_opts = opts.plugins; - let opts = opts.component; + let mut opts = opts.component; + opts.grpc.detect_hostname(); let fe_opts = opts.frontend_options(); let dn_opts = opts.datanode_options(); diff --git a/src/cmd/tests/load_config_test.rs b/src/cmd/tests/load_config_test.rs index e142a0b4a689..c590e1965a7e 100644 --- a/src/cmd/tests/load_config_test.rs +++ b/src/cmd/tests/load_config_test.rs @@ -85,7 +85,9 @@ fn test_load_datanode_example_config() { remote_write: Some(Default::default()), ..Default::default() }, - grpc: GrpcOptions::default().with_addr("127.0.0.1:3001"), + grpc: GrpcOptions::default() + .with_addr("127.0.0.1:3001") + .with_hostname("127.0.0.1:3001"), rpc_addr: Some("127.0.0.1:3001".to_string()), rpc_hostname: Some("127.0.0.1".to_string()), rpc_runtime_size: Some(8), @@ -137,6 +139,7 @@ fn test_load_frontend_example_config() { remote_write: Some(Default::default()), ..Default::default() }, + grpc: GrpcOptions::default().with_hostname("127.0.0.1:4001"), ..Default::default() }, ..Default::default() @@ -154,6 +157,7 @@ fn test_load_metasrv_example_config() { component: MetasrvOptions { selector: SelectorType::default(), data_home: "/tmp/metasrv/".to_string(), + server_addr: "127.0.0.1:3002".to_string(), logging: LoggingOptions { dir: "/tmp/greptimedb/logs".to_string(), level: Some("info".to_string()), diff --git a/src/meta-srv/Cargo.toml b/src/meta-srv/Cargo.toml index b383607afe66..4804b3ba7186 100644 --- a/src/meta-srv/Cargo.toml +++ b/src/meta-srv/Cargo.toml @@ -45,6 +45,7 @@ humantime.workspace = true humantime-serde.workspace = true itertools.workspace = true lazy_static.workspace = true +local-ip-address.workspace = true once_cell.workspace = true parking_lot.workspace = true prometheus.workspace = true diff --git a/src/meta-srv/src/metasrv.rs b/src/meta-srv/src/metasrv.rs index e688b25e04bd..93921cbdd6c8 100644 --- a/src/meta-srv/src/metasrv.rs +++ b/src/meta-srv/src/metasrv.rs @@ -142,11 +142,14 @@ pub struct MetasrvOptions { pub backend: BackendImpl, } +const DEFAULT_METASRV_ADDR_PORT: &str = "3002"; + impl Default for MetasrvOptions { fn default() -> Self { Self { - bind_addr: "127.0.0.1:3002".to_string(), - server_addr: "127.0.0.1:3002".to_string(), + bind_addr: format!("127.0.0.1:{}", DEFAULT_METASRV_ADDR_PORT), + // If server_addr is not set, the server will use the local ip address as the server address. + server_addr: String::new(), store_addrs: vec!["127.0.0.1:2379".to_string()], selector: SelectorType::default(), use_memory_store: false, @@ -184,6 +187,31 @@ impl Configurable for MetasrvOptions { } } +impl MetasrvOptions { + /// Detect server address if `auto_server_addr` is true. + pub fn detect_server_addr(&mut self) { + if self.server_addr.is_empty() { + match local_ip_address::local_ip() { + Ok(ip) => { + let detected_addr = format!( + "{}:{}", + ip, + self.bind_addr + .split(':') + .nth(1) + .unwrap_or(DEFAULT_METASRV_ADDR_PORT) + ); + info!("Using detected: {} as server address", detected_addr); + self.server_addr = detected_addr; + } + Err(e) => { + error!("Failed to detect local ip address: {}", e); + } + } + } + } +} + pub struct MetasrvInfo { pub server_addr: String, } diff --git a/src/meta-srv/src/mocks.rs b/src/meta-srv/src/mocks.rs index 9611fcdd13df..2a621814f2d7 100644 --- a/src/meta-srv/src/mocks.rs +++ b/src/meta-srv/src/mocks.rs @@ -44,12 +44,32 @@ pub struct MockInfo { pub async fn mock_with_memstore() -> MockInfo { let kv_backend = Arc::new(MemoryKvBackend::new()); let in_memory = Arc::new(MemoryKvBackend::new()); - mock(Default::default(), kv_backend, None, None, Some(in_memory)).await + mock( + MetasrvOptions { + server_addr: "127.0.0.1:3002".to_string(), + ..Default::default() + }, + kv_backend, + None, + None, + Some(in_memory), + ) + .await } pub async fn mock_with_etcdstore(addr: &str) -> MockInfo { let kv_backend = EtcdStore::with_endpoints([addr], 128).await.unwrap(); - mock(Default::default(), kv_backend, None, None, None).await + mock( + MetasrvOptions { + server_addr: "127.0.0.1:3002".to_string(), + ..Default::default() + }, + kv_backend, + None, + None, + None, + ) + .await } pub async fn mock( diff --git a/src/meta-srv/src/service/heartbeat.rs b/src/meta-srv/src/service/heartbeat.rs index 489afe41e8c2..ef3d30b4d933 100644 --- a/src/meta-srv/src/service/heartbeat.rs +++ b/src/meta-srv/src/service/heartbeat.rs @@ -194,6 +194,7 @@ mod tests { use super::get_node_id; use crate::metasrv::builder::MetasrvBuilder; + use crate::metasrv::MetasrvOptions; #[tokio::test] async fn test_ask_leader() { @@ -201,6 +202,10 @@ mod tests { let metasrv = MetasrvBuilder::new() .kv_backend(kv_backend) + .options(MetasrvOptions { + server_addr: "127.0.0.1:3002".to_string(), + ..Default::default() + }) .build() .await .unwrap(); diff --git a/src/meta-srv/src/service/store.rs b/src/meta-srv/src/service/store.rs index f9a970bca731..acbc090e5c89 100644 --- a/src/meta-srv/src/service/store.rs +++ b/src/meta-srv/src/service/store.rs @@ -306,6 +306,7 @@ mod tests { #[tokio::test] async fn test_batch_put() { + common_telemetry::init_default_ut_logging(); let metasrv = new_metasrv().await; let mut req = BatchPutRequest::default(); diff --git a/src/servers/Cargo.toml b/src/servers/Cargo.toml index 674cd3f7df05..75c68e7a76de 100644 --- a/src/servers/Cargo.toml +++ b/src/servers/Cargo.toml @@ -65,6 +65,7 @@ influxdb_line_protocol = { git = "https://github.com/evenyag/influxdb_iox", bran itertools.workspace = true jsonb.workspace = true lazy_static.workspace = true +local-ip-address.workspace = true log-query.workspace = true loki-api = "0.1" mime_guess = "2.0" diff --git a/src/servers/src/grpc.rs b/src/servers/src/grpc.rs index d3198b46a83c..8225f7cd8cdd 100644 --- a/src/servers/src/grpc.rs +++ b/src/servers/src/grpc.rs @@ -65,11 +65,39 @@ pub struct GrpcOptions { pub tls: TlsOption, } +impl GrpcOptions { + /// Detect hostname if `auto_hostname` is true. + pub fn detect_hostname(&mut self) { + if self.hostname.is_empty() { + match local_ip_address::local_ip() { + Ok(ip) => { + let detected_addr = format!( + "{}:{}", + ip, + self.addr + .split(':') + .nth(1) + .unwrap_or(DEFAULT_GRPC_ADDR_PORT) + ); + info!("Using detected: {} as server address", detected_addr); + self.hostname = detected_addr; + } + Err(e) => { + error!("Failed to detect local ip address: {}", e); + } + } + } + } +} + +const DEFAULT_GRPC_ADDR_PORT: &str = "4001"; + impl Default for GrpcOptions { fn default() -> Self { Self { - addr: "127.0.0.1:4001".to_string(), - hostname: "127.0.0.1".to_string(), + addr: format!("127.0.0.1:{}", DEFAULT_GRPC_ADDR_PORT), + // If hostname is not set, the server will use the local ip address as the hostname. + hostname: String::new(), max_recv_message_size: DEFAULT_MAX_GRPC_RECV_MESSAGE_SIZE, max_send_message_size: DEFAULT_MAX_GRPC_SEND_MESSAGE_SIZE, runtime_size: 8, @@ -83,6 +111,11 @@ impl GrpcOptions { self.addr = addr.to_string(); self } + + pub fn with_hostname(mut self, hostname: &str) -> Self { + self.hostname = hostname.to_string(); + self + } } pub struct GrpcServer { diff --git a/tests-integration/src/cluster.rs b/tests-integration/src/cluster.rs index 83778da5bbc4..93664c2f19cd 100644 --- a/tests-integration/src/cluster.rs +++ b/tests-integration/src/cluster.rs @@ -185,6 +185,7 @@ impl GreptimeDbClusterBuilder { max_metadata_value_size: None, }, wal: self.metasrv_wal_config.clone(), + server_addr: "127.0.0.1:3002".to_string(), ..Default::default() }; diff --git a/tests-integration/src/standalone.rs b/tests-integration/src/standalone.rs index cc2458fa99cb..0b6a3774187c 100644 --- a/tests-integration/src/standalone.rs +++ b/tests-integration/src/standalone.rs @@ -45,6 +45,7 @@ use frontend::instance::builder::FrontendBuilder; use frontend::instance::{FrontendInstance, Instance, StandaloneDatanodeManager}; use meta_srv::metasrv::{FLOW_ID_SEQ, TABLE_ID_SEQ}; use query::stats::StatementStatistics; +use servers::grpc::GrpcOptions; use servers::Mode; use snafu::ResultExt; @@ -291,6 +292,7 @@ impl GreptimeDbStandaloneBuilder { procedure: procedure_config, metadata_store: kv_backend_config, wal: self.metasrv_wal_config.clone().into(), + grpc: GrpcOptions::default().with_hostname("127.0.0.1:4001"), ..StandaloneOptions::default() }; diff --git a/tests-integration/src/test_util.rs b/tests-integration/src/test_util.rs index 57ec7f6f86f9..3ac0332b50a7 100644 --- a/tests-integration/src/test_util.rs +++ b/tests-integration/src/test_util.rs @@ -349,7 +349,9 @@ pub(crate) fn create_datanode_opts( providers, store: default_store, }, - grpc: GrpcOptions::default().with_addr(PEER_PLACEHOLDER_ADDR), + grpc: GrpcOptions::default() + .with_addr(PEER_PLACEHOLDER_ADDR) + .with_hostname(PEER_PLACEHOLDER_ADDR), mode, wal: wal_config, ..Default::default() diff --git a/tests-integration/tests/http.rs b/tests-integration/tests/http.rs index 8b252e71e48c..d2b469f8e4a8 100644 --- a/tests-integration/tests/http.rs +++ b/tests-integration/tests/http.rs @@ -850,7 +850,7 @@ is_strict_mode = false [grpc] addr = "127.0.0.1:4001" -hostname = "127.0.0.1" +hostname = "127.0.0.1:4001" max_recv_message_size = "512MiB" max_send_message_size = "512MiB" runtime_size = 8 diff --git a/tests/conf/datanode-test.toml.template b/tests/conf/datanode-test.toml.template index 3c999635d91c..d820babf5c7b 100644 --- a/tests/conf/datanode-test.toml.template +++ b/tests/conf/datanode-test.toml.template @@ -1,8 +1,6 @@ node_id = 1 mode = 'distributed' require_lease_before_startup = true -rpc_addr = '127.0.0.1:29410' -rpc_hostname = '127.0.0.1' rpc_runtime_size = 8 [wal] diff --git a/tests/conf/frontend-test.toml.template b/tests/conf/frontend-test.toml.template new file mode 100644 index 000000000000..983754e5894b --- /dev/null +++ b/tests/conf/frontend-test.toml.template @@ -0,0 +1,3 @@ +[grpc] +addr = "127.0.0.1:29401" +hostname = "127.0.0.1:29401" \ No newline at end of file diff --git a/tests/runner/src/env.rs b/tests/runner/src/env.rs index 7c35e79fbafa..7ca65b3a5f56 100644 --- a/tests/runner/src/env.rs +++ b/tests/runner/src/env.rs @@ -356,6 +356,8 @@ impl Env { "--log-dir={}/greptimedb-frontend/logs", self.sqlness_home.display() ), + "-c".to_string(), + self.generate_config_file(subcommand, db_ctx), ]; ( args, @@ -456,6 +458,7 @@ impl Env { "start".to_string(), ]; args.push(format!("--rpc-addr=127.0.0.1:2941{id}")); + args.push(format!("--rpc-hostname=127.0.0.1:2941{id}")); args.push(format!("--http-addr=127.0.0.1:2943{id}")); args.push(format!("--data-home={}", data_home.display())); args.push(format!("--log-dir={}/logs", data_home.display())); @@ -480,6 +483,7 @@ impl Env { "start".to_string(), ]; args.push(format!("--rpc-addr=127.0.0.1:2968{id}")); + args.push(format!("--rpc-hostname=127.0.0.1:2968{id}")); args.push(format!("--node-id={id}")); args.push(format!( "--log-dir={}/greptimedb-flownode/logs",