Sentinel integration Dubbo limiting combat (Distributed limiting)

  Before we understand the Sentinel integrated SpringBoot for current limiting, also discussed the basic principles of limiting Sentinel, then it follows that we learn about Sentinel integration Dubbo and Nacos for current limiting dynamic data sources and distributed limiting.

  First look at my project directory:


Single limiting services:

  Provider :

  First, from the api module begins:

  Which only defines an interface:

public interface SentinelService {
    String sayHello(String txt);
}

  He goes on to write server-side code.

1. First, we need to need to add a dependency:

<dependency>
    <groupId>com.wuzz.demo</groupId>
    <artifactId>sentinel-dubbo-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.2</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-dubbo-adapter</artifactId>
    <version>1.6.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.6.3</version>
</dependency>

2. We need to write and publish the interface implementation class service to Dubbo:

@Service // the current service release to service dubbo 
public  class SentinelServiceImpl the implements SentinelService { 

    @Override 
    public String sayHello (String TXT) {
         return  " the Hello world: " + LocalDateTime.now (); 
    } 
}

3. Add Dubbo configuration, this uses annotations ways:

@Configuration
@DubboComponentScan("com.wuzz.demo")
public class DubboConfig {

    @Bean
    public ApplicationConfig applicationConfig(){
        ApplicationConfig applicationConfig=new ApplicationConfig();
        applicationConfig.setName("sentinel-dubbo");
        applicationConfig.setOwner("wuzz");
        return applicationConfig;
    }
    @Bean
    public RegistryConfig registryConfig(){
        RegistryConfig registryConfig=new RegistryConfig();
        registryConfig.setAddress("zookeeper://192.168.1.101:2181");
        return registryConfig;
    }
    @Bean
    public ProtocolConfig protocolConfig(){
        ProtocolConfig protocolConfig=new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }
}

4. Profile application.properties:

server.port = 8881

The preparation of the master boot categories:

@SpringBootApplication
public class SentinelProviderApplication {
    public static void main(String[] args) throws IOException {
        initFlowRules();
        SpringApplication.run(SentinelProviderApplication.class, args);
        System.in.read();
    }

    //初始化规则
    private static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>(); //限流规则的集合
        FlowRule flowRule = new FlowRule();
        flowRule.setResource(" Com.wuzz.demo.SentinelService: the sayHello (java.lang.String) " ); // resources (method name, an interface) 
        flowRule.setCount ( 10 ); // limit threshold = 10 QPS 
        flowRule.setGrade (RuleConstant. FLOW_GRADE_QPS); // limit threshold type (or the number of concurrent threads QPS)
         // flow control means (directly rejected, Warm Up, uniform line) 
        flowRule.setControlBehavior (RuleConstant.CONTROL_BEHAVIOR_DEFAULT); 
        flowRule.setLimitApp ( " Sentinel-Web " ) ; // flow control for the call source, call the default source if it is not case 
        rules.add (flowRule); 
        FlowRuleManager.loadRules (the rules); 
    } 
}

Set the reference current limit:

  Service Provider for providing services to the outside world, call processing requests from the consumers. In order to protect the flow surges Provider being the amount of collapse affect the stability, can be configured to limit the flow pattern QPS Provider, the threshold will be such that when requests per second exceeds the set to automatically reject many requests. Limiting the particle size can be a service interface and service two methods of particle size. If you want QPS entire service interface does not exceed over a certain value, the corresponding service that can interface resources (resourceName fully qualified name of the interface) to configure QPS threshold; If you want QPS a method of service does not exceed a certain value, that can correspond service method resources (resourceName the interface fully qualified name: the method signature) configured QPS threshold.

Laimitapp :

  In many scenes, according to the caller to limit the flow is very important. For example, there are two services A and B are initiating call to the Service Provider, we hope only to requests from the service B are limiting, you can set limitApp limiting rules for the service name B's. Sentinel Dubbo Adapter will automatically parse Dubbo consumer (the caller) the application name as the caller's name (origin), in resource protection is going to be put on the caller's name. If the rule limiting the caller is not configured (default), the current-limiting rules are in effect for all callers. If the configuration rules limiting the caller is limiting rules will take effect only designated caller.

  NOTE: Dubbo default application name does not carry communication information terminal, thus requiring the developer to manually applicationname calling terminal into the attachment, the corresponding end Provider analysis. Sentinel Dubbo Adapter implements a pass Filter for automatic application name to the end consumer from the provider end through. If the call is not introduced into the end of the Sentinel DubboAdapter, but also according to desired end call flow restrictor may be placed in the application name in the calling terminal manual attachment, key as dubboApplication.

