成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

100萬QPS短鏈系統(tǒng)如何設(shè)計(jì)?

開發(fā) 前端
為了從根本上改善這一痛點(diǎn),本文將系統(tǒng)介紹如何基于 Spring Boot 3.4.5 + Spring Cloud Context 實(shí)現(xiàn)無需重啟即可動(dòng)態(tài)更新配置文件的機(jī)制,覆蓋原理解析、實(shí)戰(zhàn)代碼、注意事項(xiàng),助你提升至少 50% 的配置變更效率。

前言

凌晨兩點(diǎn),監(jiān)控大屏突然飆紅——短鏈服務(wù)QPS突破80萬! 數(shù)據(jù)庫連接池告急,Redis集群響應(yīng)延遲突破500ms。

這不是演習(xí),而是某電商平臺(tái)大促的真實(shí)場(chǎng)景。

當(dāng)每秒百萬級(jí)請(qǐng)求涌向你的短鏈服務(wù),你該如何設(shè)計(jì)系統(tǒng)?

今天這篇文章跟大家一起聊聊100萬QPS短鏈系統(tǒng)要如何設(shè)計(jì)?

希望對(duì)你會(huì)有所幫助。

最近建了一些工作內(nèi)推群,各大城市都有,歡迎各位HR和找工作的小伙伴進(jìn)群交流,群里目前已經(jīng)收集了不少的工作內(nèi)推崗位。

1.短鏈系統(tǒng)的核心挑戰(zhàn)

首先我們一起看看設(shè)計(jì)一個(gè)高并發(fā)的短鏈系統(tǒng),會(huì)遇到哪些核心的挑戰(zhàn)。

如下圖所示:

圖片圖片

百萬QPS下的三大生死關(guān):

  • ID生成瓶頸:傳統(tǒng)數(shù)據(jù)庫自增ID撐不住百萬并發(fā)
  • 跳轉(zhuǎn)性能黑洞:302重定向的TCP連接成本
  • 緩存雪崩風(fēng)險(xiǎn):熱點(diǎn)短鏈瞬間擊穿Redis

2.短鏈生成

2.1 發(fā)號(hào)器的設(shè)計(jì)

發(fā)號(hào)器是短鏈系統(tǒng)的發(fā)動(dòng)機(jī)。

方案對(duì)比:

方案

吞吐量

缺點(diǎn)

適用場(chǎng)景

UUID

5萬/s

長度長,無法排序

小型系統(tǒng)

Redis自增ID

8萬/s

依賴緩存持久化

中型系統(tǒng)

Snowflake

12萬/s

時(shí)鐘回?fù)軉栴}

中大型系統(tǒng)

分段發(fā)號(hào)

50萬/s

需要預(yù)分配

超大型系統(tǒng)

分段發(fā)號(hào)器實(shí)現(xiàn)(Java版):

public class SegmentIDGen {
    privatefinal AtomicLong currentId = new AtomicLong(0);
    privatevolatilelong maxId;
    privatefinal ExecutorService loader = Executors.newSingleThreadExecutor();

    public void init() {
        loadSegment();
        loader.submit(this::daemonLoad);
    }

    private void loadSegment() {
        // 從DB獲取號(hào)段:SELECT max_id FROM alloc WHERE biz_tag='short_url'
        this.maxId = dbMaxId + 10000; // 每次取1萬個(gè)號(hào)
        currentId.set(dbMaxId);
    }

    private void daemonLoad() {
        while (currentId.get() > maxId * 0.8) {
            loadSegment(); // 號(hào)段使用80%時(shí)異步加載
        }
    }

    public long nextId() {
        if (currentId.get() >= maxId) thrownew BusyException();
        return currentId.incrementAndGet();
    }
}

關(guān)鍵優(yōu)化

  • 雙Buffer異步加載(避免加載阻塞)
  • 監(jiān)控號(hào)段使用率(動(dòng)態(tài)調(diào)整步長)
  • 多實(shí)例分段隔離(biz_tag區(qū)分業(yè)務(wù))

2.2 短鏈映射算法

短碼映射將長ID轉(zhuǎn)換成62進(jìn)制的字符串。

轉(zhuǎn)換原理:

2000000000 = 2×62^4 + 17×62^3 + 35×62^2 + 10×62 + 8 
           = "Cdz9a"

原始ID: 2000000000,轉(zhuǎn)換為62進(jìn)制的值為Cdz9a。

// Base62編碼(0-9a-zA-Z)
publicclass Base62Encoder {
    privatestaticfinal String BASE62 = 
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    
    public static String encode(long id) {
        StringBuilder sb = new StringBuilder();
        while (id > 0) {
            sb.append(BASE62.charAt((int)(id % 62)));
            id /= 62;
        }
        return sb.reverse().toString();
    }
    
    // 測(cè)試:生成8位短碼
    public static void main(String[] args) {
        long id = 1_000_000_000L;
        System.out.println(encode(id)); // 輸出:BFp3qQ
    }
}

編碼優(yōu)勢(shì):

  • 6位短碼可表示 62^6 ≈ 568億種組合
  • 8位短碼可表示 62^8 ≈ 218萬億種組合
  • 無意義字符串避免被猜測(cè)

