阿里最新開源配置中心和註冊中心: Nacos 限流最佳實踐

2021-02-25 芋道源碼

點擊上方「芋道源碼」,選擇「設為星標」

做積極的人,而不是積極廢人!


Nacos 限流最佳實踐

Tomcat 限流

Nginx 限流

總結

作者:風卿(Nacos 社區 committer)

本文系投稿。如果胖友有想要投稿的內容,歡迎後臺留言。哇咔咔。

Nacos 限流最佳實踐

Nacos自開源以來,版本迭代速度很快,已經發布了0.9版本,準備發1.0的正式版本,支持企業使用Nacos生產高可用。在生產環境,Nacos首先需要保證自身服務的穩定性,在正常的運行環境下不會出現服務掛掉的情況。當然在一些依賴的系統出問題的時候(比如磁碟和DB),Nacos服務會受到影響,需要監控系統發現這些問題並能及時的介入處理。

作為高性能的服務發現和配置管理服務,Nacos也是存在自己的性能基線的,當瞬時的高峰流量超過自身的性能基線的時候,需要對高峰流量進行限流,以保證整體服務的健康運行而不影響到其他核心應用。

Tomcat 限流

Nacos基於spring boot使用內嵌的tomcat,tomcat線程分為acceptor線程和worker線程,acceptor線程負責從內核accept隊列中取出連接並交給worker線程,而worker線程則負責處理連接(讀取參數、執行處理、返迴響應等)

當tomcat不能及時處理新的連接時,內核中新建的連接將會進入連接隊列排隊,acceptCount參數能夠設置tomcat accept連接隊列大小,當新的連接數超過acceptCount則拒絕連接,立即返回給client,不會讓client一直等待造成響應很慢或超時

接受了的連接需要由worker線程調度處理,當worker線程處理的連接數越來越多時,處理的速度會越來越慢造成client響應時間變長,需要根據系統和機器情況設置合理的maxConnections,當連接數到達maxConnections時,不再接受新的連接,讓新連接排隊等待,超出隊列長度則直接拒絕。

maxThreads參數設置tomcat的最大線程數,過高的線程數會讓系統運行的負載過高、響應變慢,過低的線程數讓系統的資源利用率太低,需要根據實際的運行情況(CPU、IO等)設置合理的最大線程數。

Nginx 限流

tomcat限流只能做到自身負載的調節,在實際生產環境中還遠遠不夠,需要依賴Nacos自身的限流來提高系統的限流能力。

Nacos的open API都是基於http協議,可以很方便地使用nginx來做限流,不需要自身再開發限流模塊來支持各種限流策略。nginx的基本使用以及nginx+lua模塊安裝網上資源很豐富,這裡就不再介紹。

Nacos每個接口執行的代價不盡相同,一般來說寫操作代價比讀操作大,與此同時還有高頻操作和低頻操作之分,SDK調用的接口一般來說是高頻接口,容易出現問題,所以在生產環境需要將這些接口區別對待,根據服務自身的實際情況採取合理的限流策略,以防錯用方打垮Nacos服務。下面介紹一下Nacos在生產環境的幾種限流場景

限制訪問速率1、限制單個接口的請求QPS

limit_get_config對讀操作進行限流,正常使用Nacos獲取動態配置一般就啟動和運行時修改配置推送到client,獲取配置相對來說是低頻操作,如果頻繁獲取配置肯定是client有錯用或者應用不正常(比如數據平臺任務failover重試任務)

limit_req_zone $limit_key zone=limit_get_config:10m rate=10r/s;

server {
        listen       8080;
        server_name  localhost;

        location /nacos/v1/cs/configs {
            if ($request_method = POST ) {
               rewrite ^ /limit_publish_config_url last;
            }

            rewrite ^ /limit_get_config_url last;
        }

        location /limit_get_config_url {
            set $limit_key "$remote_addr+$arg_dataid+$arg_group+$arg_tenant";
            limit_req zone=limit_get_config burst=10 nodelay;
            proxy_pass http://127.0.0.1:8848/nacos/v1/cs/configs;
        }
}

limit_req_zone設置限流key和內存大小,以及請求速率

limit_key由[ip,dataId,group,tenant]四元組組成,可以防止client錯用頻繁訪問單個配置

burst設置漏桶算法的桶的大小

nodelay設置非延遲模式,如果桶滿了則會馬上返回給客戶端錯誤碼

proxy_pass指定後端Nacos的接口url