ControlBehavior:

  When QPS exceeds a certain threshold, then take measures for traffic control. Means for flow control include the following: directly rejected, Warm Up, uniform line. FlowRule the corresponding fields in controlBehavior

  1. Direct rejection (RuleConstant.CONTROL_BEHAVIOR_DEFAULT) flow control mode is the default mode, when any regular QPS exceeds a threshold value, the new request is immediately rejected, reject mode is thrown FlowException. This method is applicable to a case where the processing capacity of the system known exactly, such as determining the exact level of the system pressure measured by the time
  2. Warm Up (RuleConstant.CONTROL_BEHAVIOR_WARM_UP) mode, the preheating / cold start mode, when the system is in low long-term concurrent flow suddenly increased to the highest peak of qps may cause instantaneous flow system is too large to overwhelm the system. Warmup Therefore, the number corresponding to the processing request is to increase slowly, after a period of time, it reaches a maximum number of request processing system
  3. Uniform queuing (RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER) strictly controlled manner through the request interval, that is, make a request at a uniform speed through, corresponding to the leaky bucket principle it is, at fixed intervals the request through. When the request came, if the distance by the time of the request by the current request at intervals of not less than the predetermined value, so that the current request by; otherwise, the current request by calculating the expected time, if the request is expected to rule by less than preset timeout period, the request will wait until the time comes by default; on the contrary, it is immediately blocked an exception is thrown. You can set a maximum waiting time: flowRule.setMaxQueueingTimeMs (5 * 1000); // maximum waiting time: 5s This approach is mainly used to treat intermittent bursts of traffic, such as a message queue. Imagine such a scene, a large number of seconds in a request comes in, and the next few seconds is idle, we want the system to be able to process these requests gradually during the next idle, rather than simply reject the first seconds extra request.

  Consumer :

1. Add dependence:

<dependency>
  <groupId>com.wuzz.demo</groupId>
  <artifactId>sentinel-dubbo-api</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.7.2</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-recipes</artifactId>
  <version>4.0.1</version>
</dependency>
<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId>
  <version>2.7.1</version>
</dependency>

2.consumer mainly provide services, we need a controller:

@RestController
public class SentinelController {

    @Reference(timeout = 3000,check = false)
    SentinelService sentinelService;//proxy$0

    @GetMapping("/say")
    public String sayHello(){
        RpcContext.getContext().setAttachment("dubboApplication","sentinel-web");
        return sentinelService.sayHello("test");
    }

    @GetMapping("/say2")
    public String sayHello2(){
        return sentinelService.sayHello("test2");
    }
}

3. Start the main categories:

@SpringBootApplication
public class SentinelConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SentinelConsumerApplication.class, args);
    }

}

4. Profile application.properties:

server.port = 8882
dubbo.registry.address=zookeeper://192.168.1.101:2181
dubbo.scan.base-packages=com.wuzz.demo
dubbo.application.name=sentinel-web

  Write complete server and client code, this time we need to start the Sentinel-Dashboard so intuitive to see the effect of limiting. Then start the server, and the parameter is added JVM startup -Dcsp.sentinel.dashboard.server = localhost: 8080 console specified address and port. Other specific parameters are as follows:

-server
-XX:MaxHeapSize=128m
-Xms256m
-Xmx256m
-XX:PermSize=128M
-XX:MaxPermSize=256m
-Dproject.name=app-demo
-Dcsp.sentinel.dashboard.server=localhost:8080
-Dcsp.sentinel.log.use.pid=true

  Then start the client, through the JMeter pressure-measurement, the following results:

  On the other hand we launched the Sentinel-Dashboard so we can see through the console:

