后端配置指南
AppSolve 后端服务配置指南
后端配置指南
本指南提供 AppSolve 后端服务的详细配置说明,包括环境变量、Firebase Admin、Cloudflare 资源、AI 服务集成等配置。
环境变量配置
1. 核心配置
创建 .dev.vars
文件用于本地开发:
# 环境标识
ENVIRONMENT=development
# Firebase Admin SDK
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxx@your-project.iam.gserviceaccount.com
# API 密钥(用于服务间通信)
API_SECRET_KEY=your-secure-api-secret-key
# CORS 配置
ALLOWED_ORIGINS=http://localhost:3000,https://yourdomain.com
2. AI 服务配置
2.1 OpenAI 配置
# OpenAI API
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo-preview
OPENAI_MAX_TOKENS=2000
OPENAI_TEMPERATURE=0.7
2.2 Google AI (Gemini) 配置
# Google AI
GOOGLE_AI_API_KEY=AIza...
GEMINI_MODEL=gemini-pro
GEMINI_MAX_OUTPUT_TOKENS=2048
2.3 图像生成服务 (FAL.ai)
# FAL.ai
FAL_KEY=your-fal-api-key
FAL_MODEL_IMAGE=fal-ai/flux/schnell
FAL_MODEL_VIDEO=fal-ai/kling-video/v1/standard/text-to-video
3. 第三方服务配置
# Sentry 错误监控
SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx
# 速率限制
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW_MS=60000
# 缓存配置
CACHE_TTL_SECONDS=3600
CACHE_MAX_AGE=86400
Cloudflare 配置
1. Workers 配置
1.1 wrangler.jsonc 详解
{
"name": "appsolve-backend",
"main": "src/index.ts",
"compatibility_date": "2024-01-01",
// KV 命名空间绑定
"kv_namespaces": [
{
"binding": "CACHE",
"id": "your-cache-namespace-id",
"preview_id": "your-cache-preview-id"
},
{
"binding": "ANALYTICS",
"id": "your-analytics-namespace-id",
"preview_id": "your-analytics-preview-id"
},
{
"binding": "QUOTA",
"id": "your-quota-namespace-id",
"preview_id": "your-quota-preview-id"
}
],
// R2 存储桶绑定
"r2_buckets": [
{
"binding": "R2_MEDIA_STORAGE",
"bucket_name": "media-storage"
}
],
// 环境变量
"vars": {
"ENVIRONMENT": "production",
"LOG_LEVEL": "info"
}
}
1.2 创建 KV 命名空间
# 缓存存储
pnpm wrangler kv:namespace create "CACHE"
pnpm wrangler kv:namespace create "CACHE" --preview
# 分析数据存储
pnpm wrangler kv:namespace create "ANALYTICS"
pnpm wrangler kv:namespace create "ANALYTICS" --preview
# 配额管理存储
pnpm wrangler kv:namespace create "QUOTA"
pnpm wrangler kv:namespace create "QUOTA" --preview
2. R2 存储配置
2.1 创建存储桶
# 媒体文件存储
pnpm wrangler r2 bucket create media-storage
# 配置 CORS(如需要)
pnpm wrangler r2 bucket cors put media-storage --file cors-config.json
2.2 CORS 配置示例
// cors-config.json
[
{
"AllowedOrigins": ["https://yourdomain.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]
2.3 存储结构
media-storage/
├── images/
│ ├── generated/ # AI 生成的图像
│ ├── uploads/ # 用户上传
│ └── thumbnails/ # 缩略图
├── videos/
│ ├── generated/ # AI 生成的视频
│ └── processed/ # 处理后的视频
└── temp/ # 临时文件
3. Workers 限制与优化
3.1 资源限制
- CPU 时间:10ms (免费) / 50ms (付费)
- 内存:128MB
- 脚本大小:1MB (压缩后)
- 请求大小:100MB
3.2 优化策略
// 使用 Durable Objects 处理长任务
export class VideoProcessor {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request) {
// 处理视频生成任务
}
}
Firebase Admin 配置
1. 服务账号设置
1.1 生成服务账号
- Firebase Console > 项目设置 > 服务账号
- 生成新的私钥
- 安全存储 JSON 文件
1.2 配置权限
确保服务账号具有以下角色:
- Firebase Admin SDK Administrator
- Cloud Datastore User
- Storage Admin
2. Firestore 配置
2.1 数据模型
// 用户集合
interface UserDocument {
uid: string;
email: string;
displayName?: string;
photoURL?: string;
tier: "free" | "pro" | "premium";
credits: number;
createdAt: Timestamp;
updatedAt: Timestamp;
}
// 任务集合
interface TaskDocument {
userId: string;
type: "image" | "video";
status: "pending" | "processing" | "completed" | "failed";
input: any;
output?: any;
error?: string;
createdAt: Timestamp;
completedAt?: Timestamp;
}
2.2 索引优化
// firestore.indexes.json
{
"indexes": [
{
"collectionGroup": "imageTasks",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "userId", "order": "ASCENDING" },
{ "fieldPath": "status", "order": "ASCENDING" },
{ "fieldPath": "createdAt", "order": "DESCENDING" }
]
}
]
}
AI 服务集成
1. 提示词管理
// src/infrastructure/ai/prompts.ts
export const IMAGE_GENERATION_PROMPTS = {
enhance: (input: string) => `
Enhance the following image description for AI generation:
Original: ${input}
Add artistic details, lighting, composition, and style.
Keep it concise but descriptive.
`,
style: (input: string, style: string) => `
Apply ${style} style to: ${input}
`,
};
2. 模型选择策略
// src/infrastructure/ai/model-selector.ts
export class ModelSelector {
selectImageModel(requirements: ImageRequirements): string {
if (requirements.quality === "premium") {
return "fal-ai/flux/dev";
}
if (requirements.speed === "fast") {
return "fal-ai/flux/schnell";
}
return "fal-ai/stable-diffusion-xl";
}
}
3. 错误处理与重试
// src/infrastructure/ai/retry-handler.ts
export class AIRetryHandler {
async executeWithRetry<T>(
fn: () => Promise<T>,
options = { maxRetries: 3, backoff: 1000 }
): Promise<T> {
for (let i = 0; i <= options.maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === options.maxRetries) throw error;
await new Promise((resolve) =>
setTimeout(resolve, options.backoff * Math.pow(2, i))
);
}
}
throw new Error("Max retries exceeded");
}
}
缓存策略
1. 多层缓存架构
// src/infrastructure/cache/cache-strategy.ts
export class CacheStrategy {
constructor(
private memory: MemoryCache,
private kv: KVCache,
private cdn: CDNCache
) {}
async get(key: string): Promise<any> {
// L1: 内存缓存
let value = this.memory.get(key);
if (value) return value;
// L2: KV 缓存
value = await this.kv.get(key);
if (value) {
this.memory.set(key, value);
return value;
}
// L3: CDN 缓存
return await this.cdn.get(key);
}
}
2. 缓存键设计
// 缓存键规范
const CACHE_KEYS = {
user: (id: string) => `user:${id}`,
task: (id: string) => `task:${id}`,
explore: (category: string, page: number) => `explore:${category}:${page}`,
analytics: (date: string) => `analytics:${date}`,
};
速率限制配置
1. 基于用户层级的限制
// src/infrastructure/ratelimit/tier-limits.ts
export const TIER_LIMITS = {
free: {
requests: { limit: 10, window: "1h" },
imageGeneration: { limit: 5, window: "1d" },
videoGeneration: { limit: 1, window: "1d" },
storage: { limit: 100 * 1024 * 1024 }, // 100MB
},
pro: {
requests: { limit: 100, window: "1h" },
imageGeneration: { limit: 50, window: "1d" },
videoGeneration: { limit: 10, window: "1d" },
storage: { limit: 5 * 1024 * 1024 * 1024 }, // 5GB
},
premium: {
requests: { limit: 1000, window: "1h" },
imageGeneration: { limit: 500, window: "1d" },
videoGeneration: { limit: 100, window: "1d" },
storage: { limit: 50 * 1024 * 1024 * 1024 }, // 50GB
},
};
2. 实现示例
// src/middleware/rate-limit.ts
export async function rateLimitMiddleware(
request: Request,
env: Env,
ctx: ExecutionContext
) {
const userId = getUserId(request);
const userTier = await getUserTier(userId);
const limits = TIER_LIMITS[userTier];
const key = `ratelimit:${userId}:requests`;
const current = await env.QUOTA.get(key);
if (current >= limits.requests.limit) {
return new Response("Rate limit exceeded", { status: 429 });
}
await env.QUOTA.put(key, current + 1, {
expirationTtl: parseWindow(limits.requests.window),
});
}
监控和日志
1. 结构化日志
// src/infrastructure/monitoring/logger.ts
export class Logger {
log(level: string, message: string, meta?: any) {
const entry = {
timestamp: new Date().toISOString(),
level,
message,
...meta,
environment: env.ENVIRONMENT,
};
console.log(JSON.stringify(entry));
}
}
2. 性能监控
// src/infrastructure/monitoring/performance.ts
export class PerformanceMonitor {
async trackAPICall(endpoint: string, fn: Function) {
const start = Date.now();
try {
const result = await fn();
const duration = Date.now() - start;
// 记录到分析存储
await this.recordMetric({
endpoint,
duration,
status: "success",
timestamp: new Date().toISOString(),
});
return result;
} catch (error) {
const duration = Date.now() - start;
await this.recordMetric({
endpoint,
duration,
status: "error",
error: error.message,
timestamp: new Date().toISOString(),
});
throw error;
}
}
}
安全配置
1. API 认证
// src/middleware/auth.ts
export async function authMiddleware(
request: Request,
env: Env
): Promise<User | null> {
const token = request.headers.get("Authorization")?.replace("Bearer ", "");
if (!token) {
throw new UnauthorizedError("No token provided");
}
try {
// 验证 Firebase ID Token
const decodedToken = await admin.auth().verifyIdToken(token);
return {
uid: decodedToken.uid,
email: decodedToken.email,
// ... 其他用户信息
};
} catch (error) {
throw new UnauthorizedError("Invalid token");
}
}
2. 输入验证
// 使用 Zod 进行严格的输入验证
import { z } from "zod";
export const ImageGenerationSchema = z.object({
prompt: z.string().min(1).max(1000),
style: z.enum(["realistic", "artistic", "cartoon"]).optional(),
aspectRatio: z.enum(["1:1", "16:9", "9:16"]).default("1:1"),
quality: z.enum(["standard", "high"]).default("standard"),
});
部署配置
1. 生产环境变量
# 设置生产环境密钥
pnpm wrangler secret put FIREBASE_PRIVATE_KEY
pnpm wrangler secret put OPENAI_API_KEY
pnpm wrangler secret put GOOGLE_AI_API_KEY
pnpm wrangler secret put FAL_KEY
pnpm wrangler secret put API_SECRET_KEY
2. 自定义域名
# 添加自定义域名
pnpm wrangler domains add api.yourdomain.com
# 配置路由
pnpm wrangler routes add api.yourdomain.com/* appsolve-backend
3. 环境隔离
// wrangler.jsonc
{
"environments": {
"staging": {
"name": "appsolve-backend-staging",
"vars": {
"ENVIRONMENT": "staging"
}
},
"production": {
"name": "appsolve-backend",
"vars": {
"ENVIRONMENT": "production"
}
}
}
}
故障排除
1. 常见错误
Firebase 认证失败
# 检查服务账号密钥
echo $FIREBASE_PRIVATE_KEY | base64 -d
# 验证项目 ID
firebase projects:list
KV 存储问题
# 列出所有 KV 命名空间
pnpm wrangler kv:namespace list
# 检查 KV 内容
pnpm wrangler kv:key list --namespace-id=xxx
R2 上传失败
# 检查存储桶
pnpm wrangler r2 bucket list
# 验证 CORS 配置
pnpm wrangler r2 bucket cors get media-storage
2. 性能优化
- 使用
waitUntil()
处理非关键任务 - 实现请求合并减少 API 调用
- 使用 Cloudflare Cache API 缓存响应
- 优化图片和视频的 CDN 分发