RPC分布式通信(3)--RPC基础框架接口

一、MprpcApplication 核心职责

MprpcApplication是 RPC 框架的 "管家",核心作用:

  1. 单例模式:全局唯一实例,避免重复初始化;

  2. 配置加载:解析 RPC 框架的配置文件(如服务器 IP、端口、日志路径、注册中心地址等);

  3. 框架初始化:启动时初始化日志、网络、注册中心等核心组件;

  4. 全局参数访问:提供接口获取配置参数(如获取服务器端口、注册中心地址);

  5. 框架销毁:程序退出时释放资源。

二、MprpcApplication 核心接口设计

以下是工业级 RPC 框架中MprpcApplication的标准接口设计(按功能分类):

接口类型 接口名 功能描述
单例获取 GetInstance() 获取全局唯一的MprpcApplication实例(懒汉 / 饿汉单例)
初始化 Init(int argc, char** argv) 解析命令行参数 + 加载配置文件,初始化框架(核心入口)
配置获取 GetConfig(const std::string& key) 根据 key 获取配置值(如 "rpcserver_ip")
便捷配置获取 GetRpcServerIp() 快捷获取 RPC 服务器 IP(封装GetConfig
便捷配置获取 GetRpcServerPort() 快捷获取 RPC 服务器端口
便捷配置获取 GetZkServerIp() 快捷获取 Zookeeper 注册中心 IP
框架销毁 Destroy() 释放框架资源(日志、网络连接、注册中心句柄等)

三、MprpcApplication 完整实现代码

以下是可直接编译运行的MprpcApplication实现,包含单例、配置加载、参数访问等核心功能:

1. 头文件(mprpcapplication.h)
复制代码
#ifndef MPRPCAPPLICATION_H
#define MPRPCAPPLICATION_H

#include <iostream>
#include <string>
#include <unordered_map>
#include <mutex>

// RPC框架核心应用类(单例模式)
class MprpcApplication {
public:
    // 1. 单例获取:懒汉模式(线程安全)
    static MprpcApplication& GetInstance();

    // 2. 框架初始化:解析命令行参数 + 加载配置文件
    // 命令行参数格式:./rpcserver -i config.conf
    void Init(int argc, char** argv);

    // 3. 通用配置获取接口
    std::string GetConfig(const std::string& key);

    // 4. 便捷配置获取接口(封装GetConfig,避免重复解析字符串)
    std::string GetRpcServerIp();   // 获取RPC服务器IP
    uint16_t GetRpcServerPort();    // 获取RPC服务器端口
    std::string GetZkServerIp();    // 获取Zookeeper注册中心IP
    uint16_t GetZkServerPort();     // 获取Zookeeper注册中心端口

    // 5. 框架销毁:释放全局资源
    void Destroy();

    // 禁止拷贝和移动(单例模式必须)
    MprpcApplication(const MprpcApplication&) = delete;
    MprpcApplication& operator=(const MprpcApplication&) = delete;
    MprpcApplication(MprpcApplication&&) = delete;
    MprpcApplication& operator=(MprpcApplication&&) = delete;

private:
    // 私有构造/析构:单例模式
    MprpcApplication() = default;
    ~MprpcApplication() = default;

    // 解析配置文件(内部辅助函数)
    void LoadConfigFile(const std::string& config_file);

    // 全局配置存储(key-value)
    std::unordered_map<std::string, std::string> m_config_map;

    // 单例锁(保证线程安全)
    static std::mutex m_mutex;
    static MprpcApplication* m_instance;
};

#endif // MPRPCAPPLICATION_H
2. 实现文件(mprpcapplication.cpp)
复制代码
#include "mprpcapplication.h"
#include <unistd.h>
#include <string.h>
#include <sstream>

// 静态成员初始化
MprpcApplication* MprpcApplication::m_instance = nullptr;
std::mutex MprpcApplication::m_mutex;

// 1. 获取单例实例(线程安全的懒汉模式)
MprpcApplication& MprpcApplication::GetInstance() {
    if (m_instance == nullptr) {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (m_instance == nullptr) {
            m_instance = new MprpcApplication();
        }
    }
    return *m_instance;
}

// 2. 框架初始化核心逻辑
void MprpcApplication::Init(int argc, char** argv) {
    if (argc < 2) {
        std::cerr << "usage: " << argv[0] << " -i <config_file>" << std::endl;
        exit(EXIT_FAILURE);
    }

    // 解析命令行参数(-i 指定配置文件)
    int opt = 0;
    std::string config_file;
    while ((opt = getopt(argc, argv, "i:")) != -1) {
        switch (opt) {
            case 'i':
                config_file = optarg;
                break;
            case '?':
                std::cerr << "invalid option: " << static_cast<char>(optopt) << std::endl;
                exit(EXIT_FAILURE);
            case ':':
                std::cerr << "option " << static_cast<char>(optopt) << " requires an argument" << std::endl;
                exit(EXIT_FAILURE);
            default:
                break;
        }
    }

    // 加载配置文件
    LoadConfigFile(config_file);

    // 初始化日志/网络等组件(可扩展)
    std::cout << "MprpcApplication init success!" << std::endl;
    std::cout << "rpcserver_ip: " << GetRpcServerIp() << std::endl;
    std::cout << "rpcserver_port: " << GetRpcServerPort() << std::endl;
    std::cout << "zookeeper_ip: " << GetZkServerIp() << std::endl;
    std::cout << "zookeeper_port: " << GetZkServerPort() << std::endl;
}

// 解析配置文件(格式:key=value,忽略注释行#)
void MprpcApplication::LoadConfigFile(const std::string& config_file) {
    FILE* fp = fopen(config_file.c_str(), "r");
    if (fp == nullptr) {
        std::cerr << "config file " << config_file << " not exist!" << std::endl;
        exit(EXIT_FAILURE);
    }

    // 逐行解析配置
    char buf[512] = {0};
    while (fgets(buf, sizeof(buf), fp) != nullptr) {
        // 去掉换行符/空格
        std::string line(buf);
        Trim(line);

        // 跳过空行/注释行
        if (line.empty() || line[0] == '#') {
            continue;
        }

        // 解析key=value
        size_t pos = line.find('=');
        if (pos == std::string::npos) {
            // 配置格式错误
            continue;
        }

        std::string key = line.substr(0, pos);
        std::string value = line.substr(pos + 1);
        Trim(key);
        Trim(value);
        m_config_map[key] = value;
    }

    fclose(fp);
}

// 辅助函数:去除字符串首尾空格(内部使用)
void Trim(std::string& s) {
    size_t start = s.find_first_not_of(" \t\r\n");
    if (start == std::string::npos) {
        s = "";
        return;
    }
    size_t end = s.find_last_not_of(" \t\r\n");
    s = s.substr(start, end - start + 1);
}

// 3. 通用配置获取
std::string MprpcApplication::GetConfig(const std::string& key) {
    auto it = m_config_map.find(key);
    if (it == m_config_map.end()) {
        return "";
    }
    return it->second;
}

// 4. 便捷配置获取(封装类型转换)
std::string MprpcApplication::GetRpcServerIp() {
    return GetConfig("rpcserver_ip");
}

uint16_t MprpcApplication::GetRpcServerPort() {
    std::string port_str = GetConfig("rpcserver_port");
    return std::stoi(port_str);
}

std::string MprpcApplication::GetZkServerIp() {
    return GetConfig("zookeeper_ip");
}

uint16_t MprpcApplication::GetZkServerPort() {
    std::string port_str = GetConfig("zookeeper_port");
    return std::stoi(port_str);
}

// 5. 框架销毁(释放资源)
void MprpcApplication::Destroy() {
    // 释放日志资源、网络连接、zk客户端句柄等(可扩展)
    std::cout << "MprpcApplication destroy success!" << std::endl;
    if (m_instance != nullptr) {
        delete m_instance;
        m_instance = nullptr;
    }
}
3. 配置文件示例(config.conf)
复制代码
# RPC框架配置文件
# 服务器配置
rpcserver_ip=127.0.0.1
rpcserver_port=8080

# Zookeeper注册中心配置
zookeeper_ip=127.0.0.1
zookeeper_port=2181

# 日志配置(可扩展)
log_path=./log
log_level=info
4. 测试使用示例(main.cpp)
复制代码
#include "mprpcapplication.h"

int main(int argc, char** argv) {
    // 1. 初始化RPC框架(核心步骤)
    MprpcApplication::GetInstance().Init(argc, argv);

    // 2. 获取配置参数
    std::string rpc_ip = MprpcApplication::GetInstance().GetRpcServerIp();
    uint16_t rpc_port = MprpcApplication::GetInstance().GetRpcServerPort();
    std::cout << "=== 业务层获取配置 ===" << std::endl;
    std::cout << "RPC Server IP: " << rpc_ip << std::endl;
    std::cout << "RPC Server Port: " << rpc_port << std::endl;

    // 3. 运行RPC服务器/客户端逻辑(可扩展)
    // ...

    // 4. 销毁框架(程序退出前)
    MprpcApplication::GetInstance().Destroy();

    return 0;
}
四、核心设计要点解析
  1. 单例模式

    • 采用懒汉模式 + 双检锁,保证线程安全且延迟初始化;
    • 禁用拷贝 / 移动构造,避免多实例创建。
  2. 配置解析

    • 支持命令行参数-i指定配置文件,符合 Linux 程序习惯;
    • 解析key=value格式,忽略注释行和空行,兼容常见配置文件格式。
  3. 扩展性设计

    • 通用GetConfig接口兼容新增配置项;
    • 便捷接口(如GetRpcServerPort)封装类型转换,降低业务层使用成本;
    • Destroy函数预留资源释放接口,可扩展日志、网络、注册中心等资源释放。
  4. 错误处理

    • 初始化失败时直接退出并打印错误信息,避免框架带病运行;
    • 配置文件不存在 / 格式错误时友好提示。

五、扩展方向(工业级优化)

  1. 配置热更新 :添加ReloadConfig接口,支持不重启程序更新配置;
  2. 配置校验 :初始化时校验必填配置(如rpcserver_port必须是合法端口);
  3. 日志集成:整合你之前的日志系统,将框架日志写入指定路径;
  4. 注册中心初始化 :在Init中初始化 Zookeeper 客户端,封装到MprpcApplication
  5. 饿汉模式:若框架启动时必须初始化,可改为饿汉单例(提前创建实例)。

总结

  1. MprpcApplication是 RPC 框架的入口类,核心是单例管理 + 配置加载 + 全局参数访问
  2. 核心接口Init负责框架初始化,GetConfig/ 便捷接口负责参数获取,Destroy负责资源释放;
  3. 设计要点:线程安全的单例、灵活的配置解析、低耦合的扩展接口。

关键点回顾

  1. 单例模式:懒汉 + 双检锁,保证全局唯一且线程安全;
  2. 初始化流程:解析命令行参数 → 加载配置文件 → 初始化核心组件;
  3. 配置访问:通用接口兼容扩展,便捷接口降低使用成本。
相关推荐
Dreamboat_LX2 小时前
websocket-sockjs-stomp
网络·websocket·网络协议
txinyu的博客4 小时前
TCP的可靠性问题
网络·网络协议·tcp/ip
陌路204 小时前
RPC分布式通信(1)--分布式通信讲解
分布式·网络协议·rpc
西***63475 小时前
三大一体化音视频管理平台:技术特性与场景落地全解析
分布式
php_kevlin5 小时前
websocket实现站内信
android·websocket·网络协议
2401_865854886 小时前
ssl证书使用中可能会遇到的问题
网络·网络协议·ssl
少许极端6 小时前
Redis入门指南(六):从零到分布式缓存-数据持久化与事务
redis·分布式·缓存·事务·持久化
捷米研发三部6 小时前
CANopen 转 Modbus TCP:智能机床控制器与上位机监控系统的无缝对接方案
网络·网络协议
陈震_7 小时前
分布式解决方案
分布式