首页 > 编程笔记 > C++笔记 阅读:2

微服务架构详解(附带C++实例)

微服务架构的引入是为了克服传统单体应用架构的不足。在单体应用中,所有功能都集成在一个大型应用程序中,这导致系统难以维护、扩展和部署。随着业务需求的变化和系统规模的增长,需要一种更加灵活、可扩展和可维护的架构模式来应对这些挑战。由此产生了微服务架构。

微服务架构核心思想

微服务架构的核心思想包括:

微服务架构中的角色

微服务通信流程如下图所示。


图 1 微服务通信流程

在一个典型的微服务架构中,微服务之间可以分为两种角色:
在实际的微服务架构中,一个微服务可能既是服务提供者,也是服务消费者。它可能提供某些服务供其他微服务调用,并同时调用其他微服务提供的服务来完成自己的业务逻辑。在这种情况下,一个微服务可能扮演着多种角色,形成复杂的服务网络。

C++实现微服务架构设计

在 C++ 程序中实现微服务架构的步骤与其他编程语言中的类似,主要包括以下几个方面:

微服务架构的C++实现案例

为了更好地理解实现微服务架构的流程,下面通过一个简单的示例来进行演示。我们将创建一个基于 C++ 和 ZeroMQ 库的微服务,用于处理用户管理的功能。这个示例将包括服务的初始化、启动、停止以及消息的处理:

1) 主函数部分

#include "Microservice.hpp"
#include <iostream>
#include <unordered_map> // 包含unordered_map用于保存用户信息,实际项目通常使用数据库
// 使用unordered_map来保存用户信息的简单数据库
std::unordered_map<std::string, std::string> userDatabase;
// 示例:创建用户服务
std::string createUser(const std::string& userInfo) {
    // 假设用户信息格式为 "UserID:UserName"
    std::size_t delimiterPos = userInfo.find(':');
    if (delimiterPos != std::string::npos) {
        std::string userId = userInfo.substr(0, delimiterPos);
        std::string userName = userInfo.substr(delimiterPos + 1);
        userDatabase[userId] = userName; // 将用户信息保存到内存中
        std::cout << "Creating user with ID: " << userId << " and name: " << userName <<
std::endl;
        std::cout << "User database size: " << userDatabase.size() << std::endl;
        // 返回保存成功的消息
        return "User created successfully";
    } else {
        return "Error: Invalid user information format";
    }
}
// 示例:获取用户信息服务
std::string getUserInfo(const std::string& userId) {
    auto it = userDatabase.find(userId);
    if (it != userDatabase.end()) {
        std::cout << "Getting user info for user with ID: " << userId << std::endl;
        // 返回相应的用户信息
        return "User info for user with ID " + userId + ": " + it->second;
    } else {
        std::cout << "User with ID " << userId << " not found" << std::endl;
        return "Error: User with ID " + userId + " not found";
    }
}
int main() {
    // 创建两个微服务实例
    Microservice createUserService("tcp://*:5555");
    Microservice getUserInfoService("tcp://*:5556");
    // 设置服务的消息处理回调函数
    createUserService.setCallback(createUser);
    getUserInfoService.setCallback(getUserInfo);
    // 启动服务
    createUserService.start();
    getUserInfoService.start();
    // 等待服务运行
    std::cout << "Services are running..." << std::endl;
    std::cin.get();
    // 停止服务
    createUserService.stop();
    getUserInfoService.stop();
    return 0;
}
在示例中,主函数首先创建并启动两个微服务实例,一个用于创建用户,另一个用于获取用户信息。然后,它设置了每个服务的消息处理回调函数,并启动了这两个服务。最后,它等待用户输入以保持服务的运行,并在用户输入后停止服务。

2) 服务提供者类的定义

#ifndef MICROSERVICE_H
#define MICROSERVICE_H

#include <zmq.hpp>
#include <string>
#include <functional>
#include <thread> // 用于多线程
#include <iostream>

class Microservice {
public:
    // 构造函数,初始化ZeroMQ上下文和套接字,设置服务端点
    Microservice(const std::string& endpoint) : context_(1), socket_(context_, ZMQ_REP), endpoint_(endpoint) {}

    // 析构函数,关闭套接字和上下文
    ~Microservice() {
        socket_.close();
        context_.close();
    }

    // 启动服务
    void start() {
        // 绑定到指定的端点
        socket_.bind(endpoint_);

        // 创建一个线程来处理消息
        std::thread t(&Microservice::handleMessages, this);
        t.detach(); // 分离线程,使得主线程可以继续执行
    }

