<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Middleware on Shaowen Chen's Website</title><link>https://www.chenshaowen.com/en/tags/middleware/</link><description>Recent content in Middleware on Shaowen Chen's Website</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>&amp;copy;2016 - {year}, All Rights Reserved.</copyright><lastBuildDate>Sun, 12 Jul 2026 00:00:00 +0000</lastBuildDate><sy:updatePeriod>weekly</sy:updatePeriod><atom:link href="https://www.chenshaowen.com/en/tags/middleware/atom.xml" rel="self" type="application/rss+xml"/><item><title>Deploying Ceph in Containers</title><link>https://www.chenshaowen.com/en/blog/container-deploy-ceph.html</link><pubDate>Sun, 12 Jul 2026 00:00:00 +0000</pubDate><atom:modified>Sun, 12 Jul 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-ceph.html</guid><description>This article covers single-node validation and three-node production deployment with cephadm. For architecture, operations, and functional testing, see Ceph Architecture and Operations. 1. Disk Preparation An OSD can only use a block device (/dev/sdX, a partition, /dev/loopN). 1.1 Inspecting Available Devices 1 2 3 4 5 6 7 lsblk -o</description><dc:creator>微信公众号</dc:creator><category>Middleware</category><category>Containers</category><category>Ceph</category><category>Storage</category><category>Operations</category></item><item><title>Ceph Architecture and Operations</title><link>https://www.chenshaowen.com/en/blog/container-deploy-ceph-architecture-operations-and-testing.html</link><pubDate>Sat, 11 Jul 2026 00:00:00 +0000</pubDate><atom:modified>Sat, 11 Jul 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-ceph-architecture-operations-and-testing.html</guid><description>Ceph is a unified distributed storage system that supports block storage (RBD), object storage (RGW), and file storage (CephFS). The official cephadm can orchestrate each daemon as a container (Docker, or Podman + Containerd); see Deploying Ceph in Containers for details.
1. Architecture 1.1 Topology and Data Paths The diagram below shows a common five-node topology (3 MON + 2 MGR + 5 OSD): MONs only need to come in odd numbers, and in a five-node deployment 3 is enough (tolerating one MON failure); 5 MONs tolerate 2 failures, but the metadata overhead is larger, so there is generally no need to run a MON on every machine.</description><dc:creator>微信公众号</dc:creator><category>Middleware</category><category>Containers</category><category>Ceph</category><category>Storage</category><category>Operations</category><category>Architecture</category></item><item><title>Deploying VictoriaMetrics in Containers</title><link>https://www.chenshaowen.com/en/blog/container-deploy-victoriametrics.html</link><pubDate>Sat, 11 Jul 2026 00:00:00 +0000</pubDate><atom:modified>Sat, 11 Jul 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-victoriametrics.html</guid><description>VictoriaMetrics (VM for short) is a time-series database compatible with the Prometheus ecosystem. It uses fewer resources than Prometheus and comes in both single-node and cluster editions. The single-node edition can directly replace Prometheus storage; the cluster edition splits reads, writes, and storage across vmstorage / vminsert / vmselect, giving it stronger horizontal scaling.</description><dc:creator>微信公众号</dc:creator><category>Middleware</category><category>Containers</category><category>VictoriaMetrics</category><category>Prometheus</category><category>Monitoring</category><category>Operations</category></item><item><title>Deploying ClickHouse in Containers</title><link>https://www.chenshaowen.com/en/blog/container-deploy-clickhouse.html</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><atom:modified>Wed, 11 Feb 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-clickhouse.html</guid><description>1. ClickHouse Single Node 1.1 Configure Environment Variables 1 2 3 4 5 6 7 8 export CONTAINER_CLI=nerdctl export IMAGE=clickhouse/clickhouse-server:24 export CLICKHOUSE_INSTANCE_NAME=clickhouse export CH_DATA=/data/ops/clickhouse/$CLICKHOUSE_INSTANCE_NAME export CLICKHOUSE_PORT=9000 export CLICKHOUSE_PROMETHEUS_PORT=9363 export CLICKHOUSE_USER=default export CLICKHOUSE_PASSWORD=xxxxxx 1.2 Generate the Configuration Files 1 2 3 4 5 6 7 8 9 10 11 12 13</description><dc:creator>微信公众号</dc:creator><category>Middleware</category><category>Containers</category><category>ClickHouse</category><category>Prometheus</category><category>Monitoring</category><category>Operations</category></item><item><title>Deploying Redis in Containers</title><link>https://www.chenshaowen.com/en/blog/container-deploy-redis.html</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><atom:modified>Wed, 11 Feb 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-redis.html</guid><description>1. Redis Single Instance Configure environment variables 1 2 3 4 5 6 7 8 9 export CONTAINER_CLI=nerdctl export IMAGE=redis:7 export REDIS_INSTANCE_NAME=redis-instance export REDIS_PASSWORD=xxxxxx export REDIS_PORT=6379 export REDIS_DATA=/data/ops/redis/$REDIS_INSTANCE_NAME mkdir -p $REDIS_DATA/data $REDIS_DATA/log Start the service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $CONTAINER_CLI run -d \ --name $REDIS_INSTANCE_NAME \ --restart always \ --security-opt apparmor=unconfined \ --security-opt seccomp=unconfined \ --network host \ --ulimit memlock=-1 \ --ulimit stack=67108864 \ --ulimit nofile=1048576:1048576 \ --memory-swappiness=0 \ -v $REDIS_DATA/data:/data \ -v $REDIS_DATA/log:/var/log/redis \ $IMAGE redis-server --port $REDIS_PORT --requirepass $REDIS_PASSWORD \ --maxmemory 64gb \ --maxmemory-policy noeviction \ --appendonly yes \ --appendfsync everysec Test the connection A PONG response means the connection succeeded</description><dc:creator>微信公众号</dc:creator><category>Middleware</category><category>Containers</category><category>Redis</category><category>Operations</category></item><item><title>Containerized Deployment of a Multi-Node FoundationDB Cluster and Operations</title><link>https://www.chenshaowen.com/en/blog/container-deploy-multi-node-foundationdb-and-maintenance.html</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate><atom:modified>Tue, 10 Feb 2026 00:00:00 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/container-deploy-multi-node-foundationdb-and-maintenance.html</guid><description>1. Generate a Cluster ID 1 cat /dev/urandom | tr -dc &amp;#39;a-zA-Z0-9&amp;#39; | fold -w 16 | head -n 1 The examples below use CLUSTER_ID=fKbIga9RHP79OIx1.
2. On the First Node Configure environment variables 1 2 3 4 5 6 7 8 9 10 export CONTAINER_CLI=nerdctl export IMAGE=foundationdb/foundationdb:7.1.26 export CLUSTER_ID=fKbIga9RHP79OIx1 export FDB_INSTANCE_NAME=fdb_server export FDB_CLUSTER_FIRST_IP=$(hostname -I | awk &amp;#39;{print $1}&amp;#39;) export FDB_PUBLIC_IP=$(hostname -I | awk &amp;#39;{print $1}&amp;#39;) export FDB_PORT=4500 export FDB_DIR=/data/ops/fdb/$FDB_INSTANCE_NAME Clean up old data 1 2 3 $CONTAINER_CLI rm -f $FDB_INSTANCE_NAME mv $FDB_DIR $FDB_DIR.</description><dc:creator>微信公众号</dc:creator><category>FoundationDB</category><category>Database</category><category>Middleware</category><category>Storage</category><category>Containers</category><category>3FS</category><category>Operations</category></item><item><title>RabbitMQ Message Queue</title><link>https://www.chenshaowen.com/en/blog/message-queue-about-rabbitmq.html</link><pubDate>Sat, 23 Dec 2017 20:51:22 +0000</pubDate><atom:modified>Sat, 23 Dec 2017 20:51:22 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/message-queue-about-rabbitmq.html</guid><description>1. Where a Message Queue Fits 1.1 Asynchronous Processing Use case: after a user registers, a registration email and a registration SMS must be sent. With the synchronous approach, system performance (concurrency, throughput, response time) hits a bottleneck. 1.2 Application Decoupling Use case: after a user places an order, the</description><dc:creator>微信公众号</dc:creator><category>RabbitMQ</category><category>Middleware</category><category>Celery</category><category>Python</category><category>Message</category><category>Queue</category></item><item><title>Error Code Design and Unified Exception Handling in Django</title><link>https://www.chenshaowen.com/en/blog/error-code-design-and-unified-processing-in-django.html</link><pubDate>Mon, 30 Oct 2017 21:50:33 +0000</pubDate><atom:modified>Mon, 30 Oct 2017 21:50:33 +0000</atom:modified><guid>https://www.chenshaowen.com/en/blog/error-code-design-and-unified-processing-in-django.html</guid><description>I currently use Django for SaaS development, and I develop and maintain several SaaS applications at the same time. Many SaaS applications have agreed-upon error codes, some used to handle login state, others to mark business logic status. For a feature that is so strongly shared across projects, it is</description><dc:creator>微信公众号</dc:creator><category>Django</category><category>Python</category><category>Error Codes</category><category>Middleware</category><category>R&amp;D</category><category>Learning</category><category>API</category><category>Best Practices</category></item></channel></rss>