本项目技术架构介绍
前端

  • Vue3 + Element Plus

后端

  • Spring Cloud 2023.0.3
  • Spring Boot 3.3.4
  • Java 21

服务治理

  • Nacos(注册中心+配置中心)
  • OpenFeign(服务调用)
  • Spring Cloud Gateway(统一网关)

认证授权

  • Spring Security + OAuth2
  • 独立认证中心

业务微服务

  • 认证中心(OAuth2)
  • Gateway网关
  • 积分系统(增减/流水)
  • 微信支付(V3 Native支付)
  • 登录服务
  • 图生图(ComfyUI对接)

AIGC核心

  • 对接ComfyUI工作流API
  • RabbitMQ/RocketMQ异步解耦
  • 提供img2img工作流JSON示例

一. 图生图微服务整体架构: 异步任务+模型调度+对象存储
人物写真图生图的耗时通常在 5-15秒 之间(取决于显存和分辨率)。如果让前端HTTP同步等,必然超时或阻塞线程。
正确做法:异步任务模式,这是大厂AI中台的标准方案。

流程拆解:

  1. 用户提交原图 + 选择风格(古风/证件照/赛博朋克)。
  2. 后端返回taskId,立即响应“生成中”。
  3. 后端异步消费队列,调用图生图服务。
  4. 生成完成后,图片上传OSS/本地,更新任务状态为“已完成”。
  5. 前端轮询或WebSocket拿到结果URL。
    这套架构,Spring Boot只做调度和状态管理,不阻塞主线程,能撑住上千并发

二. Java 实现随机、轮询、最小连接数三策略,高可用图生图调度中心
假设你接了一个AI写真小程序的私活,峰值期 100 个用户同时上传照片生成写真。单机 ComfyUI:

  • 显存 24G 最多同时跑 2-3 个任务
  • 第 4 个请求直接 OOM 或排队 5 分钟+
  • 节点宕机后整个服务不可用
    解决方案
  • 节点动态注册/摘除
  • 实时感知每个节点的当前连接数
  • 智能调度:让空闲节点多干活,繁忙节点少干活

核心代码

@Slf4j
@Component
public class ComfyUILoadBalancer {
    
    private final CopyOnWriteArrayList<String> healthyServers = new CopyOnWriteArrayList<>();
    private final AtomicInteger roundRobinCounter = new AtomicInteger(0);
    private final ConcurrentHashMap<String, AtomicInteger> connectionCounts = new ConcurrentHashMap<>();
    
    private final ComfyUIServerConfig config;
    
    public ComfyUILoadBalancer(ComfyUIServerConfig config) {
        this.config = config;
        initializeServers();
    }
    
    private void initializeServers() {
        if (config.getServers() != null && !config.getServers().isEmpty()) {
            healthyServers.addAll(config.getServers());
            for (String server : config.getServers()) {
                connectionCounts.putIfAbsent(server, new AtomicInteger(0));
            }
            log.info("初始化 ComfyUI 服务器列表: {}", healthyServers);
        } else {
            log.warn("未配置 ComfyUI 服务器列表");
        }
    }
    
    public String selectServer() {
        if (healthyServers.isEmpty()) {
            throw new IllegalStateException("没有可用的 ComfyUI 服务器");
        }
        
        switch (config.getStrategy()) {
            case ROUND_ROBIN:
                return selectByRoundRobin();
            case RANDOM:
                return selectByRandom();
            case LEAST_CONNECTIONS:
                return selectByLeastConnections();
            default:
                return selectByRoundRobin();
        }
    }
    
    private String selectByRoundRobin() {
        int index = Math.abs(roundRobinCounter.getAndIncrement() % healthyServers.size());
        String server = healthyServers.get(index);
        log.debug("轮询选择服务器: {}, 当前连接数: {}", server, getConnectionCount(server));
        incrementConnection(server);
        return server;
    }
    
    private String selectByRandom() {
        int index = (int) (Math.random() * healthyServers.size());
        String server = healthyServers.get(index);
        log.debug("随机选择服务器: {}, 当前连接数: {}", server, getConnectionCount(server));
        incrementConnection(server);
        return server;
    }
    
    private String selectByLeastConnections() {
        String selectedServer = healthyServers.get(0);
        int minConnections = getConnectionCount(selectedServer);
        
        for (String server : healthyServers) {
            int connections = getConnectionCount(server);
            if (connections < minConnections) {
                minConnections = connections;
                selectedServer = server;
            }
        }
        
        log.debug("最少连接选择服务器: {}, 当前连接数: {}", selectedServer, minConnections);
        incrementConnection(selectedServer);
        return selectedServer;
    }
    
    public void markServerHealthy(String server) {
        if (!healthyServers.contains(server)) {
            healthyServers.add(server);
            connectionCounts.putIfAbsent(server, new AtomicInteger(0));
            log.info("服务器标记为健康: {}", server);
        }
    }
    
    public void markServerUnhealthy(String server) {
        if (healthyServers.remove(server)) {
            connectionCounts.remove(server);
            log.warn("服务器标记为不健康: {}", server);
        }
    }
    
    public void incrementConnection(String server) {
        AtomicInteger count = connectionCounts.get(server);
        if (count != null) {
            int newCount = count.incrementAndGet();
            log.debug("服务器 {} 连接数增加到: {}", server, newCount);
        }
    }
    
    public void decrementConnection(String server) {
        AtomicInteger count = connectionCounts.get(server);
        if (count != null) {
            int newCount = count.decrementAndGet();
            if (newCount < 0) {
                count.set(0);
            }
            log.debug("服务器 {} 连接数减少到: {}", server, newCount);
        }
    }
    
    public int getConnectionCount(String server) {
        AtomicInteger count = connectionCounts.get(server);
        return count != null ? count.get() : 0;
    }
    
    public List<String> getHealthyServers() {
        return healthyServers;
    }
    
    public Map<String, Integer> getAllConnectionCounts() {
        ConcurrentHashMap<String, Integer> result = new ConcurrentHashMap<>();
        for (Map.Entry<String, AtomicInteger> entry : connectionCounts.entrySet()) {
            result.put(entry.getKey(), entry.getValue().get());
        }
        return result;
    }
    
    public void updateServers(List<String> newServers) {
        healthyServers.clear();
        connectionCounts.clear();
        healthyServers.addAll(newServers);
        for (String server : newServers) {
            connectionCounts.putIfAbsent(server, new AtomicInteger(0));
        }
        roundRobinCounter.set(0);
        log.info("更新 ComfyUI 服务器列表: {}", healthyServers);
    }
}

项目页面预览,提供与sd相同的提示词
请添加图片描述
来展示一下效果图
原图在这里插入图片描述
生成之后的图片
在这里插入图片描述

由于节约成本 本项目 只部署单个comfyui节点,仅供娱乐

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