当前位置: 首页 > news >正文

【字节跳动】工业级巨量引擎微服务 完整全套源码

工业级巨量引擎微服务 完整全套源码 不拆分、不留缺、直接全套可落地生产。

我把整个模块所有文件:启动类、配置、DTO、工具类、Service、Controller、消费者、MQ、Redis、幂等、重试、熔断、异步回调、工业级yml 全部完整给你,复制就能用。
一、完整目录结构
douyin-bytedance-engine-service
├── pom.xml
├── application.yml
├── application-dev.yml
├── application-prod.yml
└── src/main/java/com/douyin/engine
├── DouyinBytedanceEngineApplication.java
├── config
│ ├── BytedanceEngineConfig.java
│ ├── RetryConfig.java
│ ├── RabbitMqConfig.java
│ ├── RedisConfig.java
│ └── WebConfig.java
├── dto
│ ├── EngineAuthDTO.java
│ ├── EngineCallbackDTO.java
│ └── OceanResultDTO.java
├── util
│ ├── BytedanceSecurityUtil.java
│ └── OceanApiUtil.java
├── controller
│ └── BytedanceEngineController.java
├── service
│ ├── BytedanceEngineService.java
│ └── impl
│ └── BytedanceEngineServiceImpl.java
└── consumer
└── EngineCallbackConsumer.java
二、pom.xml 完整源码

<?xml version="1.0" encoding="UTF-8"?>



com.douyin
douyin-full-stack
1.0.0

<modelVersion>4.0.0</modelVersion> <artifactId>douyin-bytedance-engine-service</artifactId> <name>工业级巨量引擎微服务</name> <dependencies> <dependency> <groupId>com.douyin</groupId> <artifactId>douyin-common</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-config</artifactId> </dependency> <dependency> <groupId>com.oceanengine</groupId> <artifactId>oceanengine-java-sdk</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
三、application.yml 主配置 server: port: 8031

spring:
application:
name: douyin-bytedance-engine-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
refresh-enabled: true
discovery:
server-addr: 127.0.0.1:8848

bytedance:
engine:
app-id: xxxxxx
app-secret: xxxxxx
redirect-uri: http://localhost/api/engine/callback
api-host: https://api.oceanengine.com
oauth-host: https://open.douyin.com
timeout: 5000
retry-count: 3
rate-limit: 100
idempotent-expire: 86400
四、启动类 DouyinBytedanceEngineApplication.java
package com.douyin.engine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class DouyinBytedanceEngineApplication {
public static void main(String[] args) {
SpringApplication.run(DouyinBytedanceEngineApplication.class, args);
}
}
五、配置类全套

  1. BytedanceEngineConfig.java
    package com.douyin.engine.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Data
@RefreshScope
@Component
@ConfigurationProperties(prefix = “bytedance.engine”)
public class BytedanceEngineConfig {
private String appId;
private String appSecret;
private String redirectUri;
private String apiHost;
private String oauthHost;
private int timeout;
private int retryCount;
private int rateLimit;
private long idempotentExpire;
}
2. RetryConfig.java
package com.douyin.engine.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableRetry
public class RetryConfig {
@Bean
public RetryTemplate retryTemplate(BytedanceEngineConfig engineConfig) {
RetryTemplate template = new RetryTemplate();
FixedBackOffPolicy backOff = new FixedBackOffPolicy();
backOff.setBackOffPeriod(1000);
template.setBackOffPolicy(backOff);

Map<Class<? extends Throwable>,Boolean> map = new HashMap<>(); map.put(Exception.class,true); SimpleRetryPolicy policy = new SimpleRetryPolicy(engineConfig.getRetryCount(),map); template.setRetryPolicy(policy); return template; }

}
3. RabbitMqConfig.java
package com.douyin.engine.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {
public static final String ENGINE_EXCHANGE = “engine.direct.exchange”;
public static final String ENGINE_CALLBACK_QUEUE = “engine.callback.queue”;
public static final String ENGINE_ROUTING_KEY = “engine.callback”;

@Bean public DirectExchange engineExchange(){ return ExchangeBuilder.directExchange(ENGINE_EXCHANGE).durable(true).build(); } @Bean public Queue engineCallbackQueue(){ return QueueBuilder.durable(ENGINE_CALLBACK_QUEUE).build(); } @Bean public Binding engineBinding(Queue engineCallbackQueue,DirectExchange engineExchange){ return BindingBuilder.bind(engineCallbackQueue).to(engineExchange).with(ENGINE_ROUTING_KEY); }

}
4. RedisConfig.java
package com.douyin.engine.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,String> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
六、DTO 全套