3.存儲(chǔ)架構(gòu)

3.1 數(shù)據(jù)存儲(chǔ)模型設(shè)計(jì)

圖片圖片

3.2 緩存層級(jí)設(shè)計(jì)

圖片圖片

3.3 緩存擊穿解決方案

// Redis緩存擊穿防護(hù)
public String getLongUrl(String shortCode) {
    // 1. 布隆過濾器預(yù)檢
    if (!bloomFilter.mightContain(shortCode)) {
        returnnull;
    }
    
    // 2. 查Redis
    String cacheKey = "url:" + shortCode;
    String longUrl = redis.get(cacheKey);
    if (longUrl != null) {
        return longUrl;
    }
    
    // 3. 獲取分布式鎖
    String lockKey = "lock:" + shortCode;
    if (redis.setnx(lockKey, "1", 10)) { // 10秒超時(shí)
        try {
            // 4. 二次檢查緩存
            longUrl = redis.get(cacheKey);
            if (longUrl != null) return longUrl;
            
            // 5. 查數(shù)據(jù)庫
            longUrl = db.queryLongUrl(shortCode);
            if (longUrl != null) {
                // 6. 回填Redis
                redis.setex(cacheKey, 3600, longUrl);
            }
            return longUrl;
        } finally {
            redis.del(lockKey);
        }
    } else {
        // 7. 等待重試
        Thread.sleep(50);
        return getLongUrl(shortCode);
    }
}

防護(hù)要點(diǎn):

  • 布隆過濾器攔截非法短碼
  • 分布式鎖防止緩存擊穿
  • 雙重檢查減少DB壓力
  • 指數(shù)退避重試策略

4.跳轉(zhuǎn)優(yōu)化

4.1 Nginx層直接跳轉(zhuǎn)

server {
    listen 80;
    server_name s.domain.com;

    location ~ ^/([a-zA-Z0-9]{6,8})$ {
        set $short_code $1;

        # 查詢Redis
        redis_pass redis_cluster;
        redis_query GET url:$short_code;

        # 命中則直接302跳轉(zhuǎn)
        if ($redis_value != "") {
            add_header Cache-Control "private, max-age=86400";
            return 302 $redis_value;
        }

        # 未命中轉(zhuǎn)發(fā)到后端
        proxy_pass http://backend;
    }
}

性能收益:

  • 跳轉(zhuǎn)延遲從100ms降至5ms
  • 節(jié)省后端服務(wù)器資源
  • 支持百萬級(jí)并發(fā)連接

4.2 連接池優(yōu)化

連接池優(yōu)化可以用Netty實(shí)現(xiàn):

// Netty HTTP連接池配置
publicclass HttpConnectionPool {
    privatefinal EventLoopGroup group = new NioEventLoopGroup();
    privatefinal Bootstrap bootstrap = new Bootstrap();
    
    public HttpConnectionPool() {
        bootstrap.group(group)
            .channel(NioSocketChannel.class)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .handler(new HttpClientInitializer());
    }
    
    public Channel getChannel(String host, int port) throws InterruptedException {
        return bootstrap.connect(host, port).sync().channel();
    }
    
    // 使用示例
    public void redirect(ChannelHandlerContext ctx, String longUrl) {
        Channel channel = getChannel("target.com", 80);
        channel.writeAndFlush(new DefaultFullHttpRequest(
            HttpVersion.HTTP_1_1, 
            HttpMethod.GET, 
            longUrl
        ));
        // 處理響應(yīng)...
    }
}

優(yōu)化效果:

  • TCP連接復(fù)用率提升10倍
  • 減少80%的TCP握手開銷
  • QPS承載能力提升3倍

5.百萬QPS整體架構(gòu)

百萬QPS整體架構(gòu)如下圖所示:

圖片圖片

核心組件解析:

1)接入層

  • CDN:緩存靜態(tài)資源
  • Nginx:處理302跳轉(zhuǎn),本地緩存熱點(diǎn)數(shù)據(jù)

2)緩存層

  • Redis集群:緩存短鏈映射
  • 布隆過濾器:攔截非法請(qǐng)求

3)服務(wù)層

  • 短鏈生成:分布式ID服務(wù)
  • 映射查詢:高并發(fā)查詢服務(wù)

4)存儲(chǔ)層

  • MySQL:分庫分表存儲(chǔ)映射關(guān)系
  • TiKV:分布式KV存儲(chǔ)ID生成狀態(tài)

6.容災(zāi)設(shè)計(jì)

6.1 限流熔斷策略

基于Sentinel的熔斷降級(jí):

public class RedirectController {
    @GetMapping("/{shortCode}")
    @SentinelResource(
        value = "redirectService", 
        fallback = "fallbackRedirect",
        blockHandler = "blockRedirect"
    )
    public ResponseEntity redirect(@PathVariable String shortCode) {
        // 跳轉(zhuǎn)邏輯...
    }
    
    // 熔斷降級(jí)方法
    public ResponseEntity fallbackRedirect(String shortCode, Throwable ex) {
        return ResponseEntity.status(503)
            .body("服務(wù)暫時(shí)不可用");
    }
    