limit_publish_config對寫操作進行限流,可以有效防止熱點寫問題。對同一個數據的高頻寫會觸發mysql的行鎖,從而導致mysql的多線程任務因等待行鎖排隊,最終導致mysql所有操作都超時服務不可用。這裡通過nginx lua模塊獲取post請求的參數,設置limit_key

limit_req_zone $limit_key zone=limit_publish_config:10m rate=5r/s;

location /limit_publish_config_url {
    set $dataId $arg_dataid;
    set $group $arg_group;
    set $tenant $arg_tenant;
    set $limit_key "$remote_addr+$dataId+$group+$tenant";
    lua_need_request_body on;
    rewrite_by_lua '
      ngx.req.read_body()
      local post_args = ngx.req.get_post_args()
      if post_args["dataId"] then
        ngx.var.dataId = post_args["dataId"];
        ngx.var.group = post_args["group"];
        ngx.var.tenant = post_args["tenant"];
        ngx.var.limit_key = ngx.var.remote_addr.."+"..ngx.var.dataId.."+"..ngx.var.group;
        if ngx.var.tenant then
          ngx.var.limit_key = ngx.var.limit_key.."+"..ngx.var.tenant;
        end
      end
    ';

    limit_req zone=limit_publish_config burst=10 nodelay;
    proxy_pass http://127.0.0.1:8848/nacos/v1/cs/configs;
}

2、限制單機訪問QPS

perclient對單個client的所有請求限制低於500QPS,可以有效防止單臺client的重試攻擊

limit_req_zone $remote_addr zone=perclient:10m rate=500r/s;

server {
        listen       8080;
        server_name  localhost;

        limit_req zone=perclient burst=250 nodelay;

        location / {
            proxy_pass http://127.0.0.1:8848/nacos/v1/cs/configs;
        }
}

3、限制 Nacos 服務 QPS

perserver限制整個Nacos服務的QPS,Nacos的服務部署在nginx之後,nginx可以保證到達Nacos的流量不會打垮Nacos

limit_req zone=perserver burst=1000 nodelay;

限制並發連接數

/nacos/v1/cs/configs/listener接口是Nacos的長連接通道,一般來說,一個client一個長連接就可以滿足生產需求。limit_conn_client限制client的連接數不超過10個,limit_conn_server限制Nacos單機(8核16G內存)支撐最多9000個長連接,最多可以同時服務9000個應用節點

limit_conn_zone $remote_addr zone=limit_conn_client:10m;
limit_conn_zone $server_name zone=limit_conn_server:10m;

