说一个好消息,C++那些事开源项目4w star了!
开源项目地址:https://github.com/Light-City/CPlusPlusThings
网站:可以点击阅读原文
或者:
https://light-city.github.io/stories_things/
gRPC 实战篇:从零打造库存管理系统
目录
一、项目背景
二、如何设计 Protobuf
核心代码 (inventory.proto)
三、如何编写 CMake 构建 gRPC
CMakeLists.txt(精简版)
四、如何实现库存管理系统
1. 初始化数据
2. 添加商品 (AddProduct)
3. 更新库存 (UpdateQuantity)
4. 创建订单 (CreateOrder)
五、后续还能做什么
六、运行!
最近有小伙伴留言想学习后端开发,尤其是 gRPC 这样前沿的技术。趁着这个机会,我们更新一篇实战教程,带你从设计到实现,打造一个高效的库存管理系统。目标很明确:
如何设计 Protobuf:定义清晰的服务和数据结构
如何编写 CMake 构建 gRPC:快速编译项目
如何实现库存管理系统:核心功能落地
后续还能做什么:扩展你的创意
准备好了吗?让我们动手开干!
演示Demo:
启动服务
客户端连接
执行一些操作,比如:展示库存,添加商品等。
注:懒人版,完整代码已更新至星球。
一、项目背景
gRPC 是 Google 推出的高性能 RPC 框架,基于 HTTP/2 和 Protocol Buffers(Protobuf),特别适合微服务和分布式系统。我们将用它实现一个库存管理系统,支持添加商品、查询库存等功能,有了这些功能是不是一个典型的电商项目出来了,哈哈。项目结构如下:
├── main.cpp
└── src
├── client/client.cpp
├── proto/inventory.proto
└── server
├── inventory_service_impl.cpp
├── inventory_service_impl.h
└── server.cpp
二、如何设计 Protobuf
Protobuf 是 gRPC 的核心,负责定义服务接口和数据结构。设计时要简洁、明确,并考虑扩展性。
核心代码 (inventory.proto)
根据功能来设计:比如需要包含:添加新商品、更新库存、获取detail、列出哪些商品、创建订单等,那么就可以设计出这些rpc。
// 库存管理服务
service InventoryService {
// 添加新商品
rpc AddProduct(Product) returns (Product);
// 更新库存数量
rpc UpdateQuantity(UpdateQuantityRequest) returns (UpdateQuantityResponse);
// 获取商品信息
rpc GetProduct(ProductQuery) returns (Product);
// 列出商品
rpc ListProducts(ProductQuery) returns (ProductList);
// 创建订单
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
// 获取订单信息
rpc GetOrder(OrderQuery) returns (Order);
}
三、如何编写 CMake 构建 gRPC
CMake 是跨平台的构建工具,我们用它来编译 Protobuf 和 gRPC 代码。以下是核心配置:
CMakeLists.txt(精简版)
cmake_minimum_required(VERSION 3.10)
project(InventorySystem)
# 设置 C++17
set(CMAKE_CXX_STANDARD 17)
# 查找 gRPC 和 Protobuf
find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)
# Protobuf 文件
set(PROTO_FILE "src/proto/inventory.proto")
set(GENERATED_DIR "${CMAKE_BINARY_DIR}/generated")
file(MAKE_DIRECTORY ${GENERATED_DIR})
# 生成代码
set(PROTO_SRC "${GENERATED_DIR}/inventory.pb.cc")
set(GRPC_SRC "${GENERATED_DIR}/inventory.grpc.pb.cc")
add_custom_command(
OUTPUT ${PROTO_SRC} ${GRPC_SRC}
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
ARGS --grpc_out=${GENERATED_DIR} --cpp_out=${GENERATED_DIR}
-I src/proto --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
${PROTO_FILE}
DEPENDS ${PROTO_FILE}
)
# 编译服务器
add_executable(server
${PROTO_SRC} ${GRPC_SRC}
src/server/server.cpp
src/server/inventory_service_impl.cpp
)
target_link_libraries(server gRPC::grpc++ protobuf::libprotobuf)
# 编译客户端
add_executable(client
${PROTO_SRC} ${GRPC_SRC}
src/client/client.cpp
)
target_link_libraries(client gRPC::grpc++ protobuf::libprotobuf)
关键点:
用
add_custom_command
生成 Protobuf 和 gRPC 代码。链接
gRPC::grpc++
和protobuf::libprotobuf
库。分开编译
server
和client
。
运行 cmake .. && make
,即可生成 server
和 client
可执行文件。
四、如何实现库存管理系统
1. 初始化数据
InventoryServiceImpl::InventoryServiceImpl() : next_product_id_(1), next_order_id_(1) {
inventory::Product p1;
p1.set_id(next_product_id_++); // 自增ID
p1.set_name("笔记本电脑");
p1.set_price(5999.99);
p1.set_quantity(50);
products_[p1.id()] = p1; // 存入 map
}
要点:用 map
存储商品,初始化样例数据。
2. 添加商品 (AddProduct)
grpc::Status InventoryServiceImpl::AddProduct(grpc::ServerContext* context,
const inventory::Product* request,
inventory::Product* response) {
std::lock_guard<std::mutex> lock(mutex_);
inventory::Product new_product;
new_product.set_id(next_product_id_++);
new_product.set_name(request->name());
new_product.set_price(request->price());
new_product.set_quantity(request->quantity());
products_[new_product.id()] = new_product;
*response = new_product;
return grpc::Status::OK;
}
要点:线程安全添加商品,返回新商品信息。
3. 更新库存 (UpdateQuantity)
grpc::Status InventoryServiceImpl::UpdateQuantity(grpc::ServerContext* context,
const inventory::UpdateQuantityRequest* request,
inventory::UpdateQuantityResponse* response) {
std::lock_guard<std::mutex> lock(mutex_);
int32_t product_id = request->product_id();
if (products_.find(product_id) == products_.end()) {
response->set_success(false);
return grpc::Status::OK;
}
inventory::Product& product = products_[product_id];
int32_t new_quantity = product.quantity() + request->quantity_change();
if (new_quantity < 0) {
response->set_success(false);
return grpc::Status::OK;
}
product.set_quantity(new_quantity);
response->set_success(true);
response->set_new_quantity(new_quantity);
return grpc::Status::OK;
}
要点:检查库存是否足够,更新并返回结果。
4. 创建订单 (CreateOrder)
grpc::Status InventoryServiceImpl::CreateOrder(grpc::ServerContext* context,
const inventory::CreateOrderRequest* request,
inventory::CreateOrderResponse* response) {
std::lock_guard<std::mutex> lock(mutex_);
inventory::Order order;
order.set_order_id(next_order_id_++);
order.set_customer_id(request->customer_id());
double total_price = 0.0;
for (constauto& item : request->items()) {
int32_t product_id = item.product_id();
int32_t quantity = item.quantity();
if (products_[product_id].quantity() < quantity) {
response->set_success(false);
return grpc::Status::OK;
}
total_price += products_[product_id].price() * quantity;
products_[product_id].set_quantity(products_[product_id].quantity() - quantity);
}
order.set_total_price(total_price);
orders_[order.order_id()] = order;
response->set_success(true);
*response->mutable_order() = order;
return grpc::Status::OK;
}
要点:检查库存,计算总价,创建订单并更新库存。
完整实现(包括查询功能等)请加入“星球”查看!
五、后续还能做什么
这个项目只是起点,你可以尝试:
数据库集成:用 MySQL 或 Redis 替换
map
,实现持久化。订单管理:扩展 Protobuf,添加订单服务。
认证授权:集成 gRPC 的 TLS 或 token 认证。
监控系统:添加日志和库存预警功能。
多语言支持:用 Python 或 Java 写客户端。
六、运行!
安装依赖:gRPC、Protobuf、CMake。
编译运行:
mkdir build && cd build cmake .. && make ./server # 启动服务器 ./client # 启动客户端
本节完
(完)
学习更多干货,欢迎关注转发!