    // 限流處理方法
    public ResponseEntity blockRedirect(String shortCode, BlockException ex) {
        return ResponseEntity.status(429)
            .body("請(qǐng)求過于頻繁");
    }
}

6.2 多級(jí)降級(jí)方案

使用多級(jí)降級(jí)方案:

圖片圖片

保證服務(wù)的高可用。

6.3 數(shù)據(jù)分片策略

基于短碼分庫分表:

public int determineDbShard(String shortCode) {
    // 取短碼首字母的ASCII值
    int ascii = (int) shortCode.charAt(0);
    // 分16個(gè)庫
    return ascii % 16;
}

public int determineTableShard(String shortCode) {
    // 取短碼的CRC32值
    CRC32 crc32 = new CRC32();
    crc32.update(shortCode.getBytes());
    // 每庫1024張表
    return (int) (crc32.getValue() % 1024);
}

這里成了16個(gè)庫,每個(gè)庫有1024張表。

7.性能壓測(cè)數(shù)據(jù)對(duì)比

優(yōu)化點(diǎn)

優(yōu)化前QPS

優(yōu)化后QPS

提升倍數(shù)

原始方案

12,000

-

1x

+Redis緩存

120,000

10x


+Nginx直跳

350,000

2.9x


+連接池優(yōu)化

780,000

2.2x


+布隆過濾器

1,200,000

1.5x



壓測(cè)環(huán)境:32核64G服務(wù)器 × 10臺(tái),千兆內(nèi)網(wǎng)

總結(jié)

百萬QPS短鏈架構(gòu)核心要點(diǎn)如圖所示:

圖片圖片

四大設(shè)計(jì)原則:

  • 無狀態(tài)設(shè)計(jì):跳轉(zhuǎn)服務(wù)完全無狀態(tài),支持無限擴(kuò)展
  • 讀多寫少優(yōu)化:將讀性能壓榨到極致
  • 分而治之:數(shù)據(jù)分片,流量分散
  • 柔性可用:寧可部分降級(jí),不可全線崩潰

真正的架構(gòu)藝術(shù)不在于復(fù)雜,而在于在百萬QPS洪流中,用最簡單的路徑解決問題。當(dāng)你的系統(tǒng)能在流量風(fēng)暴中優(yōu)雅舞蹈,才是架構(gòu)師的巔峰時(shí)刻。

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2022-09-13 17:45:40

長網(wǎng)址短鏈系統(tǒng)

2024-11-12 08:13:09

2024-11-19 16:31:23

2022-10-09 14:15:42

短鏈設(shè)計(jì)

2022-09-13 08:01:58

短鏈服務(wù)哈希算法字符串

2023-08-10 10:13:35

轉(zhuǎn)轉(zhuǎn)短鏈平臺(tái)

2025-04-30 08:56:34

2025-06-04 03:15:00

高并發(fā)短鏈系統(tǒng)

2023-07-26 13:29:43

高性能短鏈系統(tǒng)

2024-07-22 11:48:42

2019-05-05 09:28:59

架構(gòu)數(shù)據(jù)查詢

2019-07-29 14:40:26

架構(gòu)存儲(chǔ)檢索

2024-06-28 09:59:35

2022-11-21 09:57:18

網(wǎng)關(guān)系統(tǒng)

2015-05-15 13:21:22

URL系統(tǒng)設(shè)計(jì)

2025-04-27 01:22:00

QPS高并發(fā)MySQL

2025-04-27 10:10:04

2022-02-09 20:50:46

短鏈系統(tǒng)場(chǎng)景

2009-03-02 09:13:00

LinuxFedora操作系統(tǒng)

2018-09-20 09:33:38

單機(jī)QPSRedis
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 美日韩免费 | 婷婷在线网站 | 亚洲精品久久久久久一区二区 | 热99视频 | 欧美色综合一区二区三区 | 日韩中文字幕免费在线观看 | 日本高清精品 | 午夜视频一区二区 | 精品国产一区二区三区性色 | 亚洲视频欧美视频 | 日本三级黄视频 | 欧美午夜影院 | 在线观看亚洲专区 | 国产一区2区 | 国产一区二区电影 | 一区二区三区视频在线观看 | 日韩久久中文字幕 | 国产黄色大片在线免费观看 | 北条麻妃99精品青青久久 | 欧美三级视频在线观看 | 久久久久久久久久久91 | 在线观看中文字幕亚洲 | 国产午夜久久久 | 久久久久久久久久久91 | 欧美日韩三级视频 | 中文字幕一区二区三区日韩精品 | 国产人免费人成免费视频 | 国产在线视频一区 | 午夜免费电影院 | 日韩中文一区 | 在线视频一区二区三区 | 欧美在线一区二区三区 | 一级毛片中国 | 国产精品久久久久aaaa | 欧美一区2区三区4区公司 | 国产一区欧美 | 中文字幕一区二区三区四区五区 | 久久综合国产 | 成人国产精品入口免费视频 | 久久久久久国产精品免费免费 | 国产一区不卡 |