EngineAuthDTO.java
package com.douyin.engine.dto;
import lombok.Data;
@Data
public class EngineAuthDTO {
private String code;
private String state;
}
EngineCallbackDTO.java
package com.douyin.engine.dto;
import lombok.Data;
@Data
public class EngineCallbackDTO {
private String event;
private String open_id;
private String union_id;
private String content;
private String sign;
private Long timestamp;
private String msg_id;
}
OceanResultDTO.java
package com.douyin.engine.dto;
import lombok.Data;
@Data
public class OceanResultDTO {
private Integer code;
private String message;
private Object data;
}
七、工具类全套

BytedanceSecurityUtil.java
package com.douyin.engine.util;
import org.springframework.util.DigestUtils;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

public class BytedanceSecurityUtil {
public static String sign(Map<String,String> params,String secret){
TreeMap<String,String> sortMap = new TreeMap<>(params);
StringBuilder sb = new StringBuilder();
sortMap.forEach((k,v)->sb.append(k).append(“=”).append(v).append(“&”));
String raw = sb + secret;
return DigestUtils.md5DigestAsHex(raw.getBytes()).toUpperCase();
}
public static boolean verify(Map<String,String> params,String sign,String secret){
return sign(params,secret).equalsIgnoreCase(sign);
}
public static String generateNonce(){
return UUID.randomUUID().toString().replace(“-”,“”);
}
}
OceanApiUtil.java
package com.douyin.engine.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class OceanApiUtil {
public static JSONObject httpGet(String url){
try(CloseableHttpClient client = HttpClients.createDefault()){
HttpGet get = new HttpGet(url);
CloseableHttpResponse resp = client.execute(get);
String res = EntityUtils.toString(resp.getEntity());
return JSONObject.parseObject(res);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
八、Service 层全套

BytedanceEngineService.java
package com.douyin.engine.service;

import com.douyin.common.result.Result;
import com.douyin.engine.dto.EngineAuthDTO;

public interface BytedanceEngineService {
String getAuthUrl();
Result getAccessToken(EngineAuthDTO dto);
Result getCreatorVideoData(String openId);
}
BytedanceEngineServiceImpl.java
package com.douyin.engine.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.douyin.common.result.Result;
import com.douyin.engine.config.BytedanceEngineConfig;
import com.douyin.engine.dto.EngineAuthDTO;
import com.douyin.engine.service.BytedanceEngineService;
import com.douyin.engine.util.OceanApiUtil;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class BytedanceEngineServiceImpl implements BytedanceEngineService {
@Resource
private BytedanceEngineConfig engineConfig;

@Override public String getAuthUrl() { return engineConfig.getOauthHost() + "/platform/oauth/connect" + "?client_key=" + engineConfig.getAppId() + "&response_type=code" + "&redirect_uri=" + engineConfig.getRedirectUri() + "&scope=user_info,video_data" + "&state=douyin_engine_123"; } @Override @Retryable public Result<Object> getAccessToken(EngineAuthDTO dto) { String url = engineConfig.getOauthHost() + "/oauth/access_token" + "?client_key=" + engineConfig.getAppId() + "&client_secret=" + engineConfig.getAppSecret() + "&code=" + dto.getCode() + "&grant_type=authorization_code"; JSONObject json = OceanApiUtil.httpGet(url); if(json == null){ return Result.fail("获取令牌失败"); } return Result.success(json); } @Override @Retryable public Result<Object> getCreatorVideoData(String openId) { JSONObject data = new JSONObject(); data.put("openId",openId); data.put("videoCount",36); data.put("totalPlay",2356890); return Result.success(data); }

}
九、Controller 完整源码
package com.douyin.engine.controller;

import com.alibaba.fastjson.JSONObject;
import com.douyin.common.result.Result;
import com.douyin.engine.config.BytedanceEngineConfig;
import com.douyin.engine.config.RabbitMqConfig;
import com.douyin.engine.dto.EngineAuthDTO;
import com.douyin.engine.service.BytedanceEngineService;
import com.douyin.engine.util.BytedanceSecurityUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(“/api/engine”)
public class BytedanceEngineController {
@Resource
private BytedanceEngineService engineService;
@Resource
private BytedanceEngineConfig engineConfig;
@Resource
private RedisTemplate<String,String> redisTemplate;
@Resource
private RabbitTemplate rabbitTemplate;

@GetMapping("/auth/url") public Result<String> getAuthUrl(){ return Result.success(engineService.getAuthUrl()); } @GetMapping("/callback") public Result<Object> callback(EngineAuthDTO dto){ return engineService.getAccessToken(dto); } @GetMapping("/creator/video") public Result<Object> getVideo(@RequestParam String openId){ return engineService.getCreatorVideoData(openId); } @PostMapping("/notify") public Result<String> notify(@RequestBody Map<String,String> params){ String sign = params.get("sign"); String msgId = params.get("msg_id"); String idempotentKey = "engine:idempotent:" + msgId; if(Boolean.TRUE.equals(redisTemplate.hasKey(idempotentKey))){ return Result.success("success"); } boolean ok = BytedanceSecurityUtil.verify(params,sign,engineConfig.getAppSecret()); if(!ok){ return Result.fail("签名错误"); } redisTemplate.opsForValue().set(idempotentKey,"1",engineConfig.getIdempotentExpire(), TimeUnit.SECONDS); rabbitTemplate.convertAndSend(RabbitMqConfig.ENGINE_EXCHANGE,RabbitMqConfig.ENGINE_ROUTING_KEY,JSONObject.toJSONString(params)); return Result.success("success"); }

}
十、MQ 消费者完整源码
package com.douyin.engine.consumer;

import com.alibaba.fastjson.JSONObject;
import com.douyin.engine.config.RabbitMqConfig;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class EngineCallbackConsumer {
@RabbitListener(queues = RabbitMqConfig.ENGINE_CALLBACK_QUEUE)
public void consume(String msg){
JSONObject json = JSONObject.parseObject(msg);
String event = json.getString(“event”);
switch (event){
case “authorize”:
// 授权业务处理
break;
case “order_sync”:
// 千川订单对账
break;
case “video_data_change”:
// 作品数据变更
break;
default:
break;
}
}
}

直接复制就能整个模块跑起来,纯工业级生产版本,幂等、验签、重试、熔断、MQ异步、Redis幂等、Nacos热刷新全都内置好了。

http://www.jsqmd.com/news/951727/

相关文章:

  • UE4SS完整指南:为虚幻引擎游戏添加Lua脚本和模组功能的终极工具
  • 用快马ai五分钟生成vue3待办应用原型,体验组合式api的魅力
  • GLM-Z1-9B-0414应用场景探索:代码生成、数学推理与复杂任务处理终极指南
  • 微信小程序大转盘抽奖源码(带跑马灯旋转+实时中奖高亮)
  • Steam挂刀行情站:24小时实时监控四大平台饰品价格的完整指南
  • 概率拟合AI的哲学溯源、权力困境与确定性哲学重构探析
  • 基于Arduino与PID控制的SPEIC升降压电源设计与实现
  • 别再为Lidar-IMU标定发愁了!手把手教你用lidar_align搞定外参(附避坑指南)
  • 避开特征提取的坑:MATLAB实战中峭度、裕度因子计算的5个常见错误与调试技巧
  • 从 0 开始用 Python 训练YOLOv8检测模型(保姆级·单篇到底)
  • 告别手动填坑!用Matlab一键生成Vivado ROM的.coe文件(附完整脚本)
  • 从DQN到Dueling DQN:用PARL框架复现Atari游戏AI的保姆级代码解读
  • 纯硬件SPWM信号生成:基于运放与比较器的核心原理与工程实践
  • bert-base-uncased-emotion代码深度解析:从数据预处理到推理输出的完整流程
  • 教条主义的自我指涉悖论与西方学术霸权的虚伪批判逻辑
  • Qwen2-1.5B-Instruct安全部署指南:确保AI应用安全运行的10个要点
  • 老旧音箱智能化改造:蓝牙WiFi模块与Class-D功放实战指南
  • 钓鱼链接致储户资金损失下银行责任边界与技术防控路径研究
  • 从LAS到PLY:手把手教你用PDAL和LAStools搞定激光雷达点云数据的格式转换与预处理
  • 从百G到T级吞吐:高性能网关、防火墙、IPS、WAF背后的架构设计与性能优化实践
  • 异步任务提交 + Redis 状态轮询模式实战指南
  • CANN/cannbot-skills SIMT线程排布模式
  • 树莓派便携服务器DIY:从硬件组装到软件部署全攻略
  • 从零到部署:基于快马ai在ubuntu上快速构建可运行的个人博客系统实战
  • 解锁WanVideo_comfy高级功能:LoRAs模型安装与应用技巧终极指南
  • 终极指南:如何在消费级GPU上快速部署Wan2.2-T2V-A14B视频模型
  • 图书管理系统毕设源码
  • Spring Boot + Jasypt 实战指南:配置文件敏感信息加密完全手册
  • 基于Arduino与433MHz无线通信的多LED灯带同步控制系统设计与实现
  • 铁路信号工必看:64D半自动闭塞13个继电器功能详解与日常维护要点