C语言企业项目实战(四)

第六部分:构建与测试

6.1 单元测试(Unity框架)

复制代码
// tests/unit/test_sds.c
#include "unity.h"
#include "sds.h"
void setUp(void) {}
void tearDown(void) {}
void test_sds_new(void) {
    sds str = sdsnew("Hello");
    TEST_ASSERT_NOT_NULL(str);
    TEST_ASSERT_EQUAL_STRING("Hello", str);
    TEST_ASSERT_EQUAL(5, sdslen(str));
    sdsfree(str);
}
void test_sds_cat(void) {
    sds str = sdsnew("Hello");
    str = sdscat(str, " World");
    TEST_ASSERT_EQUAL_STRING("Hello World", str);
    TEST_ASSERT_EQUAL(11, sdslen(str));
    sdsfree(str);
}
void test_sds_cpy(void) {
    sds str = sdsnew("Hello");
    str = sdscpy(str, "Hi");
    TEST_ASSERT_EQUAL_STRING("Hi", str);
    TEST_ASSERT_EQUAL(2, sdslen(str));
    sdsfree(str);
}
int main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_sds_new);
    RUN_TEST(test_sds_cat);
    RUN_TEST(test_sds_cpy);
    return UNITY_END();
}

6.2 压力测试

复制代码
// tests/benchmark/bench_cache.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define THREADS 4
#define REQUESTS_PER_THREAD 1000000
#define HOST "127.0.0.1"
#define PORT 6379
typedef struct {
    int thread_id;
    long long requests;
    long long successes;
    long long total_time_us;
} bench_result;
void *bench_thread(void *arg) {
    bench_result *result = (bench_result *)arg;
    redisContext *c = redisConnect(HOST, PORT);
    if (!c || c->err) {
        printf("连接失败: %s\n", c ? c->errstr : "未知错误");
        return NULL;
    }
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for (int i = 0; i < REQUESTS_PER_THREAD; i++) {
        // SET命令
        char key[32], value[64];
        snprintf(key, sizeof(key), "key:%d:%d", result->thread_id, i);
        snprintf(value, sizeof(value), "value:%d:%d", result->thread_id, i);
        redisReply *reply = redisCommand(c, "SET %s %s", key, value);
        if (reply && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {
            result->successes++;
        }
        freeReplyObject(reply);
        // GET命令
        reply = redisCommand(c, "GET %s", key);
        if (reply && reply->type == REDIS_REPLY_STRING) {
            result->successes++;
        }
        freeReplyObject(reply);
        result->requests += 2;
    }
    gettimeofday(&end, NULL);
    result->total_time_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
    redisFree(c);
    return NULL;
}
int main() {
    pthread_t threads[THREADS];
    bench_result results[THREADS];
    for (int i = 0; i < THREADS; i++) {
        results[i].thread_id = i;
        results[i].requests = 0;
        results[i].successes = 0;
        results[i].total_time_us = 0;
        pthread_create(&threads[i], NULL, bench_thread, &results[i]);
    }
    long long total_requests = 0;
    long long total_successes = 0;
    long long max_time_us = 0;
    for (int i = 0; i < THREADS; i++) {
        pthread_join(threads[i], NULL);
        total_requests += results[i].requests;
        total_successes += results[i].successes;
        if (results[i].total_time_us > max_time_us) {
            max_time_us = results[i].total_time_us;
        }
    }
    double qps = (double)total_requests / (max_time_us / 1000000.0);
    double success_rate = (double)total_successes / total_requests * 100;
    printf("========== 压测结果 ==========\n");
    printf("总请求数: %lld\n", total_requests);
    printf("成功数: %lld\n", total_successes);
    printf("成功率: %.2f%%\n", success_rate);
    printf("QPS: %.0f\n", qps);
    printf("平均延迟: %.2f us\n", max_time_us / (double)total_requests);
    return 0;
}

第七部分:部署与运维

7.1 Systemd服务配置

复制代码
# /etc/systemd/system/ccache.service
[Unit]
Description=C-Cache High Performance Memory Cache
After=network.target
Documentation=https://github.com/ccache/ccache
[Service]
Type=simple
User=ccache
Group=ccache
ExecStart=/usr/local/bin/ccache /etc/ccache/ccache.conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
LimitMEMLOCK=infinity
# 安全加固
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes
ReadWritePaths=/var/lib/ccache /var/log/ccache
[Install]
WantedBy=multi-user.target

7.2 Docker镜像构建

复制代码
# Dockerfile
FROM alpine:3.18 AS builder
RUN apk add --no-cache gcc make musl-dev linux-headers
COPY . /src
WORKDIR /src
RUN make && make install
FROM alpine:3.18
RUN apk add --no-cache libgcc
COPY --from=builder /usr/local/bin/ccache /usr/local/bin/ccache
COPY --from=builder /etc/ccache/ccache.conf /etc/ccache/ccache.conf
RUN adduser -D -h /var/lib/ccache ccache
USER ccache
EXPOSE 6379
ENTRYPOINT ["/usr/local/bin/ccache"]
CMD ["/etc/ccache/ccache.conf"]

7.3 监控指标暴露

复制代码
// src/monitor/metrics.c
#include 
#include "dict.h"
#include "atomic.h"
/* 性能计数器 */
static atomic64_t total_commands_processed;
static atomic64_t total_net_input_bytes;
static atomic64_t total_net_output_bytes;
static atomic64_t total_expired_keys;
static atomic64_t total_evicted_keys;
/* 获取统计信息 */
sds getInfo(sds info) {
    info = sdscatprintf(info,
        "# Server\r\n"
        "redis_version:%s\r\n"
        "os:%s\r\n"
        "arch_bits:%d\r\n"
        "process_id:%d\r\n"
        "\r\n"
        "# Clients\r\n"
        "connected_clients:%d\r\n"
        "\r\n"
        "# Memory\r\n"
        "used_memory:%zu\r\n"
        "used_memory_human:%s\r\n"
        "\r\n"
        "# Stats\r\n"
        "total_commands_processed:%lld\r\n"
        "instantaneous_ops_per_sec:%lld\r\n"
        "total_net_input_bytes:%lld\r\n"
        "total_net_output_bytes:%lld\r\n"
        "expired_keys:%lld\r\n"
        "evicted_keys:%lld\r\n"
        "\r\n",
        CCACHE_VERSION,
        getOS(),
        sizeof(void*) * 8,
        getpid(),
        server.clients_count,
        zmalloc_used_memory(),
        bytesToHuman(mem_str, zmalloc_used_memory()),
        atomic64_read(&total_commands_processed),
        getInstantaneousOpsPerSec(),
        atomic64_read(&total_net_input_bytes),
        atomic64_read(&total_net_output_bytes),
        atomic64_read(&total_expired_keys),
        atomic64_read(&total_evicted_keys)
    );
    return info;
}

C语言企业级开发的关键不在于写出多么精巧的代码,而在于构建一套可持续维护、可扩展、高性能的工程体系。希望本文能够帮助你跨越"会写C语言"到"能开发企业级系统"之间的鸿沟。

相关推荐
189228048611 小时前
NV091固态MT29F16T08EWLCHD8-QJES:C
c语言·开发语言
AI科技星1 小时前
《数术工坊:无穷套娃录》 一部用数学套娃写成的“天书小说”
c语言·开发语言·网络·量子计算·agi
m0_547486662 小时前
华南农业大学《C语言程序设计》期末试卷及答案2018-2025年PDF
c语言·开发语言·pdf·c语言程序设计
Hello:CodeWorld13 小时前
C 风格变参 vs C++ 变参模板:核心区别与选型指南
c语言·c++·算法
十月的皮皮15 小时前
C语言学习笔记20260606- 求月份天数三种写法
c语言·笔记·学习
caimouse16 小时前
Reactos 第 5 章 进程与线程 — 5.8 Windows 的 APC 机制
c语言·windows
努力攻坚操作系统18 小时前
编程语言编译运行机制对比:C / Java / Python
java·c语言·python
学会去珍惜18 小时前
C语言简介
c语言·开发语言
技术落地手记19 小时前
一个需求 ID 换一份完整测试用例,我让 AI 替测试同事省掉半天
单元测试·测试