Lua: 事件处理深度解析之从协程到跨平台架构实践

Lua事件处理基础概念

1 ) 事件驱动编程模型

Lua作为一种轻量级脚本语言,在事件处理方面具有独特的优势。

事件驱动编程是一种编程范式,其中程序的流程由外部事件(如用户操作、传感器输入、网络消息等)决定

2 ) Lua在事件处理中的优势

  • 轻量级特性:Lua内核小于120KB,启动速度快,非常适合嵌入到其他程序中进行事件处理
  • 高效协程支持:Lua原生支持协程,为异步事件处理提供了强大基础
  • 灵活的回调机制:通过闭包和函数引用实现灵活的事件回调

Lua中的回调机制实现

1 ) 基础回调函数

lua 复制代码
-- 定义事件处理器 
function eventHandler(eventType, data)
    print("处理事件:", eventType, "数据:", data)
end 
 
-- 事件注册器 
local eventRegistry = {}
 
function registerEvent(eventName, handler)
    eventRegistry[eventName] = handler 
end 
 
-- 触发事件 
function triggerEvent(eventName, ...)
    local handler = eventRegistry[eventName]
    if handler then 
        handler(...)
    end 
end 
 
-- 使用示例 
registerEvent("click", eventHandler)
triggerEvent("click", "button1", {x=100, y=200})

2 ) 闭包实现事件回调

在Bolt等框架中,闭包是实现事件回调的常用技巧,允许回调函数访问外部作用域的变量

lua 复制代码
-- 使用闭包创建带状态的事件处理器 
function createClickHandler(buttonId)
    local clickCount = 0 
    
    return function(x, y)
        clickCount = clickCount + 1 
        print(string.format("按钮%s被点击,位置:(%d,%d),点击次数:%d", 
              buttonId, x, y, clickCount))
    end 
end 
 
-- 注册不同按钮的处理器 
local button1Handler = createClickHandler("按钮1")
local button2Handler = createClickHandler("按钮2")
 
-- 模拟点击事件 
button1Handler(10, 20)  -- 输出: 按钮1被点击,位置:(10,20),点击次数:1 
button1Handler(15, 25)  -- 输出: 按钮1被点击,位置:(15,25),点击次数:2 
button2Handler(30, 40)  -- 输出: 按钮2被点击,位置:(30,40),点击次数:1 

协程与事件循环

1 )Lua协程基础

Lua支持协程(协同式多线程),为事件处理提供了强大的异步能力

ts 复制代码
-- 协程示例:异步事件处理 
function asyncEventProcessor()
    local co = coroutine.create(function()
        while true do 
            local event = coroutine.yield() -- 等待事件 
            print("异步处理事件:", event)
            
            -- 模拟耗时操作 
            for i = 1, 3 do 
                print("处理中...", i)
                coroutine.yield() -- 让出控制权 
            end 
            
            print("事件处理完成")
        end 
    end)
    return co 
end 
 
-- 事件循环 
local processor = asyncEventProcessor()
coroutine.resume(processor) -- 启动协程 
 
-- 模拟事件队列 
local eventQueue = {"event1", "event2", "event3"}
 
for _, event in ipairs(eventQueue) do 
    coroutine.resume(processor, event)
end 

2 ) 尾调用优化

Lua支持尾调用消除,这在递归事件处理中非常重要,可以避免堆栈溢出

lua 复制代码
-- 尾递归事件处理器 
function processEventRecursive(events, index)
    index = index or 1 
    
    if index > #events then 
        return "处理完成"
    end 
    
    print("处理事件:", events[index])
    return processEventRecursive(events, index + 1) -- 尾调用 
end 
 
local events = {"click", "keydown", "mousemove"}
local result = processEventRecursive(events)
print(result)

Lua事件处理的核心机制

1 ) 协程(Coroutine)基础

Lua通过非对称协程实现事件调度,关键API:

lua 复制代码
local co = coroutine.create(function()
  while true do
    local event = coroutine.yield()  -- 挂起协程等待事件
    print("处理事件:", event)
  end
end)
coroutine.resume(co, "start")  -- 触发事件
coroutine.resume(co, "data_received")
  • yield():暂停执行并返回事件数据
  • resume():传递事件恢复协程

2 )libUV事件循环集成

