当前位置: 首页 > 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.rkmt.cn/news/1463345.html

相关文章:

  • 用快马ai五分钟生成vue3待办应用原型,体验组合式api的魅力
  • bert-base-uncased-emotion代码深度解析:从数据预处理到推理输出的完整流程
  • 告别手动填坑!用Matlab一键生成Vivado ROM的.coe文件(附完整脚本)
  • 教条主义的自我指涉悖论与西方学术霸权的虚伪批判逻辑
  • 老旧音箱智能化改造:蓝牙WiFi模块与Class-D功放实战指南
  • 钓鱼链接致储户资金损失下银行责任边界与技术防控路径研究
  • 从百G到T级吞吐:高性能网关、防火墙、IPS、WAF背后的架构设计与性能优化实践
  • 从零到部署:基于快马ai在ubuntu上快速构建可运行的个人博客系统实战
  • 基于Arduino与433MHz无线通信的多LED灯带同步控制系统设计与实现
  • Spring Boot + Jasypt 实战指南:配置文件敏感信息加密完全手册
  • 铁路信号工必看:64D半自动闭塞13个继电器功能详解与日常维护要点
  • 避坑指南:在Win10+VS2013环境下配置BundleFusion跑通D435i离线数据(解决CUDA 8.0等环境问题)
  • “这是好事啊“:“经历过才能从容“是成长的唯一路径?
  • K2.5长文本模型工程化落地:128K稳定推理与生产部署指南
  • 旧音箱改造:从交流供电到直流电池供电的便携化DIY指南
  • 暗黑破坏神2终极优化指南:d2dx宽屏补丁让经典游戏焕发新生
  • question-vs-statement-classifier1在NPU设备上的加速指南:提升推理速度的3个方法
  • 深圳弱电箱生产厂家怎么选?采购前建议了解这几点
  • 广州:从流量争夺到AI认知权争夺,广州企业GEO布局正当时 - GEO优化
  • Vortex模组管理器:游戏模组管理的终极解决方案
  • 告别EV2400:用一块STM32F407开发板搞定BQ40Z50电池数据监控(含电压、电量读取)
  • xcms:构建现代代谢组学分析的技术架构与实现路径
  • TinyLlama微调实战:如何使用DPOTrainer进行模型对齐训练完整指南
  • 178软文网软文营销平台完善多层风控体系护航企业稳健安全传播
  • 雀魂牌谱分析工具:专业麻将数据统计与可视化解决方案
  • 如何快速部署typo-detector-distilbert-en:5分钟实现英文拼写错误检测
  • 计算机毕业设计之基于Spark的网剧推荐系统设计与实现
  • 深度解析:基于YOLOv5的AI自动瞄准系统3种实战部署方案
  • NPU加速的BERT模型:bert-uncased-keyword-extractor性能优化实战指南 [特殊字符]
  • AI工具×智能结算=降本增效新拐点?实测数据:结算周期压缩至17秒,人力成本直降64%