一、电商系统架构设计
本教程将基于ThinkPHP 6.1构建一个完整的电商平台,涵盖商品、订单、支付、秒杀等核心模块,并解决高并发场景下的技术挑战。
技术架构:
- 核心框架:ThinkPHP 6.1 + Swoole
- 前端架构:Vue3 + Vant
- 数据库:MySQL 8.0(主从分离)
- 缓存系统:Redis集群
- 消息队列:RabbitMQ
- 搜索引擎:Elasticsearch
核心业务模块:
- 分布式商品服务
- 高并发秒杀系统
- 多级订单系统
- 支付与结算系统
- 实时数据分析
二、项目初始化与微服务架构
1. 多应用项目初始化
# 创建ThinkPHP项目
composer create-project topthink/think tp-mall
# 安装多应用支持
composer require topthink/think-multi-app
# 目录结构调整
tp-mall/
├── app/
│ ├── product/ # 商品服务
│ ├── order/ # 订单服务
│ ├── payment/ # 支付服务
│ ├── user/ # 用户服务
│ └── common/ # 公共模块
├── extend/
│ ├── service/ # 微服务客户端
│ └── utils/ # 工具类
├── config/
├── route/
└── runtime/
# 配置数据库分库
// config/database.php
return [
'connections' => [
'product' => [
'type' => 'mysql',
'hostname' => '192.168.1.101',
'database' => 'mall_product',
// ...其他配置
],
'order' => [
'type' => 'mysql',
'hostname' => '192.168.1.102',
'database' => 'mall_order',
// ...其他配置
]
]
];
2. 微服务通信设计
// extend/service/RpcClient.php
namespace extendservice;
use thinkfacadeConfig;
class RpcClient
{
protected $serviceName;
protected $timeout = 5;
public function __construct($serviceName)
{
$this->serviceName = $serviceName;
}
public function call($method, $params = [])
{
$config = Config::get('microservice.' . $this->serviceName);
$url = $config['host'] . '/' . $method;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// 使用示例(商品服务调用)
$productService = new RpcClient('product');
$productInfo = $productService->call('product/getInfo', ['id' => 1001]);
三、高并发秒杀系统实现
1. 秒杀架构设计
// app/product/controller/Seckill.php
namespace appproductcontroller;
use thinkfacadeCache;
use thinkfacadeDb;
class Seckill
{
// 秒杀商品预热
public function preheat($productId)
{
$product = Db::name('product')
->where('id', $productId)
->find();
if (!$product || $product['stock'] handler();
$redis->set('seckill:stock:' . $productId, $product['stock']);
// 商品信息缓存
Cache::tag('seckill')->set('seckill:product:' . $productId, $product);
return true;
}
// 秒杀请求处理
public function seckill($productId, $userId)
{
$redis = Cache::store('redis')->handler();
$lockKey = 'seckill:lock:' . $productId;
// 分布式锁防止超卖
if (!$redis->set($lockKey, 1, ['nx', 'ex' => 5])) {
return ['code' => 0, 'msg' => '系统繁忙'];
}
try {
// 校验库存
$stockKey = 'seckill:stock:' . $productId;
$stock = $redis->decr($stockKey);
if ($stock incr($stockKey); // 恢复库存
return ['code' => 0, 'msg' => '已售罄'];
}
// 生成秒杀订单
$orderData = [
'user_id' => $userId,
'product_id' => $productId,
'status' => 0,
'create_time' => time()
];
// 异步处理订单
$rabbitmq = new extendserviceRabbitMQ();
$rabbitmq->publish('seckill_order', json_encode($orderData));
return ['code' => 1, 'msg' => '秒杀成功'];
} finally {
$redis->del($lockKey);
}
}
}
2. RabbitMQ消费者实现
// extend/service/RabbitMQ.php
namespace extendservice;
use PhpAmqpLibConnectionAMQPStreamConnection;
use PhpAmqpLibMessageAMQPMessage;
class RabbitMQ
{
protected $connection;
protected $channel;
public function __construct()
{
$config = config('rabbitmq');
$this->connection = new AMQPStreamConnection(
$config['host'],
$config['port'],
$config['user'],
$config['password']
);
$this->channel = $this->connection->channel();
}
// 消息发布
public function publish($queue, $message)
{
$this->channel->queue_declare($queue, false, true, false, false);
$msg = new AMQPMessage($message, ['delivery_mode' => 2]);
$this->channel->basic_publish($msg, '', $queue);
}
// 消息消费
public function consume($queue, $callback)
{
$this->channel->queue_declare($queue, false, true, false, false);
$this->channel->basic_qos(null, 1, null);
$this->channel->basic_consume($queue, '', false, false, false, false, $callback);
while ($this->channel->is_consuming()) {
$this->channel->wait();
}
}
public function __destruct()
{
$this->channel->close();
$this->connection->close();
}
}
// 订单消费者示例
$rabbitmq = new RabbitMQ();
$callback = function ($msg) {
$orderData = json_decode($msg->body, true);
// 处理订单逻辑
Db::connect('order')->name('order')->insert($orderData);
$msg->ack();
};
$rabbitmq->consume('seckill_order', $callback);
四、分布式事务处理
1. 订单创建事务方案
// app/order/service/OrderService.php
namespace apporderservice;
use thinkfacadeDb;
use extendserviceRpcClient;
class OrderService
{
public function createOrder($userId, $productId, $quantity)
{
// 1. 调用商品服务扣减库存
$productService = new RpcClient('product');
$result = $productService->call('product/reduceStock', [
'id' => $productId,
'quantity' => $quantity
]);
if ($result['code'] != 1) {
throw new Exception('库存不足');
}
// 2. 创建订单
Db::startTrans();
try {
$orderId = Db::name('order')->insertGetId([
'user_id' => $userId,
'product_id' => $productId,
'quantity' => $quantity,
'status' => 1,
'create_time' => time()
]);
// 3. 记录订单日志
Db::name('order_log')->insert([
'order_id' => $orderId,
'action' => 'create',
'create_time' => time()
]);
Db::commit();
return $orderId;
} catch (Exception $e) {
Db::rollback();
// 补偿:恢复库存
$productService->call('product/restoreStock', [
'id' => $productId,
'quantity' => $quantity
]);
throw $e;
}
}
}
2. 定时任务补偿机制
// app/command/CheckOrder.php
namespace appcommand;
use thinkconsoleCommand;
use thinkconsoleInput;
use thinkconsoleOutput;
use thinkfacadeDb;
class CheckOrder extends Command
{
protected function configure()
{
$this->setName('check:order')
->setDescription('检查未支付订单');
}
protected function execute(Input $input, Output $output)
{
// 查找30分钟未支付的订单
$time = time() - 1800;
$orders = Db::connect('order')
->name('order')
->where('status', 1)
->where('create_time', 'select();
foreach ($orders as $order) {
try {
Db::startTrans();
// 更新订单状态为已取消
Db::connect('order')
->name('order')
->where('id', $order['id'])
->update(['status' => 0]);
// 恢复商品库存
$productService = new extendserviceRpcClient('product');
$productService->call('product/restoreStock', [
'id' => $order['product_id'],
'quantity' => $order['quantity']
]);
Db::commit();
} catch (Exception $e) {
Db::rollback();
$output->writeln("订单{$order['id']}处理失败: " . $e->getMessage());
}
}
$output->writeln('订单检查完成');
}
}
// 配置定时任务
# crontab -e
*/5 * * * * cd /path/to/tp-mall && php think check:order
五、支付系统集成
1. 多支付渠道适配器
// app/payment/service/PaymentService.php
namespace apppaymentservice;
use apppaymentlibAlipay;
use apppaymentlibWechatPay;
use apppaymentlibUnionPay;
class PaymentService
{
protected $channel;
public function __construct($channel)
{
$this->channel = $channel;
}
public function pay($orderId, $amount)
{
switch ($this->channel) {
case 'alipay':
$payment = new Alipay(config('payment.alipay'));
break;
case 'wechat':
$payment = new WechatPay(config('payment.wechat'));
break;
case 'union':
$payment = new UnionPay(config('payment.union'));
break;
default:
throw new Exception('不支持的支付渠道');
}
return $payment->createOrder([
'order_id' => $orderId,
'amount' => $amount,
'notify_url' => url('/payment/notify/' . $this->channel)
]);
}
public function verifyNotify($data)
{
// 验证逻辑...
}
}
// 支付宝支付示例
$payment = new PaymentService('alipay');
$payUrl = $payment->pay($orderId, $amount);
2. 支付结果异步通知
// app/payment/controller/Notify.php
namespace apppaymentcontroller;
use thinkfacadeDb;
class Notify
{
public function alipay()
{
$data = $this->request->post();
$payment = new apppaymentservicePaymentService('alipay');
if (!$payment->verifyNotify($data)) {
return 'fail';
}
// 处理订单支付成功逻辑
Db::connect('order')->startTrans();
try {
// 更新订单状态
Db::connect('order')
->name('order')
->where('order_id', $data['out_trade_no'])
->update([
'status' => 2,
'pay_time' => time(),
'transaction_id' => $data['trade_no']
]);
// 记录支付日志
Db::connect('order')
->name('payment_log')
->insert([
'order_id' => $data['out_trade_no'],
'amount' => $data['total_amount'],
'channel' => 'alipay',
'create_time' => time()
]);
Db::commit();
return 'success';
} catch (Exception $e) {
Db::rollback();
return 'fail';
}
}
}
六、性能优化实战
1. Swoole HTTP服务
// 安装Swoole扩展
pecl install swoole
// 配置Swoole服务
// config/swoole.php
return [
'host' => '0.0.0.0',
'port' => 9501,
'options' => [
'worker_num' => 4,
'daemonize' => false,
'max_request' => 1000,
'dispatch_mode' => 2,
'enable_static_handler' => true,
'document_root' => public_path()
]
];
// 启动脚本
// swoole.php
use thinkswooleManager;
$manager = new Manager();
$manager->setConfig(config('swoole'));
$manager->start();
// 启动命令
php swoole.php start
// Nginx反向代理配置
location / {
proxy_pass http://127.0.0.1:9501;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2. 缓存与数据库优化
// 多级缓存策略
public function getProductInfo($productId)
{
$cacheKey = 'product:' . $productId;
// 1. 静态变量缓存
static $localCache = [];
if (isset($localCache[$cacheKey])) {
return $localCache[$cacheKey];
}
// 2. Redis缓存
$redis = Cache::store('redis')->handler();
$product = $redis->get($cacheKey);
if ($product) {
$localCache[$cacheKey] = json_decode($product, true);
return $localCache[$cacheKey];
}
// 3. 数据库查询
$product = Db::connect('product')
->name('product')
->where('id', $productId)
->find();
if ($product) {
// 写入缓存
$redis->set($cacheKey, json_encode($product), 3600);
$localCache[$cacheKey] = $product;
}
return $product;
}
// MySQL查询优化
// 1. 使用索引提示
Db::name('order')
->useIndex('idx_user_status')
->where('user_id', $userId)
->where('status', 1)
->select();
// 2. 大数据量分页优化
public function getOrderList($userId, $lastId = 0, $limit = 10)
{
return Db::name('order')
->where('user_id', $userId)
->where('id', '>', $lastId)
->order('id', 'asc')
->limit($limit)
->select();
}
七、安全防护策略
1. 接口安全防护
// 接口签名验证中间件
namespace appcommonmiddleware;
class ApiSign
{
public function handle($request, Closure $next)
{
$sign = $request->header('Sign');
$timestamp = $request->header('Timestamp');
// 验证时间戳(防止重放攻击)
if (abs(time() - $timestamp) > 300) {
return json(['code' => 403, 'msg' => '请求已过期']);
}
// 生成签名
$params = $request->param();
ksort($params);
$str = http_build_query($params) . '×tamp=' . $timestamp;
$realSign = md5($str . config('app.app_key'));
if ($realSign !== $sign) {
return json(['code' => 403, 'msg' => '签名错误']);
}
return $next($request);
}
}
// 使用示例
// 路由配置
Route::group('api', function() {
Route::get('product/list', 'api/product/list');
})->middleware(ApiSign::class);
2. XSS与CSRF防护
// XSS过滤中间件
namespace appcommonmiddleware;
class XssFilter
{
protected $filterFields = ['content', 'description'];
public function handle($request, Closure $next)
{
$input = $request->param();
array_walk_recursive($input, function(&$value, $key) {
if (in_array($key, $this->filterFields)) {
$value = htmlspecialchars($value, ENT_QUOTES);
}
});
$request->withParam($input);
return $next($request);
}
}
// CSRF防护配置
// config/middleware.php
return [
// 全局中间件
thinkmiddlewareSessionInit::class,
thinkmiddlewareCsrf::class => [
'except' => ['api/*'] // API接口除外
]
];
// 表单中使用CSRF令牌
<form action="/order/create" method="post">
<input type="hidden" name="__token__" value="{:token()}">
<!-- 其他表单字段 -->
</form>
八、总结与扩展
本教程构建了一个完整的电商系统:
- 设计了微服务架构
- 实现了高并发秒杀
- 解决了分布式事务
- 集成了支付系统
- 优化了系统性能
扩展方向:
- 大数据分析平台
- 智能推荐系统
- 物流跟踪系统
- 多商户支持
完整项目代码已开源:https://github.com/example/thinkphp-mall