上一篇文章中已经简单介绍了Sentinel控制台的安装如接入,在Dubbo应用中接入Sentinel非常的简单,几乎是0入侵,只需要添加一个Sentinel的Dubbo适配器即可,在接下来的这篇文章将介绍从0开始搭建Dubbo应用然后接入Sentinel进行流量控制(QPS)的例子


创建Dubbo公共接口模块

  • 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
http://maven.apache.org/xsd/maven-4.0.0.xsd”>

<parent>
<artifactId>sentinel_dubbo</artifactId>
<groupId>com.hzk.demo</groupId>
<version>1.2.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>

<artifactId>dubbo_common_interfaces</artifactId>

</project>

  • 定义公共接口

package com.common.dubbo.service;
public interface Service1 {
            void method1(String requestId);
}


创建Dubbo服务模块

  • pom.xml

<dependencies>

<!– 引入公共接口 –>
<dependency>
<groupId>com.hzk.demo</groupId>
<artifactId>dubbo_common_interfaces</artifactId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!– spring-context –>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring_version}</version>
</dependency>
<!– alibaba dubbo –>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo_version}</version>
</dependency>
<!– curator-recipes –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator_version}</version>
</dependency>
<!– curator-framework –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator_version}</version>
</dependency>
<!– curator-client –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${curator_version}</version>
</dependency>
<!– sentinel-dubbo-adapter –>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-dubbo-adapter</artifactId>
<version>${sentinel_version}</version>
</dependency>
<!– 客户端接入sentinel控制台需要的jar –>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel_version}</version>
</dependency>

</dependencies>

  • 自定义一个ServiceRuleBean

package com.dubbo.bean;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.List;
/**
* 加载service rule的bean
*/
public class ServiceRuleBean {
private ServiceRuleBean(){}
private ServiceRuleBean(List<FlowRule> ruleList){

FlowRuleManager.loadRules(ruleList);

}

}

  • 实现公共接口的ServiceImpl

package com.dubbo.serviceimpl;
import com.common.dubbo.service.Service1;

public class Service1Impl implements Service1{
@Override
public void method1(String requestId) {
System.out.println(“服务端接收的_requestId:”+requestId+”:this is dubbo service1 impl!”);
}
}

  • 创建sentinel-rules.xml【resources下的路径:spring/sentinel-rules.xml】

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd”>

<!– sentinel rules grade参数:1=QPS 0=THREAD–>
<bean id=”service1rule” class=”com.alibaba.csp.sentinel.slots.block.flow.FlowRule”>
<property name=”resource” value=”com.common.dubbo.service.Service1″/>
<property name=”count” value=”10″ />
<property name=”grade” value=”1″/>
</bean>

<!– 加载sentinel rule –>
<bean class=”com.dubbo.bean.ServiceRuleBean”>
<constructor-arg>
        <list>
                <ref bean=”service1rule”/>
        </list>
</constructor-arg>

</bean>
</beans>

  • 创建dubbo-service.xml【resources下的路径:spring/dubbo-service.xml】

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:dubbo=”http://code.alibabatech.com/schema/dubbo”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd”>

<!– dubbo 配置 ,注册中心使用zookeeper,服务自己准备–>
<dubbo:application name=”sentinel_dubbo_service”/>
<dubbo:registry protocol=”zookeeper” address=”***“/>

<!– 服务注册 –>
<bean id=”service1″ class=”com.dubbo.serviceimpl.Service1Impl”/>

<dubbo:service interface=”com.common.dubbo.service.Service1″ ref=”service1″/>

</beans>

  • 创建applicationContext.xml【resources下的路径:spring/applicationContext.xml】

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd”>

<!– dubbo-service –>
<import resource=”classpath:spring/dubbo-service.xml“/>
<!– sentinel-rules –>
<import resource=”classpath:spring/sentinel-rules.xml“/>

</beans>

  • 最后配置web.xml文件加载spring配置

<!DOCTYPE web-app PUBLIC
“-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
“http://java.sun.com/dtd/web-app_2_3.dtd” >

<web-app>
<!–spring–>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

此时的service-provide已经搭建好,该dubbo服务模块提供了一个method1接口,并且接入了Sentinel对该接口(Service1)进行了最大QPS=10的流量限制,当然也可以只对Service1接口的某个方法进行流量控制,可参考官方文档,接下来编写一个dubbo消费者模块对该接口调用进行测试


创建Dubbo消费者模块

  • pom.xml

<!– 引入公共接口 –>
<dependency>
<groupId>com.hzk.demo</groupId>
<artifactId>dubbo_common_interfaces</artifactId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!– spring-context –>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring_version}</version>
</dependency>
<!–spring test–>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring_version}</version>
</dependency>
<!– junit –>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
<!– alibaba dubbo –>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo_version}</version>
</dependency>
<!– curator-recipes –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator_version}</version>
</dependency>
<!– curator-framework –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator_version}</version>
</dependency>
<!– curator-client –>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${curator_version}</version>
</dependency>
<!– sentinel-dubbo-adapter –>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-dubbo-adapter</artifactId>
<version>${sentinel_version}</version>
</dependency>
<!– 客户端接入sentinel控制台需要的jar –>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel_version}</version>
</dependency>

  • 创建dubbo-consumer.xml【resources下的路径:spring/dubbo-consumer.xml】

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:dubbo=”http://code.alibabatech.com/schema/dubbo”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd”>

<!– dubbo 配置 –>
<dubbo:application name=”sentinel_dubbo_consumer”/>
<dubbo:registry protocol=”zookeeper” address=”***”/>

<!– 服务发现 –>
<dubbo:reference interface=”com.common.dubbo.service.Service1″ id=”service1″/>

</beans>

  • 创建applicationContext.xml【resources下的路径:spring/applicationContext.xml】

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd”>

<!– dubbo-consumer –>
<import resource=”classpath:spring/dubbo-consumer.xml“/>

</beans>

  • 创建一个测试spring用例测试service接口

package com.dubbo.consumer;
import com.common.dubbo.service.Service1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:spring/applicationContext.xml”)
public class ConsumerTest {

@Autowired
public Service1 service1;

/**
* 远程服务调用测试
*/
@Test

        public void test1(){

int count = 0;
while (true){
count++;
try {
service1.method1(Integer.toString(count));
}catch (Exception e){//若接口请求QPS超过了服务端sentinel设置的限制则客户端会抛出异常
 System.out.println(“======requestId:”+count+” is block========”);
}
}

}

}


启动测试

  1. 首先启动dubbo-service模块
  2. service模块启动成功之后,运行consumer模块的测试用例即可,随即可以看到结果
  3. 服务端控制台结果如下:
  4. 客户端控制台结果如下:
  5. 通过后台打印的数据可以看到,在客户端反馈被block的request都没有进入到service端,可见Sentinel的QPS限流已经生效

结语

本文只介绍sentinel的最简单的一个基于QPS的限流功能,当然也可以根据线程数进行限制,Sentinel还有其它强大功能,感兴趣的同学可以参考官方文档,有不少的例子,另外需要接入控制台的也可以参考上一篇文章在应用启动的时候设定VM参数即可

发表评论

电子邮件地址不会被公开。