通过 Luvit 框架(Lua+libUV)实现高性能I/O

lua 复制代码
local uv = require('uv')
uv.new_timer():start(1000, 1000, function()
  print("定时事件触发")
end)
uv.run()  -- 启动事件循环

事件系统架构设计

1 ) 事件调度器核心实现

lua 复制代码
local EventEmitter = {
  listeners = {}
}

function EventEmitter:on(event, callback)
  self.listeners[event] = self.listeners[event] or {}
  table.insert(self.listeners[event], callback)
end

function EventEmitter:emit(event, ...)
  for _, callback in ipairs(self.listeners[event] or {}) do
    coroutine.resume(coroutine.create(callback), ...)
  end
end

4 ) 跨线程事件(使用lua-threads)

lua 复制代码
local thread = require("thread")
local worker = thread.new(function()
  --- 子线程处理耗时操作
  return compute_result()
end)
worker:join()  -- 事件同步点

与NestJS事件架构对比

1 ) NestJS事件驱动模型

基于观察者模式的装饰器实现:

typescript 复制代码
import { EventEmitter } from 'events';
const emitter = new EventEmitter();

// 事件监听
@OnEvent('data')
handleData(payload: string) {
  console.log(Received: ${payload});
}

// 事件触发
emitter.emit('data', 'NestJS事件数据');

2 ) Lua与Node.js的协作模式

通过LuaNode桥接实现混合事件循环

javascript 复制代码
const lua = require('lua_vm');
lua.exec(`
  local js = require("js")
  js.global:emit("luaEvent", {data="from Lua"})
`);

事件系统核心实现

1 ) 事件管理器基础架构

lua 复制代码
-- 事件管理器类定义
local EventManager = {}
EventManager.__index = EventManager
 
function EventManager:new()
    local obj = {
        listeners = {},  -- 存储事件监听器
        eventQueue = {}, -- 事件队列
        maxQueueSize = 1000 -- 最大队列大小 
    }
    setmetatable(obj, EventManager)
    return obj
end 
 
-- 注册事件监听器 
function EventManager:on(event, callback, priority)
    if not self.listeners[event] then
        self.listeners[event] = {}
    end
    
    priority = priority or 0
    table.insert(self.listeners[event], {callback = callback, priority = priority})
    
    -- 按优先级排序
    table.sort(self.listeners[event], function(a, b)
        return a.priority > b.priority
    end)
end 
 
-- 触发事件 
function EventManager:emit(event, ...)
    if self.listeners[event] then 
        for _, listener in ipairs(self.listeners[event]) do
            local success, err = pcall(listener.callback, ...)
            if not success then
                print("Event callback error: " .. tostring(err))
            end 
        end
    end
end 
 
-- 移除事件监听器
function EventManager:off(event, callback)
    if self.listeners[event] then 
        for i, listener in ipairs(self.listeners[event]) do
            if listener.callback == callback then
                table.remove(self.listeners[event], i)
                break
            end
        end
    end
end

2 ) 事件队列管理

lua 复制代码
-- 异步事件队列实现
function EventManager:queueEvent(event, ...)
    table.insert(self.eventQueue, {event = event, args = {...}})
    if #self.eventQueue > self.maxQueueSize then
        table.remove(self.eventQueue, 1) -- 移除最旧的事件 
    end
end
 
-- 处理队列中的事件
function EventManager:processQueue()
    local queueSize = #self.eventQueue
    for i = 1, queueSize do
        local eventInfo = table.remove(self.eventQueue, 1)
        self:emit(eventInfo.event, unpack(eventInfo.args))
    end
end 

高级特性实现

1 ) 事件过滤与条件触发

lua 复制代码
-- 带条件的事件监听
function EventManager:onCondition(event, condition, callback)
    local wrappedCallback = function(...)
        local args = {...}
        if condition(unpack(args)) then
            callback(unpack(args))
        end
    end 
    self:on(event, wrappedCallback)
end
 
-- 一次性事件监听
function EventManager:once(event, callback)
    local wrappedCallback = function(...)
        self:off(event, wrappedCallback)
        callback(...)
    end
    self:on(event, wrappedCallback)
end 

2 ) 事件上下文管理

lua 复制代码
-- 事件上下文类
local EventContext = {}
EventContext.__index = EventContext
 