Distributed limiting how:

  Why use a cluster traffic control it? Suppose we want to restrict a user to call a total QPS API is 50, but the number of machines may be many (such as 100 units). This time we naturally think of to find a server to call the total amount dedicated to statistics, other examples of this are communicating with the server to determine whether you can call. This is the most basic way flow control cluster.

In addition cluster flow control can also address the uneven flow resulting in poor overall effect of limiting the problem. Suppose there are 10 clusters machines, each machine is provided to our single flow restrictor 10 QPS threshold, the current limit threshold of the entire cluster as would ideally 100 QPS. But the actual circumstances traffic to each machine may not be uniform, can cause some machines began limiting the case to the total no. Therefore, relying on stand-alone dimension to limit the words will not accurately limit the overall flow. The cluster flow control can precisely control the amount of calls the entire cluster, combined with the single limiting reveal all the details, you can better play the effect of flow control.

  Clusters Flow Control There are two identities:

  • Token Client: Cluster flow control client for requesting the relevant token Token Server communication. Cluster limiting the server returns the results to the client to decide whether limiting.
  • Token Server: i.e., flow control cluster server handles requests from the Token Client determines rule is set according to the cluster should grant token (whether to allow).

  To use the cluster flow control function, we need to configure a dynamic source rule in the application side, and push through real-time Sentinel console. As shown below:


Build Token-Server:

1. Add pom-dependent:

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-cluster-server-default</artifactId>
  <version>1.6.3</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
  <version>1.6.3</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-transport-simple-http</artifactId>
  <version>1.6.3</version>
</dependency>

2.dubbo Nacos utilizing dynamic data sources required to achieve  InitFunc Interface:

public  class NacosDataSourceInitFunc the implements InitFunc { 

    Private Final of the remoteAddress String = " localhost " ; // service center host nacos arranged 
    Private Final the groupId String = " SENTINEL_GROUP " ;
     Private Final FLOW_POSTFIX String = " -flow-the rules " ; // DataID (names + postfix) 

    // means that the current token-server will be available on the nacos rules limiting the 
    @Override
     public  void the init () throws Exception { 
        ClusterFlowRuleManager.setPropertySupplier ( namespace -> {
            ReadableDataSource<String, List<FlowRule>> rds=
                    new NacosDataSource<List<FlowRule>>(remoteAddress,groupId,namespace+FLOW_POSTFIX,
                            source -> JSON.parseObject(source,new TypeReference<List<FlowRule>>(){}));
            return rds.getProperty();
        });
    }
}

  Then you need to add expansion files com.alibaba.csp.sentinel.init.InitFunc point in the META-INF / services. Its content is our implementation:

com.wuzz.demo.NacosDataSourceInitFunc

3. Start the main categories:

public class ClusterServer {

    public static void main(String[] args) throws Exception {
        ClusterTokenServer tokenServer=new SentinelDefaultTokenServer();
        ClusterServerConfigManager.loadGlobalTransportConfig(
                new ServerTransportConfig().setIdleSeconds(600).setPort(9999));
        ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton("app-wuzz")); //设置成动态
        tokenServer.start();
    }
}

  Start Sentinel-dashboard:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -XX:MaxHeapSize=128m -Xms256m -Xmx256m -XX:PermSize=128M -XX:MaxPermSize=256m  -jar sentinel-dashboard-1.6.3.jar

  Start and increasing nacos configuration: Data Id = app-wuzz-flow-rules, Group = SENTINEL_GROUP

[ 
    { 
        " Resource " : " com.wuzz.demo.SentinelService: the sayHello (java.lang.String) " ,
         " Grade " : . 1 , // limiting mode QPS 
        " COUNT " : 10 , // current limit threshold of the total 
        " clusterMode " : to true , // cluster mode to true 
        " ClusterConfig " : {
             " FlowID " : 100001 , // globally unique ID 
            "thresholdType" : 1 , // threshold value model, global threshold 
            " fallbackToLocalWhenFail " : to true  // Client connection failure mode using the local flow restrictor 
        } 
    } 
]

  Start Token-Server and add the following JVM arguments, add it to the Sentinel-Dashboard for management:

