本文目录导读:

我来为你提供几个完整的Java无服务器计算案例,涵盖不同云平台和使用场景。
AWS Lambda + Java 案例
基础Lambda函数示例
package com.example.lambda;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.HashMap;
import java.util.Map;
public class UserServiceHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private final UserRepository userRepository = new UserRepository();
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
context.getLogger().log("收到请求: " + input.getHttpMethod() + " " + input.getPath());
try {
// 根据HTTP方法路由请求
switch (input.getHttpMethod()) {
case "GET":
return handleGetRequest(input);
case "POST":
return handlePostRequest(input);
case "PUT":
return handlePutRequest(input);
case "DELETE":
return handleDeleteRequest(input);
default:
return createResponse(405, "方法不允许");
}
} catch (Exception e) {
context.getLogger().log("处理异常: " + e.getMessage());
return createResponse(500, "服务器内部错误");
}
}
private APIGatewayProxyResponseEvent handleGetRequest(APIGatewayProxyRequestEvent input) {
// GET /users/{id}
String userId = input.getPathParameters().get("id");
if (userId != null) {
User user = userRepository.findById(userId);
if (user != null) {
return createResponse(200, gson.toJson(user));
}
return createResponse(404, "用户不存在");
}
// GET /users - 获取所有用户
List<User> users = userRepository.findAll();
return createResponse(200, gson.toJson(users));
}
private APIGatewayProxyResponseEvent handlePostRequest(APIGatewayProxyRequestEvent input) {
// POST /users - 创建用户
User newUser = gson.fromJson(input.getBody(), User.class);
User createdUser = userRepository.save(newUser);
return createResponse(201, gson.toJson(createdUser));
}
private APIGatewayProxyResponseEvent handlePutRequest(APIGatewayProxyRequestEvent input) {
// PUT /users/{id} - 更新用户
String userId = input.getPathParameters().get("id");
User updatedUser = gson.fromJson(input.getBody(), User.class);
updatedUser.setId(userId);
User result = userRepository.update(updatedUser);
if (result != null) {
return createResponse(200, gson.toJson(result));
}
return createResponse(404, "用户不存在");
}
private APIGatewayProxyResponseEvent handleDeleteRequest(APIGatewayProxyRequestEvent input) {
// DELETE /users/{id} - 删除用户
String userId = input.getPathParameters().get("id");
userRepository.delete(userId);
return createResponse(200, "删除成功");
}
private APIGatewayProxyResponseEvent createResponse(int statusCode, String body) {
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setStatusCode(statusCode);
// 添加CORS头
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("Access-Control-Allow-Origin", "*");
headers.put("Access-Control-Allow-Headers", "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token");
headers.put("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
response.setHeaders(headers);
response.setBody(body);
return response;
}
}
用户实体类
package com.example.lambda;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
@DynamoDBTable(tableName = "Users")
public class User {
private String id;
private String name;
private String email;
private int age;
private long createdAt;
public User() {}
public User(String id, String name, String email, int age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
this.createdAt = System.currentTimeMillis();
}
@DynamoDBHashKey(attributeName = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@DynamoDBAttribute(attributeName = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@DynamoDBAttribute(attributeName = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@DynamoDBAttribute(attributeName = "age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@DynamoDBAttribute(attributeName = "createdAt")
public long getCreatedAt() {
return createdAt;
}
public void setCreatedAt(long createdAt) {
this.createdAt = createdAt;
}
}
使用DynamoDB的数据访问层
package com.example.lambda;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
import java.util.List;
import java.util.UUID;
public class UserRepository {
private final AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
private final DynamoDBMapper mapper = new DynamoDBMapper(client);
public User save(User user) {
if (user.getId() == null || user.getId().isEmpty()) {
user.setId(UUID.randomUUID().toString());
}
mapper.save(user);
return user;
}
public User findById(String id) {
return mapper.load(User.class, id);
}
public List<User> findAll() {
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
return mapper.scan(User.class, scanExpression);
}
public User update(User user) {
User existing = findById(user.getId());
if (existing != null) {
mapper.save(user);
return user;
}
return null;
}
public void delete(String id) {
User user = new User();
user.setId(id);
mapper.delete(user);
}
}
Azure Functions + Java 案例
定时触发器函数(定时清理任务)
package com.example.azure;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.time.Instant;
import java.util.Optional;
public class CleanupScheduler {
private static final Logger logger = LoggerFactory.getLogger(CleanupScheduler.class);
@FunctionName("cleanupExpiredData")
public void cleanupExpiredData(
@TimerTrigger(name = "timerInfo", schedule = "0 0 2 * * *") String timerInfo,
ExecutionContext context) {
context.getLogger().info("定时清理任务开始执行: " + Instant.now());
// 清理过期的临时文件
cleanupTempFiles(context);
// 清理过期的会话
cleanupExpiredSessions(context);
// 清理日志文件
cleanupOldLogs(context);
context.getLogger().info("定时清理任务执行完成");
}
private void cleanupTempFiles(ExecutionContext context) {
try {
// 使用Azure Blob Storage清理文件
String connectionString = System.getenv("AzureWebJobsStorage");
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.connectionString(connectionString)
.buildClient();
String containerName = "temp-files";
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);
long cutoffTime = System.currentTimeMillis() - (24 * 60 * 60 * 1000); // 24小时前
int deletedCount = 0;
for (BlobItem blob : containerClient.listBlobs()) {
BlobClient blobClient = containerClient.getBlobClient(blob.getName());
BlobProperties properties = blobClient.getProperties();
if (properties.getLastModified().getTime() < cutoffTime) {
blobClient.delete();
deletedCount++;
}
}
context.getLogger().info("清理了 " + deletedCount + " 个临时文件");
} catch (Exception e) {
context.getLogger().severe("清理临时文件失败: " + e.getMessage());
}
}
private void cleanupExpiredSessions(ExecutionContext context) {
String connectionString = System.getenv("AZURE_SQL_CONNECTION");
if (connectionString == null) {
context.getLogger().warning("未配置数据库连接字符串");
return;
}
try (Connection conn = DriverManager.getConnection(connectionString);
PreparedStatement stmt = conn.prepareStatement(
"DELETE FROM user_sessions WHERE expires_at < GETDATE()")) {
int deletedCount = stmt.executeUpdate();
context.getLogger().info("清理了 " + deletedCount + " 个过期会话");
} catch (Exception e) {
context.getLogger().severe("清理会话失败: " + e.getMessage());
}
}
private void cleanupOldLogs(ExecutionContext context) {
// 清理超过30天的应用日志
String connectionString = System.getenv("AzureWebJobsStorage");
try {
TableServiceClient tableServiceClient = new TableServiceClientBuilder()
.connectionString(connectionString)
.buildClient();
String tableName = "applogs";
String cutoffDate = Instant.now()
.minus(30, ChronoUnit.DAYS)
.toString()
.substring(0, 10);
int deletedCount = 0;
// 查询并删除旧日志
PagedIterable<TableEntity> entities = tableServiceClient.queryTable(
tableName,
String.format("PartitionKey lt '%s'", cutoffDate),
null);
for (TableEntity entity : entities) {
tableServiceClient.deleteTableEntity(tableName, entity);
deletedCount++;
}
context.getLogger().info("清理了 " + deletedCount + " 条旧日志");
} catch (Exception e) {
context.getLogger().severe("清理日志失败: " + e.getMessage());
}
}
}
事件网格触发器(处理订单事件)
package com.example.azure;
import com.example.models.Order;
import com.google.gson.Gson;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.azure.storage.queue.QueueClient;
import com.azure.storage.queue.QueueClientBuilder;
public class OrderProcessor {
private static final Gson gson = new Gson();
@FunctionName("processOrder")
public void processOrder(
@EventGridTrigger(name = "event") String event,
ExecutionContext context) {
context.getLogger().info("订单事件到达: " + event);
try {
// 解析事件
EventGridEvent eventGridEvent = EventGridEvent.fromString(event);
Order order = gson.fromJson(eventGridEvent.getData().toString(), Order.class);
context.getLogger().info("处理订单: " + order.getOrderId());
// 1. 验证订单
boolean isValid = validateOrder(order);
if (!isValid) {
context.getLogger().warning("订单无效: " + order.getOrderId());
return;
}
// 2. 更新库存
updateInventory(order);
// 3. 如果订单金额大于1000,需要人工审核
if (order.getTotalAmount() > 1000) {
sendForApproval(order);
}
// 4. 设置订单状态
order.setStatus("PROCESSING");
// 5. 发送通知
sendNotification(order);
context.getLogger().info("订单处理完成: " + order.getOrderId());
} catch (Exception e) {
context.getLogger().severe("处理订单失败: " + e.getMessage());
throw new RuntimeException("处理订单失败", e);
}
}
private boolean validateOrder(Order order) {
// 验证订单基本信息
return order.getOrderId() != null
&& order.getCustomerId() != null
&& order.getItems() != null
&& !order.getItems().isEmpty();
}
private void updateInventory(Order order) {
// 使用Azure SQL更新库存
String connectionString = System.getenv("AZURE_SQL_CONNECTION");
try (Connection conn = DriverManager.getConnection(connectionString)) {
for (OrderItem item : order.getItems()) {
String sql = "UPDATE inventory SET quantity = quantity - ? WHERE product_id = ? AND quantity >= ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, item.getQuantity());
stmt.setString(2, item.getProductId());
stmt.setInt(3, item.getQuantity());
int updatedRows = stmt.executeUpdate();
if (updatedRows == 0) {
throw new RuntimeException("库存不足: " + item.getProductId());
}
}
}
} catch (Exception e) {
throw new RuntimeException("更新库存失败", e);
}
}
private void sendForApproval(Order order) {
// 发送到队列等待人工审核
String connectionString = System.getenv("AzureWebJobsStorage");
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectionString)
.queueName("order-approval")
.buildClient();
order.setStatus("PENDING_APPROVAL");
queueClient.sendMessage(gson.toJson(order));
}
private void sendNotification(Order order) {
// 使用Azure Notification Hubs发送通知
String connectionString = System.getenv("AZURE_NOTIFICATION_HUB_CONNECTION");
String hubName = System.getenv("AZURE_NOTIFICATION_HUB_NAME");
NotificationHubClient client = new NotificationHubClientBuilder()
.connectionString(connectionString)
.notificationHubName(hubName)
.buildClient();
Map<String, String> payload = new HashMap<>();
payload.put("message", "订单 " + order.getOrderId() + " 正在处理中");
try {
client.sendNotification(Notification.createWindowsNotification(
gson.toJson(payload)), new NotificationHubClient.SendNotificationOptions());
} catch (Exception e) {
context.getLogger().warning("发送通知失败: " + e.getMessage());
}
}
}
Google Cloud Functions + Java 案例
图片处理函数
package com.example.gcp;
import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.vision.v1.*;
import com.google.protobuf.ByteString;
import net.coobird.thumbnailator.Thumbnails;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
public class ImageProcessor implements BackgroundFunction<StorageEvent> {
private final Storage storage = StorageOptions.getDefaultInstance().getService();
private final ImageAnnotatorClient visionClient;
public ImageProcessor() {
try {
visionClient = ImageAnnotatorClient.create();
} catch (Exception e) {
throw new RuntimeException("初始化Vision客户端失败", e);
}
}
@Override
public void accept(StorageEvent event, Context context) throws Exception {
context.logger().log("处理图片: " + event.getName());
// 1. 读取原图
Blob sourceBlob = storage.get(event.getBucket(), event.getName());
byte[] imageData = sourceBlob.getContent();
// 2. 生成缩略图
String thumbnailPath = "thumbnails/" + event.getName();
generateThumbnail(imageData, event.getBucket(), thumbnailPath);
// 3. 检测图片内容(检查是否为违规内容)
boolean isSafe = detectUnsafeContent(imageData);
if (!isSafe) {
context.logger().log("图片可能包含违规内容: " + event.getName());
moveToQuarantine(event.getBucket(), event.getName());
return;
}
// 4. 提取图片标签
List<String> labels = extractLabels(imageData);
// 5. 存储图片元数据
storeImageMetadata(event, labels);
context.logger().log("图片处理完成");
}
private void generateThumbnail(byte[] imageData, String bucketName, String thumbnailPath) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 使用Thumbnailator生成缩略图
Thumbnails.of(new ByteArrayInputStream(imageData))
.size(300, 300)
.outputFormat("JPEG")
.toOutputStream(outputStream);
BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, thumbnailPath)
.setContentType("image/jpeg")
.build();
storage.create(blobInfo, outputStream.toByteArray());
}
private boolean detectUnsafeContent(byte[] imageData) {
try {
ByteString imgBytes = ByteString.copyFrom(imageData);
Image image = Image.newBuilder().setContent(imgBytes).build();
Feature feature = Feature.newBuilder()
.setType(Feature.Type.SAFE_SEARCH_DETECTION)
.build();
AnnotateImageRequest request = AnnotateImageRequest.newBuilder()
.addFeatures(feature)
.setImage(image)
.build();
BatchAnnotateImagesResponse response = visionClient.batchAnnotateImages(
Collections.singletonList(request));
SafeSearchAnnotation annotation = response.getResponses(0).getSafeSearchAnnotation();
// 检查是否有高几率的不安全内容
boolean isUnsafe =
annotation.getAdultValue() >= Likelihood.LIKELY_VALUE ||
annotation.getViolenceValue() >= Likelihood.LIKELY_VALUE ||
annotation.getRacyValue() >= Likelihood.VERY_LIKELY_VALUE;
return !isUnsafe;
} catch (Exception e) {
// 无法检测时默认通过
return true;
}
}
private List<String> extractLabels(byte[] imageData) {
try {
ByteString imgBytes = ByteString.copyFrom(imageData);
Image image = Image.newBuilder().setContent(imgBytes).build();
Feature feature = Feature.newBuilder()
.setType(Feature.Type.LABEL_DETECTION)
.build();
AnnotateImageRequest request = AnnotateImageRequest.newBuilder()
.addFeatures(feature)
.setImage(image)
.build();
BatchAnnotateImagesResponse response = visionClient.batchAnnotateImages(
Collections.singletonList(request));
List<String> labels = new ArrayList<>();
response.getResponses(0).getLabelAnnotationsList()
.forEach(label -> labels.add(label.getDescription()));
return labels;
} catch (Exception e) {
return Collections.emptyList();
}
}
private void moveToQuarantine(String bucketName, String fileName) {
String quarantinePath = "quarantine/" + fileName;
Blob blob = storage.get(bucketName, fileName);
storage.copy(
Storage.CopyRequest.newBuilder()
.setSource(blob.getBlobId())
.setTarget(BlobId.of(bucketName, quarantinePath))
.build());
blob.delete();
}
private void storeImageMetadata(StorageEvent event, List<String> labels) {
// 存储元数据到Datastore
Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
Key key = datastore.newKeyFactory()
.setKind("ImageMetadata")
.newKey(UUID.randomUUID().toString());
Entity entity = Entity.newBuilder(key)
.set("fileName", event.getName())
.set("bucket", event.getBucket())
.set("contentType", event.getContentType())
.set("size", event.getSize())
.set("processedAt", Timestamp.now())
.set("labels", labels)
.build();
datastore.put(entity);
}
}
存储事件类
package com.example.gcp;
import java.util.Map;
public class StorageEvent {
private String bucket;
private String name;
private String contentType;
private long size;
private String timeCreated;
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getTimeCreated() {
return timeCreated;
}
public void setTimeCreated(String timeCreated) {
this.timeCreated = timeCreated;
}
}
部署配置示例
AWS Lambda - serverless.yml
service: java-serverless-crud
provider:
name: aws
runtime: java11
region: us-east-1
environment:
DYNAMODB_TABLE: Users
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:Scan
Resource: "arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
userApi:
handler: com.example.lambda.UserServiceHandler
events:
- http:
path: users
method: get
cors: true
- http:
path: users
method: post
cors: true
- http:
path: users/{id}
method: get
cors: true
- http:
path: users/{id}
method: put
cors: true
- http:
path: users/{id}
method: delete
cors: true
resources:
Resources:
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.DYNAMODB_TABLE}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
BillingMode: PAY_PER_REQUEST
Azure Functions - host.json
{
"version": "2.0",
"functionTimeout": "00:10:00",
"extensions": {
"timer": {
"maxExecutionTime": "00:30:00"
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
}
}
最佳实践案例
无服务器API网关 + 认证
package com.example.secure;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
public class JwtTokenValidator {
private static final String SECRET_KEY = System.getenv("JWT_SECRET_KEY");
public static JwtUser validateToken(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("your-issuer")
.build();
DecodedJWT jwt = verifier.verify(token);
// 提取用户信息
JwtUser user = new JwtUser();
user.setUserId(jwt.getSubject());
user.setUsername(jwt.getClaim("username").asString());
user.setRoles(jwt.getClaim("roles").asList(String.class));
return user;
} catch (JWTVerificationException e) {
throw new AuthenticationException("无效的JWT令牌");
}
}
}
// 安全的Lambda处理器
public class SecureApiHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
// 1. 获取Authorization头
String authorizationHeader = input.getHeaders().get("Authorization");
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
return unauthorizedResponse();
}
// 2. 验证JWT令牌
String token = authorizationHeader.substring(7);
try {
JwtUser user = JwtTokenValidator.validateToken(token);
// 3. 检查用户权限
if (!user.hasRole("ADMIN")) {
return forbiddenResponse();
}
// 4. 处理业务逻辑
return processRequest(input, user);
} catch (AuthenticationException e) {
return unauthorizedResponse();
}
}
}
这些案例涵盖了Java无服务器计算的核心场景:
- AWS Lambda:API网关集成、DynamoDB操作、CRUD应用
- Azure Functions:定时任务、事件处理、队列操作
- Google Cloud Functions:图片处理、内容检测、存储事件
- 安全和最佳实践:JWT认证、权限控制
每个案例都展示了无服务器应用的关键特性:
- 事件驱动架构
- 自动扩缩容
- 按需计费
- 与其他云服务集成
- 无服务器特性(连接管理、状态管理等)
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播