function EventContext:new(data)
    local obj = {
        data = data or {},
        cancelled = false,
        stopPropagation = false
    }
    setmetatable(obj, EventContext)
    return obj
end 
 
function EventContext:cancel()
    self.cancelled = true 
end
 
function EventContext:stopPropagation()
    self.stopPropagation = true
end 

NestJS集成方案

1 ) NestJS服务与Lua脚本通信

ts 复制代码
// lua-event.service.ts
import { Injectable } from '@nestjs/common';
import * as lua from 'lua.vm';
 
@Injectable()
export class LuaEventService {
  private luaVM: any;
  private eventManager: any;
 
  constructor() {
    this.initializeLuaVM();
  }
 
  private initializeLuaVM() {
    this.luaVM = new lua.Lua();
    
    // 注册事件相关函数到Lua环境
    this.luaVM.global.set('registerEvent', (event: string, callback: Function) => {
      this.registerEventCallback(event, callback);
    });
    
    this.luaVM.global.set('emitEvent', (event: string, data: any) => {
      this.emitEvent(event, data);
    });
    
    this.luaVM.global.set('processQueue', () => {
      this.processEventQueue();
    });
  }
 
  async executeLuaScript(script: string) {
    try {
      return await this.luaVM.doString(script);
    } catch (error) {
      console.error('Lua script error:', error);
      throw error;
    }
  }
 
  registerEventCallback(event: string, callback: Function) {
    // 在NestJS中注册事件回调
    this.eventManager.on(event, callback);
  }
 
  emitEvent(event: string, data: any) {
    // 触发NestJS事件
    this.eventManager.emit(event, data);
  }
 
  processEventQueue() {
    // 处理事件队列
    this.eventManager.processQueue();
  }
}

2 ) 事件处理控制器

ts 复制代码
// event.controller.ts
import { Controller, Post, Get, Body } from '@nestjs/common';
import { LuaEventService } from './lua-event.service';
 
@Controller('events')
export class EventController {
  constructor(private readonly luaEventService: LuaEventService) {}
 
  @Post('execute-script')
  async executeScript(@Body('script') script: string) {
    try {
      const result = await this.luaEventService.executeLuaScript(script);
      return { success: true, result };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
 
  @Post('trigger-event')
  async triggerEvent(@Body() eventData: { event: string; data: any }) {
    this.luaEventService.emitEvent(eventData.event, eventData.data);
    return { message: 'Event triggered successfully' };
  }
 
  @Get('queue-status')
  getQueueStatus() {
    // 获取事件队列状态
    return { queueSize: this.luaEventService.getQueueSize() };
  }
}

NestJS中的事件处理对比

1 ) NestJS事件系统基础

ts 复制代码
// nestjs-event.module.ts 
import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { EventService } from './event.service';
import { EventController } from './event.controller';
 
@Module({
  imports: [EventEmitterModule.forRoot()],
  providers: [EventService],
  controllers: [EventController],
})
export class EventModule {}

2 ) NestJS事件监听器

lua 复制代码
// nestjs-event.service.ts 
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
 
@Injectable()
export class EventService {
  @OnEvent('user.created')
  handleUserCreatedEvent(payload: UserCreatedEvent) {
    console.log('用户创建事件:', payload);
    // 处理用户创建后的逻辑 
  }
 
  @OnEvent('order.completed')
  handleOrderCompletedEvent(payload: OrderCompletedEvent) {
    console.log('订单完成事件:', payload);
    // 发送通知、更新库存等 
  }
 
  @OnEvent('system.error')
  handleSystemError(payload: SystemErrorEvent) {
    console.error('系统错误:', payload);
    // 记录日志、发送告警 
  }
}

3 ) NestJS事件发射器

ts 复制代码
// nestjs-event.controller.ts 
import { Controller, Post, Body } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
 
@Controller('events')
export class EventController {
  constructor(private eventEmitter: EventEmitter2) {}
 
  @Post('user')
  createUser(@Body() userData: CreateUserDto) {
    // 创建用户逻辑 
    const user = { id: 1, name: userData.name, email: userData.email };
    
    // 发射用户创建事件 
    this.eventEmitter.emit('user.created', {
      userId: user.id,
      timestamp: new Date(),
    });
    
    return { success: true, user };
  }
 