-server -Dproject.name=app-wuzz -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.log.use.pid=true

  Computer memory is insufficient to join -XX: MaxHeapSize = 128m -Xms256m -Xmx256m -XX: PermSize = 128M -XX: MaxPermSize = 256m. After the service starts at $ user.home $ / logs / csp / sentinel-record.log.pid * .date file can be found, if you see the log file to get information about remote services, indicating token-server startup success, you can also see the list of registered by the Sentinel-Dashboard:

Provider :

1. Add pom-dependent:

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

  2. Add the expansion point file com.alibaba.csp.sentinel.init.InitFunc in META-INF / services. Its content is our implementation, just hey token-server configuration is available directly from Nacos in. The server is configured as follows:

public class NacosDataSourceInitFunc implements InitFunc {


    private final String CLUSTER_SERVER_HOST="localhost"; //token-server的地址
    private final int CLUSTER_SERVER_PORT=9999;
    private final int REQUEST_TIME_OUT=200000; //请求超时时间

    private final String APP_NAME="app-wuzz"; //namespace

    //nacos的配置()
    private final String remoteAddress="localhost"; // service host nacos distribution center of 
    Private Final groupId String = " SENTINEL_GROUP " ;
     Private Final FLOW_POSTFIX String = " -flow-rules " ; // DataID (names + postfix) 

    // means that the current token-server will be from nacos obtained on rules limiting 
    @Override
     public  void the init () throws Exception {
         // load the cluster - information 
        loadClusterClientConfig (); 

        registryClusterFlowRuleProperty (); 
    } 

    Private  void loadClusterClientConfig () { 
        ClusterClientAssignConfig assignConfig =new ClusterClientAssignConfig();
        assignConfig.setServerHost(CLUSTER_SERVER_HOST);
        assignConfig.setServerPort(CLUSTER_SERVER_PORT);
        ClusterClientConfigManager.applyNewAssignConfig(assignConfig);

        ClusterClientConfig clientConfig=new ClusterClientConfig();
        clientConfig.setRequestTimeout(REQUEST_TIME_OUT);
        ClusterClientConfigManager.applyNewConfig(clientConfig);
    }

    //注册动态数据源
    private void registryClusterFlowRuleProperty(){
        ReadableDataSource<String, List<FlowRule>> rds=
                new NacosDataSource<List<FlowRule>>(remoteAddress,groupId,APP_NAME+FLOW_POSTFIX,
                        source -> JSON.parseObject(source,new TypeReference<List<FlowRule>>(){}));
        FlowRuleManager.register2Property(rds.getProperty());
    }

}

3. Modify the master boot categories:

@SpringBootApplication
 public  class SentinelProviderApplication {
     public  static  void main (String [] args) throws IOException { // indicates that the current node is a cluster client 
        ClusterStateManager.applyState (ClusterStateManager.CLUSTER_CLIENT); 
        SpringApplication.run (. SentinelProviderApplication class , args); 
        the System . in .read (); 
    } 
}

  Start the server and added to the Sentinel-Dashboard, the additional add JVM parameters here need to pay attention, where project-name to include namespace arranged in the token-server in the, token server will correspond to the client according namespace connections (project.name default application name defined above) to calculate the total of the threshold, here is my to app-wuzz .:

-server
-XX:MaxHeapSize=128m
-Xms256m
-Xmx256m
-XX:PermSize=128M
-XX:MaxPermSize=256m
-Dproject.name=app-wuzz
-Dcsp.sentinel.dashboard.server=localhost:8080
-Dcsp.sentinel.log.use.pid=true

  After the service starts at $ user.home $ / logs / csp / sentinel-record.log.pid * .date file can be found, if you see the log file to get the information token-server, indicating that the connection is successful.

  Since we want to achieve distributed current limit, which is the need to deploy our service bureau group, we can use to implement IDEA: Add a SentinelProviderApplication . Run two programs:

  Here JVM parameters need to increase more than a -Ddubbo.protocol.port = 20881 can. Then we start the two services and clients. JMeter pressure measured by the results, you can see (multiple times request), we can see directly Sentinel-Dashboard:

  In this way a distributed limiting.

 

Guess you like

Origin www.cnblogs.com/wuzhenzhao/p/11493183.html