server {
        listen       8080;
        server_name  localhost;
        location = /nacos/v1/cs/configs/listener {
            limit_conn limit_conn_client 10;
            limit_conn limit_conn_server 9000;
            proxy_pass   http://127.0.0.1:7001/diamond-server/config.co;
            tcp_nodelay     on;
            proxy_redirect  off;
            proxy_set_header Host            $host;
            proxy_set_header X-Real-IP       $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

黑名單1、IP黑名單

當生產環境發現有錯用的client影響到Nacos服務,可以使用nginx黑名單限制client的訪問

deny 30.5.125.70;

從被限制的IP訪問Nacos

curl -X GET "http://{IP}:8080/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test" -i

Nginx返回403狀態碼給client,禁止client訪問

HTTP/1.1 403 Forbidden
Server: nginx/1.13.5
Date: Fri, 15 Mar 2019 08:34:33 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.13.5</center>
</body>
</html>

2、讀寫黑名單分離

有時候通過IP維度直接限制client訪問所有Nacos接口粒度過大,會導致應用服務不可用,可以將讀操作和寫操作分開,禁止client寫Nacos,依然允許其進行讀


    map "$remote_addr" $limit_read {
       
       default    0;
    }

    
    map "$remote_addr" $limit_write {
       
       default    0;
    }

    location /some_url_to_write {
      if ($limit_write = 1) {
        return 403;
      }
    }

3、應用黑名單

IP黑名單功能是nginx提供的基礎能力,能夠限制某些IP的訪問,但是一般一個應用會有很多臺機器,當一個應用出問題的時候,會有很多IP訪問都有問題,通過IP的維度來限制訪問達不到預期,需要有應用的維度來限制

namespace(命名空間)是一個可以區分不同應用的維度,不同的應用一般會使用不同的namespace,這樣可以在namespace維度對服務的訪問進行限制

map "$arg_tenant" $limit_namespace {
        af884cf8-1719-4e07-a1e1-3c4c105ab237   1;
        
        default    0;
    }

    location /some_url {
      if ($limit_namespace = 1) {
        return 403;
      }
    }

通過匹配namespace是否在黑名單中來設置limit_namespace變量,然後在訪問的url中判斷limit_namespace的值,如果為1返回403狀態碼

ak維度:使用一個ak代表一個應用,不同的應用在啟動的時候設置不同的ak。client在發起請求的時候會帶上ak參數到server端,在nginx層對請求的參數進行解析,對特定的應用的ak進行訪問限制

map "$http_Spas_AccessKey" $limit_ak {
        6839c164bb344cdc93107f08eda8a136   1;
        default    0;
    }

    location /some_url {
      if ($limit_ak = 1) {
        return 403;
      }
    }

總結

本文簡單介紹了Nacos在實際生產環境中如何通過限流來提高自身服務的穩定性,除了自身設置tomcat參數,還可以通過高性能的nginx作為前端對流量進行過濾提高限流能力。文中難免會有個別錯誤或者遺漏,如果大家有更多的限流或者提高穩定性的辦法可以在Nacos官網提出來。


歡迎加入我的知識星球,一起探討架構,交流源碼。加入方式,長按下方二維碼噢

已在知識星球更新源碼解析如下:


如果你喜歡這篇文章,喜歡,轉發。

生活很美好,明天見(。・ω・。)ノ♡

相關焦點

  • Nacos 集群部署模式最佳實踐
    這中間我們會引入一些其他組件以解決一些問題,本文標題也可以叫做《Nacos 接入點最佳實踐》。我將會介紹以下三種方案:直連模式、 VIP 模式和地址伺服器模式,並對它們進行對比。2 直連模式直連模式是部署上最簡單,也是最容易理解的一種模式
  • 目前最火的服務註冊中心+配置中心,阿里開源,真香!!
    Nacos 服務註冊需要具備的能力:服務提供者把自己的協議地址註冊到Nacos server服務消費者需要從Nacos Server上去查詢服務提供者的地址(根據服務名稱)Nacos Server需要感知到服務提供者的上下線的變化服務消費者需要動態感知到Nacos Server端服務地址的變化作為註冊中心所需要的能力大多如此,我們需要做的是理解各種註冊中心的獨有特性
  • SpringCloud Alibaba-nacos註冊中心
    https://nacos.ioNacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。 Nacos 是構建以「服務」為中心的現代應用架構 (例如微服務範式、雲原生範式) 的服務基礎設施。
  • 服務發現、配置中心,Nacos幫我們都搞定了
    官網如下:https://spring.io/projects/spring-cloud-alibaba/(三)NacosNacos是alibaba開源的一個動態服務發現、配置管理和服務管理平臺,Nacos約等於eureka+springcloudconfig。
  • 微服務註冊中心Nacos入門
    服務治理服務治理的核心由三部分組成:服務提供者、服務消費者、註冊中心。
  • 詳解nacos註冊中心服務註冊流程
    這個最小型的集中式管理的組件就是服務註冊中心。一、nacos 簡介本文的目的在於詳解 nacos 註冊中心的服務註冊流程,所以首先需要對 nacos 有個基本的了解。nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。
  • 最強 Spring Cloud 註冊中心 Nacos,和艿艿來擼一波~
    註冊中心原理在開始搭建 Nacos Discovery 的示例之前,我們先來簡單了解下註冊中心的原理。在使用註冊中心時,一共有三種角色:服務提供者(Service Provider)、服務消費者(Service Consumer)、註冊中心(Registry)。
  • Dubbo-go v3.0 正式發布 ——打造國內一流開源 Go 服務框架
    在服務註冊發現方面,支持 Nacos 、Zookeeper、ETCD、Consul、Polaris-mesh(騰訊開源) 等服務註冊中間件,並擁有可擴展能力。我們也會根據用戶使用情況,進一步擴展出用戶需要的實現。在配置中心方面,開發者可以使用Nacos、Apollo(攜程開源)、Zookeeper 進行框架/用戶的配置的發布和拉取。
  • 今天來學學Nacos
    一、Nacos介紹Nacos是阿里zhuc中間件團隊開源的一款服務發現
  • 微服務架構中配置中心的選擇,Apollo值得擁有
    經過實際使用你會發現Spring Cloud Config這個配置中心並不是非常好用,如果是小規模的項目可以使用問題不大,但它並不適用於中大型的企業級的配置管理。因此,我對業界開源的配置中心做個對比後最終選擇了攜程開源的Apollo配置中心解決了微服務架構配置管理和其他項目中配置管理痛點。
  • Alibaba 之 Nacos
    RocketMQ:Apache RocketMQ™ 基於 Java 的高性能、高吞吐量的分布式消息和流計算平臺。Schedulerx:阿里中間件團隊開發的一款分布式任務調度產品,支持周期性的任務與固定時間點觸發任務。AliCloud SLS:針對日誌類數據的一站式服務,在阿里巴巴集團經歷大量大數據場景錘鍊而成。
  • SpringBoot 2.0 + Nacos + Sentinel 流控規則集中存儲
    不過官方也提供了一種 Push模式,擴展讀數據源 ReadableDataSource,規則中心統一推送,客戶端通過註冊監聽器的方式時刻監聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。這裡我們通過配置 Nacos 來實現流控規則的統一存儲配置。架構
  • 微服務學習之路(1)——配置中心Nacos鏡像製作、集群搭建
    Nacos是阿里巴巴開源的為微服務提供發現、配置和管理的一個軟體平臺,其定位是構建以「服務」為中心的現代應用架構(例如微服務範式、雲原生範式)的服務基礎設施
  • 微服務:註冊中心ZooKeeper、Eureka、Consul 、Nacos對比
    再如果,同事滿足一致性和可用性,那麼分區容錯就很難保證了,也就是單點,也是分布式的基本核心,好了,明白這些理論,就可以在相應的場景選取服務註冊與發現了 服務註冊中心解決方案設計或者選型一個服務註冊中心,首先要考慮的就是服務註冊與發現機制。
  • 微服務架構:註冊中心 ZooKeeper、Eureka、Consul 、Nacos 對比!
    ConsulConsul 是 HashiCorp 公司推出的開源工具,用於實現分布式系統的服務發現與配置。Consul 使用 Go 語言編寫,因此具有天然可移植性(支持Linux、windows和Mac OS X)。
  • 小白也能懂的 Nacos 服務模型介紹
    來源:Kirito的技術分享作者:Kirito的技術分享前言按照目前市場上的主流使用場景,Nacos 被分成了兩塊功能:服務註冊發現(Naming)和配置中心(Config)。今天這篇文章所介紹的內容則是與 Nacos 服務註冊發現功能相關,來聊一聊 Nacos 的服務模型。說到服務模型,其實需要區分視角,一是用戶視角,一個內核視角。即 Nacos 用戶視角看到的服務模型和 Nacos 開發者設計的內核模型可能是完全不一樣的,而今天的文章,是站在用戶視角觀察的,旨在探討 Nacos 服務發現的最佳實踐。
  • 阿里開源的限流神器 Sentinel,輕鬆搞定接口限流!
    Sentinel是阿里巴巴開源的限流器熔斷器,並且帶有可視化操作界面。在日常開發中,限流功能時常被使用,用於對某些接口進行限流熔斷,譬如限制單位時間內接口訪問次數;或者按照某種規則進行限流,如限制ip的單位時間訪問次數等。之前我們已經講過接口限流的工具類ratelimter可以實現令牌桶的限流,很明顯sentinel的功能更為全面和完善。
  • ZooKeeper、Eureka、Consul 、Nacos,微服務註冊中心怎麼選?
    Consul:Consul 是 HashiCorp 公司推出的開源工具,用於實現分布式系統的服務發現與配置。Consul 使用 Go 語言編寫,因此具有天然可移植性(支持Linux、windows和Mac OS X)。
  • Nacos 權限控制介紹及實戰
    最新發布的 Nacos 1.2.0版本已經支持了服務發現和配置管理的權限控制,保障用戶安全上生產。本文主要介紹 Nacos 權限控制的設計方案和使用指南。什麼是權限控制?在分布式服務調用時,需要對未知的或者不受信任的請求來源的請求進行識別和拒絕。權限控制一般分為兩個階段:身份識別(Authentication)和權限識別(Authorization)。
  • 微服務的靈魂擺渡者Nacos究竟有多強?
    Nacos是阿里巴巴開源的服務註冊中心以及配置中心,致力於給開發者提供一款便捷、簡單上手的開源框架。Nacos究竟有什麼驚人的地方呢?看下圖:圖片從上圖不難看出阿里巴巴的野心,一個Nacos幹掉了Spring Cloud的三大組件,分別是註冊中心Eureka、服務配置Config,服務總線Bus。本文目錄結構如下圖: