Sentinel分散式限流元件,SpringCloud Alibaba整合

坐看雲起時_雨宣發表於2019-12-24

Sentinel 是什麼?

隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

Sentinel 具有以下特徵:

  • 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、訊息削峰填谷、叢集流量控制、實時熔斷下游不可用應用等。
  • 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制檯中看到接入應用的單臺機器秒級資料,甚至 500 臺以下規模的叢集的彙總執行情況。
  • 廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模組,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
  • 完善的 SPI 擴充套件點:Sentinel 提供簡單易用、完善的 SPI 擴充套件介面。您可以通過實現擴充套件介面來快速地定製邏輯。例如定製規則管理、適配動態資料來源等。

以上是官網對sentinel的一個介紹,本篇文章不講原理,只講搭建和使用。官網:https://github.com/alibaba/Sentinel/

正式開始之前我們先來看一下sentinel提供的dashboard介面:

通過https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard  下載原始碼進行構建,由於是SpringBoot專案,打包後可以使用java -jar xxx.jar來啟動,我這裡已經構建好了,直接來看啟動後的介面:

預設的使用者名稱和密碼都是 sentinel,

可以看到有sentinel-test的,這個是我們剛剛剛定義的。

可以看到,我剛剛對c1和c2的服務進行了訪問,在這裡可以檢視介面的qps等。

由於我使用的叢集總體,閥值為20,所以qps平均在21左右,叢集內有2個機器,分別是c1和c2, Java的測試程式碼如下:

可以看到Blocked By Sentinel (flow limiting) 說明被拒絕了,有一個注意點就是在新增規則的時候要選擇叢集:

 

在新增流控規則的時候如果不勾選預設是單機的,不會走token-server

可以看到我當前的機器節點。 下面來說專案的搭建。

 

專案結構如上,c1和c2模仿了2個應用,token-server為叢集提供token。

下面我們來看c1和c2的工程目錄:

c2和c1的工程目錄一樣,為了方便截圖,只展開C1工程。

c1、c2工程的pom配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sentinel</groupId>
    <artifactId>c1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>c1</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>



        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-extension</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-cluster-client-default</artifactId>
            <version>1.7.0</version>
        </dependency>



    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>0.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties配置如下
 

server.port=8700
spring.application.name=sentinel-test

spring.cloud.sentinel.eager=true
spring.cloud.sentinel.transport.dashboard=http://192.168.0.122:8080

C1Application.java、C2Application.java

package com.sentinel.c1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class C1Application {

    public static void main(String[] args) {
        System.setProperty("csp.sentinel.log.use.pid", "true");
        SpringApplication.run(C1Application.class, args);
    }


    @RequestMapping(value = "hello")
    public String hello(){
        return "c1";
    }

}

以上主要為C1和C2工程目錄的主要配置檔案和程式碼,接下來我們看看token-server的配置。

token-server的pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sentinel</groupId>
    <artifactId>token-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>token-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-cluster-server-default</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.9.1</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

TokenServerApplication.java

package com.sentinel.tokenserver;

import com.alibaba.csp.sentinel.cluster.server.ClusterTokenServer;
import com.alibaba.csp.sentinel.cluster.server.SentinelDefaultTokenServer;
import com.alibaba.csp.sentinel.cluster.server.config.ClusterServerConfigManager;
import com.alibaba.csp.sentinel.cluster.server.config.ServerTransportConfig;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.Collections;

@SpringBootApplication
public class TokenServerApplication {

    public static void main(String[] args) throws Exception {
//        SpringApplication.run(TokenServerApplication.class, args);


        System.setProperty("project.name", "sentinel-test");
        System.setProperty("csp.sentinel.dashboard.server", "http://192.168.0.122:8080");
        System.setProperty("csp.sentinel.log.use.pid", "true");

        ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton("default"));
        ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig().setPort(11111).setIdleSeconds(600));

        // Not embedded mode by default (alone mode).
        ClusterTokenServer tokenServer = new SentinelDefaultTokenServer();

        // A sample for manually load config for cluster server.
        // It's recommended to use dynamic data source to cluster manage config and rules.
        // See the sample in DemoClusterServerInitFunc for detail.
        ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig()
                .setIdleSeconds(600)
                .setPort(11111));
        ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton("study-process-server-dev"));

        // Start the server.
        tokenServer.start();


    }
}

tokenServer是在main方法中啟動的,並不是通過SpringBoot啟動的。為了方便測試,建立了三個SpringBoot專案。

先啟動token-server,在啟動c1 和 c2,然後在dashboard裡邊就可以看到了。

有問題可以在評論區評論,技術問題可以私聊我。

 

 

 

相關文章