  @Post('order')
  completeOrder(@Body() orderData: CreateOrderDto) {
    // 处理订单逻辑 
    const order = { id: 1, items: orderData.items, total: orderData.total };
    
    // 发射订单完成事件 
    this.eventEmitter.emit('order.completed', {
      orderId: order.id,
      total: order.total,
      timestamp: new Date(),
    });
    
    return { success: true, order };
  }
}

Lua Web开发中的事件处理(Luvit框架)

1 ) Luvit框架介绍

Luvit是Lua的Node.js等效框架,结合了Lua、libUV和LuaJIT,提供异步I/O和事件驱动能力

lua 复制代码
-- Luvit HTTP服务器示例 
local http = require('http')
 
-- 创建HTTP服务器 
local server = http.createServer(function(req, res)
    -- 路由事件处理 
    if req.path == "/api/events" then 
        handleEventsAPI(req, res)
    elseif req.path == "/api/data" then 
        handleDataAPI(req, res)
    else 
        res:setStatusCode(404)
        res:finish("Not Found")
    end 
end)
 
-- 事件API处理器 
function handleEventsAPI(req, res)
    local body = ""
    
    req:on('data', function(chunk)
        body = body .. chunk -- 数据事件 
    end)
    
    req:on('end', function()
        -- 请求完成事件 
        local eventData = JSON.decode(body)
        processEvent(eventData)
        
        res:setHeader("Content-Type", "application/json")
        res:finish(JSON.encode({status = "success"}))
    end)
end 
 
-- 启动服务器 
server:listen(8080)
print("服务器运行在 http://localhost:8080")

2 ) 事件发射器模式

lua 复制代码
-- 自定义事件发射器 
local EventEmitter = require('events').EventEmitter 
 
local myEmitter = EventEmitter:new()
 
-- 注册事件监听器 
myEmitter:on('userAction', function(action, data)
    print("用户操作:", action, "数据:", JSON.encode(data))
end)
 
myEmitter:on('systemEvent', function(eventType)
    print("系统事件:", eventType)
end)
 
-- 发射事件 
myEmitter:emit('userAction', 'click', {button = 'submit', timestamp = os.time()})
myEmitter:emit('systemEvent', 'startup')

实际应用案例:游戏事件系统

游戏事件系统架构

lua 复制代码
-- 游戏事件系统 
local GameEventSystem = {}
 
-- 事件类型定义 
local EventTypes = {
    PLAYER_MOVE = "player_move",
    PLAYER_ATTACK = "player_attack",
    ITEM_PICKUP = "item_pickup",
    LEVEL_COMPLETE = "level_complete"
}
 
-- 事件监听器注册表 
local listeners = {}
 
-- 注册事件监听器 
function GameEventSystem.addEventListener(eventType, listener)
    if not listeners[eventType] then 
        listeners[eventType] = {}
    end 
    table.insert(listeners[eventType], listener)
end 
 
-- 移除事件监听器 
function GameEventSystem.removeEventListener(eventType, listener)
    if listeners[eventType] then 
        for i, l in ipairs(listeners[eventType]) do 
            if l == listener then 
                table.remove(listeners[eventType], i)
                break 
            end 
        end 
    end 
end 
 
-- 分发事件 
function GameEventSystem.dispatchEvent(eventType, eventData)
    if listeners[eventType] then 
        for _, listener in ipairs(listeners[eventType]) do 
            -- 使用pcall确保单个监听器错误不影响其他监听器 
            local success, err = pcall(listener, eventData)
            if not success then 
                print("事件处理错误:", err)
            end 
        end 
    end 
end 
 
-- 游戏对象示例 
local Player = {}
 
function Player:new(x, y)
    local obj = {x = x, y = y, health = 100}
    setmetatable(obj, {__index = self})
    return obj 
end 
 
function Player:moveTo(newX, newY)
    local oldX, oldY = self.x, self.y 
    self.x, self.y = newX, newY 
    
    -- 发射移动事件 
    GameEventSystem.dispatchEvent(EventTypes.PLAYER_MOVE, {
        player = self,
        from = {x = oldX, y = oldY},
        to = {x = newX, y = newY}
    })
end 
 
function Player:attack(target)
    -- 发射攻击事件 
    GameEventSystem.dispatchEvent(EventTypes.PLAYER_ATTACK, {
        attacker = self,
        target = target,
        damage = 10 
    })