    // 停止服务
    void stop() {
        // 关闭套接字
        socket_.close();
    }

    // 设置消息处理回调函数
    void setCallback(std::function<std::string(const std::string&)> callback) {
        callback_ = callback;
    }

private:
    zmq::context_t context_; // ZeroMQ 上下文
    zmq::socket_t socket_;   // ZeroMQ 套接字
    std::string endpoint_;   // 服务端点
    std::function<std::string(const std::string&)> callback_; // 消息处理回调函数

    // 处理接收到的消息
    void handleMessages() {
        while (true) {
            // 接收消息
            zmq::message_t request;
            // 接收消息,并检查返回值
            zmq::recv_result_t result = socket_.recv(request, zmq::recv_flags::none);
            if (result.has_value()) {
                // std::cout << "Received message: " << std::string(static_cast<char*>(request.data()), request.size()) << std::endl;
            } else {
                std::cout << "Error receiving message: " << zmq_strerror(zmq_errno()) << std::endl;
            }

            // 转换消息为字符串
            std::string message = std::string(static_cast<char*>(request.data()), request.size());
            std::string response;
            // 调用回调函数处理消息
            if (callback_) {
                response = callback_(message);
            } else {
                response = "Error: No callback function set";
            }
            zmq::message_t reply(response.size());
            memcpy(reply.data(), response.data(), response.size());
            // 发送消息,并指定发送标志为默认值
            socket_.send(reply, zmq::send_flags::none);
        }
    }
};

#endif // MICROSERVICE_H
Microservice 类是我们定义的一个简单的微服务类,包含了服务的初始化、启动、停止以及消息处理等方法。在这个类中,使用了 ZeroMQ 库来实现服务之间的通信,同时提供了一个回调函数来处理接收到的消息。

3) 服务消费者类的定义

#include <zmq.hpp>
#include <string>
#include <iostream>
int main() {
    // 创建 ZeroMQ 上下文和套接字
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REQ);
    // 连接到创建用户服务
    socket.connect("tcp://localhost:5555");
    // 向创建用户服务发送请求
    std::string message = "1127:NewUsercc"; // 假设要创建的用户信息为 "UserID:UserName"
    zmq::message_t request(message.size());
    memcpy(request.data(), message.data(), message.size());
    if (!socket.send(request, zmq::send_flags::none)) { // 检查send函数的返回值
        std::cerr << "Failed to send message to create user service" << std::endl;
        return 1;
    }
    // 接收并打印创建用户服务的响应
    zmq::message_t reply;
    if (!socket.recv(reply, zmq::recv_flags::none)) { // 检查recv函数的返回值
        std::cerr << "Failed to receive reply from create user service" << std::endl;
        return 1;
    }
    std::string replyMessage = std::string(static_cast<char*>(reply.data()), reply.size());
    std::cout << "Received reply from create user service: " << replyMessage << std::endl;
    // 关闭与创建用户服务的连接
    socket.disconnect("tcp://localhost:5555");
    // 连接到获取用户信息服务
    socket.connect("tcp://localhost:5556");
    // 向获取用户信息服务发送请求
    message = "1127"; // 假设要获取的用户ID为1127
    request = zmq::message_t(message.size());
    memcpy(request.data(), message.data(), message.size());
    if (!socket.send(request, zmq::send_flags::none)) { // 检查send函数的返回值
        std::cerr << "Failed to send message to get user info service" << std::endl;
        return 1;
    }
    // 接收并打印获取用户信息服务的响应
    if (!socket.recv(reply, zmq::recv_flags::none)) { // 检查recv函数的返回值
        std::cerr << "Failed to receive reply from get user info service" << std::endl;
        return 1;
    }
    replyMessage = std::string(static_cast<char*>(reply.data()), reply.size());
    std::cout << "Received reply from get user info service: " << replyMessage << std::endl;
    // 关闭套接字和上下文
    socket.close();
    context.close();
    return 0;
}
服务消费者类负责调用之前创建的两个微服务。它需要知道服务的端点信息以及如何发送和接收消息。在本例中,服务消费者类使用 ZeroMQ 库来实现与微服务之间的通信,并调用相应的服务接口来完成用户的创建和获取用户信息的操作。

微服务架构示例中,通过使用 ZeroMQ 库实现服务消费者和服务提供者之间的通信,我们展示了如何在分布式环境中有效地管理服务调用和数据交换。这种架构优化了服务的独立性和可扩展性,使得各个服务可以灵活地部署和维护。

相关文章