Handle SIGTERM. Add docker-compose.yml (#59)

* docker-compsoe

* remove statsd config

* readme
This commit is contained in:
Lev Kokotov
2022-03-08 17:18:48 -08:00
committed by GitHub
parent 341ebf4123
commit b309ead58f
8 changed files with 139 additions and 24 deletions

View File

@@ -29,9 +29,6 @@ healthcheck_timeout = 100
# For how long to ban a server if it fails a health check (seconds).
ban_time = 60 # Seconds
# Stats will be sent here
statsd_address = "127.0.0.1:8125"
#
# User to use for authentication against the server.
[user]

View File

@@ -8,4 +8,4 @@ COPY --from=builder /app/target/release/pgcat /usr/bin/pgcat
COPY --from=builder /app/pgcat.toml /etc/pgcat/pgcat.toml
WORKDIR /etc/pgcat
ENV RUST_LOG=info
ENTRYPOINT ["/usr/bin/pgcat"]
CMD ["pgcat"]

View File

@@ -6,7 +6,7 @@
Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover support.
**Alpha**: looking for alpha testers, see [#35](https://github.com/levkk/pgcat/issues/35).
**Beta**: looking for beta testers, see [#35](https://github.com/levkk/pgcat/issues/35).
## Features
| **Feature** | **Status** | **Comments** |
@@ -24,8 +24,16 @@ Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover su
## Deployment
See `Dockerfile` for example deployment using Docker. The pooler is configured to spawn 4 workers so 4 CPUs are recommended for optimal performance.
That setting can be adjusted to spawn as many (or as little) workers as needed.
See `Dockerfile` for example deployment using Docker. The pooler is configured to spawn 4 workers so 4 CPUs are recommended for optimal performance. That setting can be adjusted to spawn as many (or as little) workers as needed.
For quick local example, use the Docker Compose environment provided:
```bash
docker-compose up
# In a new terminal:
psql -h 127.0.0.1 -p 6432 -c 'SELECT 1'
```
### Config

16
docker-compose.yml Normal file
View File

@@ -0,0 +1,16 @@
version: "3"
services:
postgres:
image: postgres:13
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_HOST_AUTH_METHOD: md5
pgcat:
build: .
command:
- "pgcat"
- "/etc/pgcat/pgcat.toml"
volumes:
- "${PWD}/examples/docker/pgcat.toml:/etc/pgcat/pgcat.toml"
ports:
- "6432:6432"

105
examples/docker/pgcat.toml Normal file
View File

@@ -0,0 +1,105 @@
#
# PgCat config example.
#
#
# General pooler settings
[general]
# What IP to run on, 0.0.0.0 means accessible from everywhere.
host = "0.0.0.0"
# Port to run on, same as PgBouncer used in this example.
port = 6432
# How many connections to allocate per server.
pool_size = 15
# Pool mode (see PgBouncer docs for more).
# session: one server connection per connected client
# transaction: one server connection per client transaction
pool_mode = "transaction"
# How long to wait before aborting a server connection (ms).
connect_timeout = 5000
# How much time to give `SELECT 1` health check query to return with a result (ms).
healthcheck_timeout = 1000
# For how long to ban a server if it fails a health check (seconds).
ban_time = 60 # Seconds
#
# User to use for authentication against the server.
[user]
name = "postgres"
password = "postgres"
#
# Shards in the cluster
[shards]
# Shard 0
[shards.0]
# [ host, port, role ]
servers = [
[ "postgres", 5432, "primary" ],
[ "postgres", 5432, "replica" ],
# [ "127.0.1.1", 5432, "replica" ],
]
# Database name (e.g. "postgres")
database = "postgres"
[shards.1]
# [ host, port, role ]
servers = [
[ "postgres", 5432, "primary" ],
[ "postgres", 5432, "replica" ],
# [ "127.0.1.1", 5432, "replica" ],
]
database = "postgres"
[shards.2]
# [ host, port, role ]
servers = [
[ "postgres", 5432, "primary" ],
[ "postgres", 5432, "replica" ],
# [ "127.0.1.1", 5432, "replica" ],
]
database = "postgres"
# Settings for our query routing layer.
[query_router]
# If the client doesn't specify, route traffic to
# this role by default.
#
# any: round-robin between primary and replicas,
# replica: round-robin between replicas only without touching the primary,
# primary: all queries go to the primary unless otherwise specified.
default_role = "any"
# Query parser. If enabled, we'll attempt to parse
# every incoming query to determine if it's a read or a write.
# If it's a read query, we'll direct it to a replica. Otherwise, if it's a write,
# we'll direct it to the primary.
query_parser_enabled = false
# If the query parser is enabled and this setting is enabled, the primary will be part of the pool of databases used for
# load balancing of read queries. Otherwise, the primary will only be used for write
# queries. The primary can always be explicitely selected with our custom protocol.
primary_reads_enabled = true
# So what if you wanted to implement a different hashing function,
# or you've already built one and you want this pooler to use it?
#
# Current options:
#
# pg_bigint_hash: PARTITION BY HASH (Postgres hashing function)
# sha1: A hashing function based on SHA1
#
sharding_function = "pg_bigint_hash"

View File

@@ -29,9 +29,6 @@ healthcheck_timeout = 1000
# For how long to ban a server if it fails a health check (seconds).
ban_time = 60 # Seconds
# Stats will be sent here
statsd_address = "127.0.0.1:8125"
#
# User to use for authentication against the server.
[user]

View File

@@ -103,7 +103,6 @@ pub struct General {
pub connect_timeout: u64,
pub healthcheck_timeout: u64,
pub ban_time: i64,
pub statsd_address: String,
}
impl Default for General {
@@ -116,7 +115,6 @@ impl Default for General {
connect_timeout: 5000,
healthcheck_timeout: 1000,
ban_time: 60,
statsd_address: String::from("127.0.0.1:8125"),
}
}
}
@@ -198,10 +196,6 @@ impl From<&Config> for std::collections::HashMap<String, String> {
config.general.healthcheck_timeout.to_string(),
),
("ban_time".to_string(), config.general.ban_time.to_string()),
(
"statsd_address".to_string(),
config.general.statsd_address.to_string(),
),
(
"default_role".to_string(),
config.query_router.default_role.to_string(),

View File

@@ -205,16 +205,14 @@ async fn main() {
}
});
// Setup shut down sequence
match signal::ctrl_c().await {
Ok(()) => {
info!("Shutting down...");
}
let mut term_signal = unix_signal(SignalKind::terminate()).unwrap();
Err(err) => {
error!("Unable to listen for shutdown signal: {}", err);
}
tokio::select! {
_ = signal::ctrl_c() => (),
_ = term_signal.recv() => (),
};
info!("Shutting down...");
}
/// Format chrono::Duration to be more human-friendly.