end 
 
-- 使用示例 
local player = Player:new(0, 0)
 
-- 注册事件监听器 
GameEventSystem.addEventListener(EventTypes.PLAYER_MOVE, function(data)
    print(string.format("玩家从(%d,%d)移动到(%d,%d)", 
          data.from.x, data.from.y, data.to.x, data.to.y))
end)
 
GameEventSystem.addEventListener(EventTypes.PLAYER_ATTACK, function(data)
    print(string.format("%s攻击了%s,造成%d点伤害", 
          data.attacker, data.target, data.damage))
end)
 
-- 模拟游戏行为 
player:moveTo(10, 20)
player:attack("怪物")

Lua与NestJS事件处理对比分析

1 ) 特性对比表

特性 Lua NestJS
事件模型 回调函数、协程、事件发射器 观察者模式、装饰器
异步处理 协程、libuv(Luvit) Promise、RxJS
类型安全 动态类型 TypeScript静态类型
性能 轻量级、启动快 较重但功能丰富
生态系统 嵌入式、游戏开发 企业级Web应用
学习曲线 简单易学 相对复杂

或参考

特性 传统事件系统 Lua事件系统 优势
灵活性 固定逻辑 可编程扩展 支持动态逻辑
性能 高效 中等 脚本开销存在
热更新 需重启 支持脚本重载 无需重启服务
调试 静态调试 脚本调试 独立调试能力
资源占用 中等 内存开销增加

2 ) 集成方案

在需要同时使用Lua和NestJS的项目中,可以通过以下方式集成:

typescript 复制代码
// nestjs-lua-bridge.service.ts 
import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
 
@Injectable()
export class LuaBridgeService {
  constructor(private eventEmitter: EventEmitter2) {}
 
  // 从Lua脚本执行并处理事件 
  async executeLuaScript(script: string, eventData: any) {
    // 使用lua-in-nodejs或其他Lua解释器 
    const lua = require('lua-in-nodejs');
    const state = lua.createState();
    
    // 设置Lua环境中的事件回调函数 
    state.doString(
      function emitEvent(eventName, data)
这里通过某种桥接机制调用NestJS事件系统 
      end 
    );
    
    // 执行Lua脚本 
    const result = state.doString(script);
    
    // 发射事件到NestJS 
    this.eventEmitter.emit('lua.script.executed', {
      script: script,
      result: result,
      timestamp: new Date()
    });
    
    return result;
  }
}

最佳实践与性能优化

1 ) Lua事件处理最佳实践

  1. 避免事件监听器泄漏:及时移除不需要的监听器
  2. 使用协程处理耗时操作:避免阻塞主线程
  3. 错误隔离:使用pcall确保单个监听器错误不影响系统
  4. 事件去重:避免重复处理相同事件
lua 复制代码
-- 事件管理器最佳实践 
local EventManager = {}
 
function EventManager:new()
    local obj = {
        listeners = {},
        eventHistory = {},
        maxHistory = 100 
    }
    setmetatable(obj, {index = self})
    return obj 
end 
-- 带去重功能的事件分发 
function EventManager:dispatchEvent(eventType, eventData)
    local eventKey = eventType .. "_" .. (eventData.id or "")
	-- 检查是否已处理过相同事件 
    if self.eventHistory[eventKey] then 
        return false -- 事件已处理 
    end 
	-- 记录事件历史 
    self.eventHistory[eventKey] = true 
	-- 清理旧的历史记录 
    if #self.eventHistory > self.maxHistory then 
        self.eventHistory = {}
    end 
	-- 分发事件 
    if self.listeners[eventType] then 
        for _, listener in ipairs(self.listeners[eventType]) do 
            local success, err = pcall(listener, eventData)
            if not success then 
                print("事件处理错误:", err)
            end 
        end 
    end 
    
    return true 
end 

2 ) NestJS事件处理最佳实践

typescript 复制代码
// nestjs-event-optimization.service.ts 
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { Observable, from } from 'rxjs';
import { mergeMap, timeout, catchError } from 'rxjs/operators';
 
