本文目录导读:

我将为您提供雪花算法的完整实现案例,包含多个语言的实现和详细说明。
Java 实现
public class SnowflakeIdGenerator {
// 各部分位数定义
private static final long SEQUENCE_BITS = 12L; // 序列号占12位
private static final long WORKER_ID_BITS = 5L; // 机器ID占5位
private static final long DATACENTER_ID_BITS = 5L; // 数据中心ID占5位
// 最大值计算
private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS); // 最大机器ID
private static final long MAX_DATACENTER_ID = -1L ^ (-1L << DATACENTER_ID_BITS); // 最大数据中心ID
private static final long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BITS); // 最大序列号
// 位移量
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; // 机器ID左移位数
private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; // 数据中心ID左移位数
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS; // 时间戳左移位数
// 起始时间戳(2020-01-01,可自定义)
private static final long START_TIMESTAMP = 1577808000000L;
// 成员变量
private final long workerId; // 机器ID
private final long datacenterId; // 数据中心ID
private long sequence = 0L; // 序列号
private long lastTimestamp = -1L; // 上次生成ID的时间戳
/**
* 构造函数
*/
public SnowflakeIdGenerator(long workerId, long datacenterId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException(String.format("Worker ID 必须介于 0 和 %d 之间", MAX_WORKER_ID));
}
if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
throw new IllegalArgumentException(String.format("Datacenter ID 必须介于 0 和 %d 之间", MAX_DATACENTER_ID));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 生成下一个ID
*/
public synchronized long nextId() {
long timestamp = getCurrentTimestamp();
// 时间回退检查
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("时钟回拨,拒绝生成ID,回拨时间:%d ms", lastTimestamp - timestamp));
}
// 同一毫秒内
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
// 序列号用尽
if (sequence == 0) {
timestamp = getNextTimestamp(lastTimestamp);
}
} else {
// 不同毫秒,序列号重置
sequence = 0L;
}
lastTimestamp = timestamp;
// 组装ID
return ((timestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT) |
(datacenterId << DATACENTER_ID_SHIFT) |
(workerId << WORKER_ID_SHIFT) |
sequence;
}
/**
* 获取当前时间戳
*/
private long getCurrentTimestamp() {
return System.currentTimeMillis();
}
/**
* 获取下一个时间戳
*/
private long getNextTimestamp(long lastTimestamp) {
long timestamp = getCurrentTimestamp();
while (timestamp <= lastTimestamp) {
timestamp = getCurrentTimestamp();
}
return timestamp;
}
// 解析ID(用于调试)
public static Map<String, Long> parseId(long id) {
Map<String, Long> result = new HashMap<>();
result.put("timestamp", (id >> TIMESTAMP_SHIFT) + START_TIMESTAMP);
result.put("datacenterId", (id >> DATACENTER_ID_SHIFT) & MAX_DATACENTER_ID);
result.put("workerId", (id >> WORKER_ID_SHIFT) & MAX_WORKER_ID);
result.put("sequence", id & MAX_SEQUENCE);
return result;
}
// 测试示例
public static void main(String[] args) {
SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);
// 连续生成10个ID
for (int i = 0; i < 10; i++) {
long id = generator.nextId();
System.out.println("ID: " + id + " (长度: " + Long.toBinaryString(id).length() + "位)");
System.out.println("解析: " + parseId(id));
}
// 性能测试
long startTime = System.currentTimeMillis();
int testCount = 1000000;
for (int i = 0; i < testCount; i++) {
generator.nextId();
}
long endTime = System.currentTimeMillis();
System.out.println("\n生成 " + testCount + " 个ID耗时: " + (endTime - startTime) + " ms");
}
}
Python 实现
import time
import threading
class SnowflakeIdGenerator:
def __init__(self, worker_id, datacenter_id, start_timestamp=None):
# 定义位数
self.SEQUENCE_BITS = 12
self.WORKER_ID_BITS = 5
self.DATACENTER_ID_BITS = 5
# 计算最大值
self.MAX_WORKER_ID = -1 ^ (-1 << self.WORKER_ID_BITS)
self.MAX_DATACENTER_ID = -1 ^ (-1 << self.DATACENTER_ID_BITS)
self.MAX_SEQUENCE = -1 ^ (-1 << self.SEQUENCE_BITS)
# 位移量
self.WORKER_ID_SHIFT = self.SEQUENCE_BITS
self.DATACENTER_ID_SHIFT = self.SEQUENCE_BITS + self.WORKER_ID_BITS
self.TIMESTAMP_SHIFT = self.SEQUENCE_BITS + self.WORKER_ID_BITS + self.DATACENTER_ID_BITS
# 起始时间戳(默认2020-01-01)
self.START_TIMESTAMP = start_timestamp or 1577808000000
# 验证参数
if worker_id > self.MAX_WORKER_ID or worker_id < 0:
raise ValueError(f"worker_id 必须介于 0 和 {self.MAX_WORKER_ID} 之间")
if datacenter_id > self.MAX_DATACENTER_ID or datacenter_id < 0:
raise ValueError(f"datacenter_id 必须介于 0 和 {self.MAX_DATACENTER_ID} 之间")
# 初始化成员变量
self.worker_id = worker_id
self.datacenter_id = datacenter_id
self.sequence = 0
self.last_timestamp = -1
# 线程锁
self.lock = threading.Lock()
def _get_current_timestamp(self):
return int(time.time() * 1000)
def _get_next_timestamp(self, last_timestamp):
timestamp = self._get_current_timestamp()
while timestamp <= last_timestamp:
timestamp = self._get_current_timestamp()
return timestamp
def next_id(self):
with self.lock:
timestamp = self._get_current_timestamp()
# 时钟回拨检查
if timestamp < self.last_timestamp:
raise Exception(f"clock moved backwards. Refusing to generate id for {self.last_timestamp - timestamp} milliseconds")
# 同一毫秒内
if self.last_timestamp == timestamp:
self.sequence = (self.sequence + 1) & self.MAX_SEQUENCE
# 序列号用尽
if self.sequence == 0:
timestamp = self._get_next_timestamp(self.last_timestamp)
else:
# 新毫秒,序列号重置
self.sequence = 0
self.last_timestamp = timestamp
# 组装ID
return ((timestamp - self.START_TIMESTAMP) << self.TIMESTAMP_SHIFT) | \
(self.datacenter_id << self.DATACENTER_ID_SHIFT) | \
(self.worker_id << self.WORKER_ID_SHIFT) | \
self.sequence
def parse_id(self, snowflake_id):
"""解析ID的各个部分"""
result = {
'timestamp': (snowflake_id >> self.TIMESTAMP_SHIFT) + self.START_TIMESTAMP,
'datacenter_id': (snowflake_id >> self.DATACENTER_ID_SHIFT) & self.MAX_DATACENTER_ID,
'worker_id': (snowflake_id >> self.WORKER_ID_SHIFT) & self.MAX_WORKER_ID,
'sequence': snowflake_id & self.MAX_SEQUENCE
}
return result
# 使用示例
if __name__ == "__main__":
generator = SnowflakeIdGenerator(worker_id=1, datacenter_id=1)
print("=== 单线程测试 ===")
for i in range(5):
snowflake_id = generator.next_id()
print(f"ID: {snowflake_id}, 解析: {generator.parse_id(snowflake_id)}")
print("\n=== 多线程测试 ===")
import threading
def generate_ids():
for i in range(100):
snowflake_id = generator.next_id()
print(f"Thread {threading.current_thread().name}: {snowflake_id}")
threads = [threading.Thread(target=generate_ids) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
print(f"\n最终状态 - 最后时间戳: {generator.last_timestamp}, 序列号: {generator.sequence}")
Go 实现
package main
import (
"fmt"
"sync"
"time"
)
// SnowflakeIdConfig 配置
type SnowflakeIdConfig struct {
WorkerID int64
DatacenterID int64
StartTimestamp int64 // 可自定义起始时间戳
}
// SnowflakeIdGenerator 雪花算法生成器
type SnowflakeIdGenerator struct {
// 各部分位数
sequenceBits int64 // 序列号占12位
workerIDBits int64 // 机器ID占5位
datacenterIDBits int64 // 数据中心ID占5位
// 最大值
maxWorkerID int64
maxDatacenterID int64
maxSequence int64
// 位移量
workerIDShift int64
datacenterIDShift int64
timestampShift int64
// 起始时间戳(毫秒)
startTimestamp int64
// 状态
workerID int64
datacenterID int64
sequence int64
lastTimestamp int64
// 互斥锁
mutex sync.Mutex
}
// NewSnowflakeIdGenerator 创建生成器
func NewSnowflakeIdGenerator(config SnowflakeIdConfig) (*SnowflakeIdGenerator, error) {
generator := &SnowflakeIdGenerator{
sequenceBits: 12,
workerIDBits: 5,
datacenterIDBits: 5,
}
// 计算最大值
generator.maxWorkerID = -1 ^ (-1 << generator.workerIDBits)
generator.maxDatacenterID = -1 ^ (-1 << generator.datacenterIDBits)
generator.maxSequence = -1 ^ (-1 << generator.sequenceBits)
// 计算位移量
generator.workerIDShift = generator.sequenceBits
generator.datacenterIDShift = generator.sequenceBits + generator.workerIDBits
generator.timestampShift = generator.sequenceBits + generator.workerIDBits + generator.datacenterIDBits
// 设置起始时间戳(默认2020-01-01)
if config.StartTimestamp == 0 {
generator.startTimestamp = 1577808000000
} else {
generator.startTimestamp = config.StartTimestamp
}
// 验证参数
if config.WorkerID > generator.maxWorkerID || config.WorkerID < 0 {
return nil, fmt.Errorf("worker ID 必须介于 0 和 %d 之间", generator.maxWorkerID)
}
if config.DatacenterID > generator.maxDatacenterID || config.DatacenterID < 0 {
return nil, fmt.Errorf("datacenter ID 必须介于 0 和 %d 之间", generator.maxDatacenterID)
}
generator.workerID = config.WorkerID
generator.datacenterID = config.DatacenterID
generator.sequence = 0
generator.lastTimestamp = -1
return generator, nil
}
// getCurrentTimestamp 获取当前毫秒时间戳
func (g *SnowflakeIdGenerator) getCurrentTimestamp() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
}
// getNextTimestamp 获取下一个毫秒时间戳
func (g *SnowflakeIdGenerator) getNextTimestamp(lastTimestamp int64) int64 {
timestamp := g.getCurrentTimestamp()
for timestamp <= lastTimestamp {
timestamp = g.getCurrentTimestamp()
}
return timestamp
}
// NextID 生成下一个ID
func (g *SnowflakeIdGenerator) NextID() (int64, error) {
g.mutex.Lock()
defer g.mutex.Unlock()
timestamp := g.getCurrentTimestamp()
// 时钟回拨检查
if timestamp < g.lastTimestamp {
return 0, fmt.Errorf("时钟回拨,拒绝生成ID,回拨时间:%d ms", g.lastTimestamp-timestamp)
}
// 同一毫秒内
if g.lastTimestamp == timestamp {
g.sequence = (g.sequence + 1) & g.maxSequence
// 序列号用尽
if g.sequence == 0 {
timestamp = g.getNextTimestamp(g.lastTimestamp)
}
} else {
// 新毫秒,序列号重置
g.sequence = 0
}
g.lastTimestamp = timestamp
// 组装ID
return ((timestamp - g.startTimestamp) << g.timestampShift) |
(g.datacenterID << g.datacenterIDShift) |
(g.workerID << g.workerIDShift) |
g.sequence, nil
}
// ParseID 解析ID
func (g *SnowflakeIdGenerator) ParseID(id int64) map[string]int64 {
result := make(map[string]int64)
result["timestamp"] = (id >> g.timestampShift) + g.startTimestamp
result["datacenterID"] = (id >> g.datacenterIDShift) & g.maxDatacenterID
result["workerID"] = (id >> g.workerIDShift) & g.maxWorkerID
result["sequence"] = id & g.maxSequence
return result
}
func main() {
// 创建生成器
generator, err := NewSnowflakeIdGenerator(SnowflakeIdConfig{
WorkerID: 1,
DatacenterID: 1,
})
if err != nil {
fmt.Printf("创建生成器失败: %v\n", err)
return
}
// 单线程测试
fmt.Println("=== 单线程测试 ===")
for i := 0; i < 5; i++ {
id, _ := generator.NextID()
fmt.Printf("ID: %d, 解析: %v\n", id, generator.ParseID(id))
}
// 多线程测试
fmt.Println("\n=== 多线程测试 ===")
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(threadNum int) {
defer wg.Done()
for j := 0; j < 100; j++ {
id, _ := generator.NextID()
fmt.Printf("线程 %d: %d\n", threadNum, id)
}
}(i)
}
wg.Wait()
// 性能测试
fmt.Println("\n=== 性能测试 ===")
start := time.Now()
const testCount = 1000000
for i := 0; i < testCount; i++ {
generator.NextID()
}
elapsed := time.Since(start)
fmt.Printf("生成 %d 个ID耗时: %v\n", testCount, elapsed)
}
Node.js (JavaScript) 实现
class SnowflakeIdGenerator {
constructor(workerId, datacenterId, startTimestamp = 1577808000000) {
// 定义位数
this.SEQUENCE_BITS = 12n;
this.WORKER_ID_BITS = 5n;
this.DATACENTER_ID_BITS = 5n;
// 计算最大值
this.MAX_WORKER_ID = -1n ^ (-1n << this.WORKER_ID_BITS);
this.MAX_DATACENTER_ID = -1n ^ (-1n << this.DATACENTER_ID_BITS);
this.MAX_SEQUENCE = -1n ^ (-1n << this.SEQUENCE_BITS);
// 位移量
this.WORKER_ID_SHIFT = this.SEQUENCE_BITS;
this.DATACENTER_ID_SHIFT = this.SEQUENCE_BITS + this.WORKER_ID_BITS;
this.TIMESTAMP_SHIFT = this.SEQUENCE_BITS + this.WORKER_ID_BITS + this.DATACENTER_ID_BITS;
// 起始时间戳
this.START_TIMESTAMP = BigInt(startTimestamp);
// 验证参数
if (workerId < 0n || workerId > this.MAX_WORKER_ID) {
throw new Error(`Worker ID 必须介于 0 和 ${this.MAX_WORKER_ID} 之间`);
}
if (datacenterId < 0n || datacenterId > this.MAX_DATACENTER_ID) {
throw new Error(`Datacenter ID 必须介于 0 和 ${this.MAX_DATACENTER_ID} 之间`);
}
// 初始化状态
this.workerId = BigInt(workerId);
this.datacenterId = BigInt(datacenterId);
this.sequence = 0n;
this.lastTimestamp = -1n;
}
getCurrentTimestamp() {
return BigInt(Date.now());
}
getNextTimestamp(lastTimestamp) {
let timestamp = this.getCurrentTimestamp();
while (timestamp <= lastTimestamp) {
timestamp = this.getCurrentTimestamp();
}
return timestamp;
}
nextId() {
let timestamp = this.getCurrentTimestamp();
// 时钟回拨检查
if (timestamp < this.lastTimestamp) {
throw new Error(`时钟回拨,拒绝生成ID,回拨时间:${this.lastTimestamp - timestamp} ms`);
}
// 同一毫秒内
if (this.lastTimestamp === timestamp) {
this.sequence = (this.sequence + 1n) & this.MAX_SEQUENCE;
// 序列号用尽
if (this.sequence === 0n) {
timestamp = this.getNextTimestamp(this.lastTimestamp);
}
} else {
// 新毫秒,序列号重置
this.sequence = 0n;
}
this.lastTimestamp = timestamp;
// 组装ID
return ((timestamp - this.START_TIMESTAMP) << this.TIMESTAMP_SHIFT) |
(this.datacenterId << this.DATACENTER_ID_SHIFT) |
(this.workerId << this.WORKER_ID_SHIFT) |
this.sequence;
}
parseId(id) {
return {
timestamp: Number((id >> this.TIMESTAMP_SHIFT) + this.START_TIMESTAMP),
datacenterId: Number((id >> this.DATACENTER_ID_SHIFT) & this.MAX_DATACENTER_ID),
workerId: Number((id >> this.WORKER_ID_SHIFT) & this.MAX_WORKER_ID),
sequence: Number(id & this.MAX_SEQUENCE)
};
}
}
// 使用示例
const generator = new SnowflakeIdGenerator(1n, 1n);
console.log("=== 测试生成ID ===");
for (let i = 0; i < 5; i++) {
const id = generator.nextId();
console.log(`ID: ${id.toString()}`);
console.log(`解析: ${JSON.stringify(generator.parseId(id))}`);
}
// 性能测试
console.log("\n=== 性能测试 ===");
const start = Date.now();
const count = 100000;
for (let i = 0; i < count; i++) {
generator.nextId();
}
const end = Date.now();
console.log(`生成 ${count} 个ID耗时: ${end - start} ms`);
C# 实现
using System;
using System.Collections.Generic;
using System.Threading;
public class SnowflakeIdGenerator
{
// 各部分位数
private const long SEQUENCE_BITS = 12L;
private const long WORKER_ID_BITS = 5L;
private const long DATACENTER_ID_BITS = 5L;
// 最大值
private const long MAX_WORKER_ID = -1L ^ (-1L << (int)WORKER_ID_BITS);
private const long MAX_DATACENTER_ID = -1L ^ (-1L << (int)DATACENTER_ID_BITS);
private const long MAX_SEQUENCE = -1L ^ (-1L << (int)SEQUENCE_BITS);
// 位移量
private const long WORKER_ID_SHIFT = SEQUENCE_BITS;
private const long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
private const long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
// 起始时间戳(2020-01-01)
private const long START_TIMESTAMP = 1577808000000L;
// 成员变量
private readonly long workerId;
private readonly long datacenterId;
private long sequence = 0L;
private long lastTimestamp = -1L;
private readonly object lockObject = new object();
public SnowflakeIdGenerator(long workerId, long datacenterId)
{
if (workerId > MAX_WORKER_ID || workerId < 0)
throw new ArgumentException($"Worker ID 必须介于 0 和 {MAX_WORKER_ID} 之间");
if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0)
throw new ArgumentException($"Datacenter ID 必须介于 0 和 {MAX_DATACENTER_ID} 之间");
this.workerId = workerId;
this.datacenterId = datacenterId;
}
private long GetCurrentTimestamp()
{
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
private long GetNextTimestamp(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
public long NextId()
{
lock (lockObject)
{
long timestamp = GetCurrentTimestamp();
// 时钟回拨检查
if (timestamp < lastTimestamp)
{
throw new Exception($"时钟回拨,拒绝生成ID,回拨时间:{lastTimestamp - timestamp} ms");
}
// 同一毫秒内
if (lastTimestamp == timestamp)
{
sequence = (sequence + 1) & MAX_SEQUENCE;
// 序列号用尽
if (sequence == 0)
{
timestamp = GetNextTimestamp(lastTimestamp);
}
}
else
{
// 新毫秒,序列号重置
sequence = 0L;
}
lastTimestamp = timestamp;
// 组装ID
return ((timestamp - START_TIMESTAMP) << (int)TIMESTAMP_SHIFT) |
(datacenterId << (int)DATACENTER_ID_SHIFT) |
(workerId << (int)WORKER_ID_SHIFT) |
sequence;
}
}
public Dictionary<string, long> ParseId(long id)
{
var result = new Dictionary<string, long>
{
["timestamp"] = (id >> (int)TIMESTAMP_SHIFT) + START_TIMESTAMP,
["datacenterId"] = (id >> (int)DATACENTER_ID_SHIFT) & MAX_DATACENTER_ID,
["workerId"] = (id >> (int)WORKER_ID_SHIFT) & MAX_WORKER_ID,
["sequence"] = id & MAX_SEQUENCE
};
return result;
}
}
class Program
{
static void Main(string[] args)
{
var generator = new SnowflakeIdGenerator(1, 1);
Console.WriteLine("=== 测试生成ID ===");
for (int i = 0; i < 5; i++)
{
long id = generator.NextId();
Console.WriteLine($"ID: {id}");
Console.WriteLine($"解析: {string.Join(", ", generator.ParseId(id))}");
}
// 多线程测试
Console.WriteLine("\n=== 多线程测试 ===");
var threads = new List<Thread>();
for (int i = 0; i < 5; i++)
{
int threadNum = i;
var thread = new Thread(() =>
{
for (int j = 0; j < 100; j++)
{
long id = generator.NextId();
Console.WriteLine($"线程 {threadNum}: {id}");
}
});
threads.Add(thread);
thread.Start();
}
foreach (var thread in threads)
{
thread.Join();
}
// 性能测试
Console.WriteLine("\n=== 性能测试 ===");
var start = DateTime.Now;
const int count = 1000000;
for (int i = 0; i < count; i++)
{
generator.NextId();
}
var end = DateTime.Now;
Console.WriteLine($"生成 {count} 个ID耗时: {(end - start).TotalMilliseconds} ms");
}
}
核心要点说明
1 ID结构
| 符号位(1位) | 时间戳(41位) | 数据中心ID(5位) | 机器ID(5位) | 序列号(12位) |
0 自定义起始时间 0-31 0-31 0-4095
2 关键特性
- 时间戳:41位,可以支持69年的使用时间
- 数据中心ID:5位,支持32个数据中心
- 机器ID:5位,每个数据中心支持32台机器
- 序列号:12位,同一毫秒内支持4096个ID
3 注意事项
- 时钟回拨问题:需要处理系统时钟回拨的情况
- 线程安全:需要保证并发环境下的线程安全
- 位运算:使用位移和异或运算来组装ID
4 扩展优化
- 可以增加时钟回拨等待机制
- 可以支持自定义起始时间戳
- 可以调整位数分配以适应不同场景
选择合适的实现语言,根据实际业务需求调整参数即可使用。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播