@Injectable()
export class EventOptimizationService {
  // 异步事件处理 
  @OnEvent('heavy.task')
  async handleHeavyTask(payload: HeavyTaskEvent): Promise<void> {
    from(this.processHeavyTask(payload))
      .pipe(
        timeout(30000), // 30秒超时 
        catchError(error => {
          console.error('重任务处理失败:', error);
          return [];
        })
      )
      .subscribe();
  }
 
  // 批量事件处理 
  @OnEvent('batch.process')
  handleBatchProcess(payload: BatchEvent): Observable<any> {
    return from(payload.items).pipe(
      mergeMap(item => this.processItem(item), 10), // 并发限制为10 
    );
  }
 
  private async processHeavyTask(payload: HeavyTaskEvent): Promise<any> {
    // 模拟耗时操作 
    await new Promise(resolve => setTimeout(resolve, 5000));
    return { success: true, data: payload };
  }
 
  private async processItem(item: any): Promise<any> {
    // 处理单个项目 
    return { processed: true, item };
  }
}

最佳实践建议

  • 错误处理:始终使用 pcall 包装事件回调函数,防止单个事件错误影响整个系统
  • 内存管理:定期清理不再使用的事件监听器,避免内存泄漏
  • 性能监控:监控事件队列长度和处理时间,及时发现性能瓶颈
  • 脚本安全:在生产环境中限制Lua脚本的权限,避免恶意代码执行

性能优化关键策略

1 ) 避免闭包滥用

使用局部变量缓存事件回调

lua 复制代码
local callback = function(data) -- 避免重复创建函数对象
  process(data)
end
emitter:on("event", callback)

2 ) 内存回收机制

显式注销事件:emitter:off("event", callback)

设置__gc元方法自动回收

lua 复制代码
setmetatable(emitter, {
  __gc = function() 
    clear_all_listeners()
  end
})

3 ) 表优化技巧

预分配事件表空间避免rehash

使用数字索引代替字符串键加速访问

实战案例:HTTP请求事件

1 ) OpenResty服务端事件

lua 复制代码
location /event {
  content_by_lua_block {
    local http = require "resty.http"
    local httpc = http.new()
    httpc:connect("api.com", 80)
    httpc:on("request_complete", function()
      ngx.say("Request done")
    end)
  }
}

2 ) NestJS响应Lua事件

typescript 复制代码
import { OnModuleInit } from '@nestjs/common';
export class LuaBridge implements OnModuleInit {
  initLuaRuntime() {
    luaVM.on('async_event', (data) => {
      this.eventEmitter.emit('nestEvent', data);
    });
  }
}

架构对比总结

特性 Lua事件系统 NestJS事件系统
并发模型 协程(单线程异步) 事件循环+Worker线程
内存开销 通常<100KB[3] 10MB+
适用场景 嵌入式/IoT/网关 企业级Web应用
强项 热更新/低延迟 类型安全/生态完善

完整代码示例参考:

Lua事件库实现
NestJS-Lua桥接方案

通过融合两者优势,可构建出高并发+低延迟的混合架构(如OpenResty+NestJS微服务)

相关推荐
哔哩哔哩技术2 小时前
2025年哔哩哔哩技术精选技术干货
前端·后端·架构
浩子智控3 小时前
高可靠电子产品软件工程化
测试工具·架构·系统安全·软件工程·敏捷流程
踏浪无痕3 小时前
从救火到防火:我在金融企业构建可观测性体系的实战之路
后端·面试·架构
小小王app小程序开发4 小时前
招工招聘小程序开发全解析:全栈架构、核心模块实现与性能优化
性能优化·架构
小股虫5 小时前
让系统“杀不死”:同步与异步场景下的弹性设计模式手册
分布式·微服务·设计模式·架构·团队建设·方法论
无心水5 小时前
【神经风格迁移:工程化】27、神经风格迁移全栈进阶实战:Docker容器化与K8s部署,从单机到云原生
docker·云原生·架构·神经风格迁移·docker容器化·ai部署·vgg算法
lbb 小魔仙5 小时前
【Java】Spring Boot 与 Spring Cloud 整合:微服务架构入门实战
java·spring boot·spring cloud·架构
骥龙5 小时前
第四篇:融合篇——架构的涌现效应:1+1>2
运维·架构·云计算
前端世界5 小时前
鸿蒙分布式权限管理实战指南:架构原理 + 可运行 Demo
分布式·架构·harmonyos