refactor dubbo examples & add datasource feature in example & update docs

pull/30/head
fangjian0423 7 years ago
parent d1fd1f0e2f
commit 6598768195

@ -16,6 +16,9 @@
<modules>
<module>sentinel-example</module>
<module>sentinel-dubbo-provider-example</module>
<module>sentinel-dubbo-consumer-example</module>
<module>sentinel-dubbo-api</module>
</modules>
<build>

@ -0,0 +1,30 @@
<?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>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-examples</artifactId>
<version>0.2.0.BUILD-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-dubbo-api</artifactId>
<packaging>jar</packaging>
<description>api for sentinel dubbo example</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,10 @@
package org.springframework.cloud.alibaba.cloud.examples;
/**
* @author fangjian
*/
public interface FooService {
String hello(String name);
}

@ -0,0 +1,54 @@
<?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>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-examples</artifactId>
<version>0.2.0.BUILD-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-dubbo-consumer-example</artifactId>
<packaging>jar</packaging>
<description>Example demonstrating how to use sentinel with dubbo</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>sentinel-dubbo-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,99 @@
# Sentinel Dubbo Consumer Example
## 项目说明
本项目演示如何使用 Sentinel starter 完成 Dubbo 应用的限流管理。
[Sentinel](https://github.com/alibaba/Sentinel) 是阿里巴巴开源的分布式系统的流量防卫组件Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
[Dubbo](http://dubbo.apache.org/)是一款高性能Java RPC框架有对应的[SpringBoot工程](https://github.com/apache/incubator-dubbo-spring-boot-project)。
本项目需要配合`sentinel-dubbo-provider-example`模块一起完成演示并且需要先启动sentinel-dubbo-provider-example。
本项目专注于Sentinel与Dubbo的整合关于Sentinel的更多特性可以查看[sentinel-example](https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example)。
## 示例
### 如何接入
在启动示例进行演示之前,我们先了解一下 Dubbo 如何接入 Sentinel。
**注意 本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
1. 首先,修改 pom.xml 文件,引入 Sentinel starter 和 Dubbo starter。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
2. 配置限流规则
Sentinel提供了[sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter)模块用来支持Dubbo服务调用的限流降级。sentinel-starter默认也集成了该功能。
sentinel-dubbo-adapter内部的Dubbo Filter会根据资源名进行限流降级处理。只需要配置规则即可
FlowRule flowRule = new FlowRule();
flowRule.setResource(
"org.springframework.cloud.alibaba.cloud.examples.FooService:hello(java.lang.String)");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### 规则定义
`sentinel-dubbo-api`模块中定义了FooService服务内容如下
package org.springframework.cloud.alibaba.cloud.examples.FooService;
public interface FooService {
String hello(String name);
}
该服务在Sentinel下对应的资源名是 `org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService:hello(java.lang.String)`
定义该资源名对应的限流规则:
FlowRule flowRule = new FlowRule();
flowRule.setResource("dubboResource");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### 服务调用
根据`sentinel-dubbo-provider-example`中发布的定义使用Dubbo的@Reference注解注入服务对应的Bean。
@Reference(version = "${foo.service.version}", application = "${dubbo.application.id}",
url = "dubbo://localhost:12345", timeout = 30000)
private FooService fooService;
由于设置的qps是10。调用15次查看是否被限流
FooServiceConsumer service = applicationContext.getBean(FooServiceConsumer.class);
for (int i = 0; i < 15; i++) {
try {
String message = service.hello("Jim");
System.out.println((i + 1) + " -> Success: " + message);
}
catch (SentinelRpcException ex) {
System.out.println("Blocked");
}
catch (Exception ex) {
ex.printStackTrace();
}
}
### 应用启动
支持 IDE 直接启动和编译打包后启动。
1. IDE直接启动找到主类 `SentinelDubboConsumerApp`,执行 main 方法启动应用。
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar sentinel-dubbo-consumer-example.jar`启动应用。

@ -0,0 +1,97 @@
# Sentinel Dubbo Consumer Example
## Project Instruction
This example illustrates how to use Sentinel starter to implement flow control for Spring Cloud applications.
[Sentinel](https://github.com/alibaba/Sentinel) is an open-source project of Alibaba. Sentinel takes "traffic flow" as the breakthrough point, and provides solutions in areas such as flow control, concurrency, circuit breaking, and load protection to protect service stability.
[Dubbo](http://dubbo.apache.org/) is a high-performance, java based open source RPC framework.
This example work with 'sentinel-dubbo-provider-example' module and `sentinel-dubbo-provider-example` module should startup firstly.
This example focus on the integration of Sentinel and Dubbo. You can see more features on [sentinel-example](https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example).
## Demo
### Connect to Sentinel
Before we start the demo, let's learn how to connect Sentinel with Dubbo to a Spring Cloud application.
**Note: This section is to show you how to connect to Sentinel. The configurations have been completed in the following example, so you don't need modify the code any more.**
1. Add dependency spring-cloud-starter-sentinel and dubbo-spring-boot-starter in the pom.xml file in your Spring Cloud project.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
2. Configure flow control rules
Sentinel provide [sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter) module to support dubbo. to support dubbo. sentinel-starter integrates this feature by default.
sentinel-dubbo-adapter will using Sentinel to handle resource by Dubbo Filter. You just need to define rules.
FlowRule flowRule = new FlowRule();
flowRule.setResource("dubboResource");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### Configure Rules
`sentinel-dubbo-api` define a service named FooService:
package org.springframework.cloud.alibaba.cloud.examples.FooService;
public interface FooService {
String hello(String name);
}
The resource name of this service's `hello` method is `org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService:hello(java.lang.String)` .
Configure rules
FlowRule flowRule = new FlowRule();
flowRule.setResource("dubboResource");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### Service Invocation
Using the `@Reference` annotation to inject service:
@Reference(version = "${foo.service.version}", application = "${dubbo.application.id}",
url = "dubbo://localhost:12345", timeout = 30000)
private FooService fooService;
Because QPS is 10, we can see that flow control takes effect in this invocation:
FooServiceConsumer service = applicationContext.getBean(FooServiceConsumer.class);
for (int i = 0; i < 15; i++) {
try {
String message = service.hello("Jim");
System.out.println((i + 1) + " -> Success: " + message);
}
catch (SentinelRpcException ex) {
System.out.println("Blocked");
}
catch (Exception ex) {
ex.printStackTrace();
}
}
### Start Application
Start the application in IDE or by building a fatjar.
1. Start in IDE: Find main class `SentinelDubboConsumerApp`, and execute the main method.
2. Build a fatjarExecute command `mvn clean package` to build a fatjarand run command `java -jar sentinel-dubbo-consumer-example.jar` to start the application.

@ -1,6 +1,4 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo.consumer;
import org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService;
package org.springframework.cloud.alibaba.cloud.examples;
import com.alibaba.dubbo.config.annotation.Reference;
@ -9,7 +7,8 @@ import com.alibaba.dubbo.config.annotation.Reference;
*/
public class FooServiceConsumer {
@Reference(url = "dubbo://127.0.0.1:25758", timeout = 3000)
@Reference(version = "${foo.service.version}", application = "${dubbo.application.id}",
url = "dubbo://localhost:12345", timeout = 30000)
private FooService fooService;
public String hello(String name) {

@ -1,9 +1,9 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo.consumer;
package org.springframework.cloud.alibaba.cloud.examples;
import java.util.Collections;
import org.springframework.boot.Banner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@ -12,36 +12,12 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
/**
* @author fangjian
*/
@DubboComponentScan("org.springframework.cloud.alibaba.cloud.examples.dubbo.provider")
public class ConsumerApplication {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("demo-consumer");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("multicast://224.5.6.7:1234");
return registryConfig;
}
@Bean
public ConsumerConfig consumerConfig() {
ConsumerConfig consumerConfig = new ConsumerConfig();
return consumerConfig;
}
@SpringBootApplication(scanBasePackages = "org.springframework.cloud.alibaba.cloud.examples")
public class SentinelDubboConsumerApp {
@Bean
public FooServiceConsumer annotationDemoServiceConsumer() {
@ -50,20 +26,19 @@ public class ConsumerApplication {
public static void main(String[] args) {
SpringApplicationBuilder consumerBuilder = new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF).registerShutdownHook(false)
.logStartupInfo(false).web(WebApplicationType.NONE);
ApplicationContext applicationContext = consumerBuilder
.sources(ConsumerApplication.class).run(args);
FlowRule flowRule = new FlowRule();
flowRule.setResource(
"org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService:hello(java.lang.String)");
"org.springframework.cloud.alibaba.cloud.examples.FooService:hello(java.lang.String)");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
SpringApplicationBuilder consumerBuilder = new SpringApplicationBuilder();
ApplicationContext applicationContext = consumerBuilder
.web(WebApplicationType.NONE).sources(SentinelDubboConsumerApp.class)
.run(args);
FooServiceConsumer service = applicationContext.getBean(FooServiceConsumer.class);
for (int i = 0; i < 15; i++) {

@ -0,0 +1,11 @@
spring.application.name = dubbo-consumer-demo
foo.service.version = 1.0.0
dubbo.application.id = dubbo-consumer-demo
dubbo.application.name = dubbo-consumer-demo
dubbo.protocol.id = dubbo
dubbo.protocol.name = dubbo
dubbo.protocol.port = 12345

@ -0,0 +1,54 @@
<?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>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-examples</artifactId>
<version>0.2.0.BUILD-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-dubbo-provider-example</artifactId>
<packaging>jar</packaging>
<description>Example demonstrating how to use sentinel with dubbo</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>sentinel-dubbo-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,101 @@
# Sentinel Dubbo Provider Example
## 项目说明
本项目演示如何使用 Sentinel starter 完成 Dubbo 应用的限流管理。
[Sentinel](https://github.com/alibaba/Sentinel) 是阿里巴巴开源的分布式系统的流量防卫组件Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
[Dubbo](http://dubbo.apache.org/)是一款高性能Java RPC框架有对应的[SpringBoot工程](https://github.com/apache/incubator-dubbo-spring-boot-project)。
本项目需要配合`sentinel-dubbo-consumer-example`模块一起完成演示。
本项目专注于Sentinel与Dubbo的整合关于Sentinel的更多特性可以查看[sentinel-example](https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example)。
## 示例
### 如何接入
在启动示例进行演示之前,我们先了解一下 Dubbo 如何接入 Sentinel。
**注意 本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
1. 首先,修改 pom.xml 文件,引入 Sentinel starter 和 Dubbo starter。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
2. 配置限流规则
Sentinel提供了[sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter)模块用来支持Dubbo服务调用的限流降级。sentinel-starter默认也集成了该功能。
sentinel-dubbo-adapter内部的Dubbo Filter会根据资源名进行限流降级处理。只需要配置规则即可
FlowRule flowRule = new FlowRule();
flowRule.setResource("dubboResource");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### 服务定义及发布
在application.properties文件中定义dubbo相关的配置比如协议注册中心
spring.application.name = dubbo-provider-demo
foo.service.version = 1.0.0
dubbo.scan.basePackages = org.springframework.cloud.alibaba.cloud.examples
dubbo.application.id = dubbo-provider-demo
dubbo.application.name = dubbo-provider-demo
dubbo.protocol.id = dubbo
dubbo.protocol.name = dubbo
dubbo.protocol.port = 12345
dubbo.protocol.status = server
dubbo.registry.id = my-registry
dubbo.registry.address = N/A
`sentinel-dubbo-api`模块中定义了FooService服务内容如下
package org.springframework.cloud.alibaba.cloud.examples.FooService;
public interface FooService {
String hello(String name);
}
定义具体的服务:
@Service(
version = "${foo.service.version}",
application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}",
registry = "${dubbo.registry.id}"
)
public class FooServiceImpl implements FooService {
@Override
public String hello(String name) {
return "hello, " + name;
}
}
### 应用启动
支持 IDE 直接启动和编译打包后启动。
1. IDE直接启动找到主类 `SentinelDubboProviderApp`,执行 main 方法启动应用。
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar sentinel-dubbo-provider-example.jar`启动应用。

@ -0,0 +1,97 @@
# Sentinel Dubbo Provider Example
## Project Instruction
This example illustrates how to use Sentinel starter to implement flow control for Spring Cloud applications.
[Sentinel](https://github.com/alibaba/Sentinel) is an open-source project of Alibaba. Sentinel takes "traffic flow" as the breakthrough point, and provides solutions in areas such as flow control, concurrency, circuit breaking, and load protection to protect service stability.
[Dubbo](http://dubbo.apache.org/) is a high-performance, java based open source RPC framework.
This example work with 'sentinel-dubbo-consumer-example' module and `sentinel-dubbo-provider-example` module should startup firstly.
This example focus on the integration of Sentinel and Dubbo. You can see more features on [sentinel-example](https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example).
## Demo
### Connect to Sentinel
Before we start the demo, let's learn how to connect Sentinel with Dubbo to a Spring Cloud application.
**Note: This section is to show you how to connect to Sentinel. The configurations have been completed in the following example, so you don't need modify the code any more.**
1. Add dependency spring-cloud-starter-sentinel and dubbo-spring-boot-starter in the pom.xml file in your Spring Cloud project.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
2. Configure flow control rules
Sentinel provide [sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter) module to support dubbo. to support dubbo. sentinel-starter integrates this feature by default.
sentinel-dubbo-adapter will using Sentinel to handle resource by Dubbo Filter. You just need to define rules.
FlowRule flowRule = new FlowRule();
flowRule.setResource("dubboResource");
flowRule.setCount(10);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
### Configure and Publish Service
Define some configs of dubbo in `application.properties`, like protocol, config registry
spring.application.name = dubbo-provider-demo
foo.service.version = 1.0.0
dubbo.scan.basePackages = org.springframework.cloud.alibaba.cloud.examples
dubbo.application.id = dubbo-provider-demo
dubbo.application.name = dubbo-provider-demo
dubbo.protocol.id = dubbo
dubbo.protocol.name = dubbo
dubbo.protocol.port = 12345
dubbo.protocol.status = server
dubbo.registry.id = my-registry
dubbo.registry.address = N/A
`sentinel-dubbo-api` define a service named FooService:
package org.springframework.cloud.alibaba.cloud.examples.FooService;
public interface FooService {
String hello(String name);
}
Define the implement Service annotated by `@Service`:
@Service(
version = "${foo.service.version}",
application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}",
registry = "${dubbo.registry.id}"
)
public class FooServiceImpl implements FooService {
@Override
public String hello(String name) {
return "hello, " + name;
}
}
### Start Application
Start the application in IDE or by building a fatjar.
1. Start in IDE: Find main class `SentinelDubboProviderApp`, and execute the main method.
2. Build a fatjarExecute command `mvn clean package` to build a fatjarand run command `java -jar sentinel-dubbo-provider-example.jar` to start the application.

@ -0,0 +1,20 @@
package org.springframework.cloud.alibaba.cloud.examples;
import com.alibaba.dubbo.config.annotation.Service;
/**
* @author fangjian
*/
@Service(
version = "${foo.service.version}",
application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}",
registry = "${dubbo.registry.id}"
)
public class FooServiceImpl implements FooService {
@Override
public String hello(String name) {
return "hello, " + name;
}
}

@ -0,0 +1,19 @@
package org.springframework.cloud.alibaba.cloud.examples;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
/**
* @author fangjian
*/
@SpringBootApplication
public class SentinelDubboProviderApp {
public static void main(String[] args) {
SpringApplicationBuilder providerBuilder = new SpringApplicationBuilder();
providerBuilder.web(WebApplicationType.NONE)
.sources(SentinelDubboProviderApp.class).run(args);
}
}

@ -0,0 +1,16 @@
spring.application.name = dubbo-provider-demo
foo.service.version = 1.0.0
dubbo.scan.basePackages = org.springframework.cloud.alibaba.cloud.examples
dubbo.application.id = dubbo-provider-demo
dubbo.application.name = dubbo-provider-demo
dubbo.protocol.id = dubbo
dubbo.protocol.name = dubbo
dubbo.protocol.port = 12345
dubbo.protocol.status = server
dubbo.registry.id = my-registry
dubbo.registry.address = N/A

@ -30,12 +30,6 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
<build>

@ -158,42 +158,81 @@ Sentinel 控制台支持实时监控查看,您可以通过 Sentinel 控制台
<p align="center"><img src="https://cdn.nlark.com/lark/0/2018/png/54319/1532313595369-8428cd7d-9eb7-4786-a149-acf0da4a2daf.png" width="480" heigh='180' ></p>
## Dubbo支持
## DataSource支持
[Dubbo](http://dubbo.apache.org/)是一款高性能Java RPC框架
Sentinel内部提供了[动态规则的扩展实现DataSource](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95#datasource-%E6%89%A9%E5%B1%95)
Sentinel提供了[sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter)模块用来支持Dubbo服务调用的限流降级。sentinel-starter默认也集成了该功能
Sentinel starter整合了目前存在的4类DataSource。只需要在配置文件中进行相关配置即可在Spring容器中自动注册DataSource
比如有个FooService服务定义如下:
比如要定义一个FileRefreshableDataSource配置如下:
package org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService;
public interface FooService {
String hello(String name);
}
spring.cloud.sentinel.datasource.type=file
spring.cloud.sentinel.datasource.recommendRefreshMs=2000
spring.cloud.sentinel.datasource.bufSize=2048
spring.cloud.sentinel.datasource.charset=utf-8
spring.cloud.sentinel.datasource.configParser=myParser
spring.cloud.sentinel.datasource.file=/Users/you/rule.json
该服务在Sentinel下对应的资源名是 `org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService:hello(java.lang.String)`
然后使用`@SentinelDataSource`注解修饰DataSource即可注入
在Consumer端进行限流的话需要处理SentinelRpcException。
@SentinelDataSource("spring.cloud.sentinel.datasource")
private DataSource dataSource;
FooService service = applicationContext.getBean(FooService.class);
`@SentinelDataSource`注解的value属性可以不填。默认值就是spring.cloud.sentinel.datasource。
for (int i = 0; i < 15; i++) {
try {
String message = service.hello("Jim");
} catch (SentinelRpcException ex) {
System.out.println("Blocked");
} catch (Exception ex) {
ex.printStackTrace();
value属性代表配置前缀。示例中会去找spring.cloud.sentinel.datasource.xxx相关的配置。
spring.cloud.sentinel.datasource.type就是对应的DataSource类型。
spring.cloud.sentinel.datasource.recommendRefreshMs里的recommendRefreshMs对应相关DataSource的属性。
spring.cloud.sentinel.datasource.configParser代表ConfigParser在Spring容器里的name。如果没找到会抛出异常。
type目前支持file, nacos, zk, apollo。
### 自定义DataSource
自定义DataSource只需要两部。
1. 定义DataSource
public class CustomDataSource implements DataSource {
private String fieldA;
private String fieldB;
...
}
}
在Provider端进行限流的话Consumer端调用的话会抛出RpcException。因为Provider端被限流抛出了SentinelRpcException。
2. 装配DataSource。有两种方式处理
### 应用启动
* 直接构造DataSource
@Bean
public CustomDataSource customDataSource() {
CustomDataSource customDataSource =
new CustomDataSource();
customDataSource.setFieldA("valueA");
customDataSource.setFieldB("valueB");
...
return customDataSource;
}
* 在classpath:/META-INF/sentinel-datasource.properties中管理DataSource信息
custom = yourpackage.CustomDataSource
在application.properties中定义DataSource
spring.cloud.sentinel.datasource.type = custom
spring.cloud.sentinel.datasource.fieldA = valueA
spring.cloud.sentinel.datasource.fieldB = valueB
注意由于目前Sentinel的AbstractDataSource需要有个ConfigParser作为构造函数中的参数并且它的子类的构造都是通过多个参数的构造函数构造的。
所以目前所有的Sentinel starter中的DataSource都是基于FactoryBean并且通过设置属性构造的。如果有这方面的需求需要再多加一个registerFactoryBean过程。
SentinelDataSourceRegistry.registerFactoryBean("custeom", CustomDataSourceFactoryBean.class);
在启动ServiceApplication的前提下再启动ConsumerApplication。
如果自定义DataSource可以注入属性那么没有必要使用SentinelDataSourceRegistry注册FactoryBean。
ConsumerApplication在Consumer端设置的限流规则所以启动完成后查看控制台的打印信息会发现部分调用被Block。
## More
Sentinel 是一款功能强大的中间件,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。此 Demo 仅演示了 使用 Sentinel 作为限流工具的使用,更多 Sentinel 相关的信息,请参考 [Sentinel 项目](https://github.com/alibaba/Sentinel)。

@ -165,42 +165,78 @@ To see the metrics, click **实时监控(Real-time Monitoring)** in the left-sid
<p align="center"><img src="https://cdn.nlark.com/lark/0/2018/png/54319/1532313595369-8428cd7d-9eb7-4786-a149-acf0da4a2daf.png" width="480" heigh='180'></p>
## Dubbo
## DataSource
[Dubbo](http://dubbo.apache.org/) is a high-performance, java based open source RPC framework.
Sentinel provide [DataSource](https://github.com/alibaba/Sentinel/blob/master/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/DataSource.java) to manage dynamic rules.
Sentinel provide a module named [sentinel-dubbo-adapter](https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-dubbo-adapter)to support dubbo。sentinel-starter integrates this feature by default.
Sentinel starter integrated 4 DataSources provided by Sentinel. It will be register into Spring Context if you write some configs in `application.properties`.
For example, a service named FooService, see the code below:
If you want to define FileRefreshableDataSource:
package org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService;
public interface FooService {
String hello(String name);
}
spring.cloud.sentinel.datasource.type=file
spring.cloud.sentinel.datasource.recommendRefreshMs=2000
spring.cloud.sentinel.datasource.bufSize=2048
spring.cloud.sentinel.datasource.charset=utf-8
spring.cloud.sentinel.datasource.configParser=myParser
spring.cloud.sentinel.datasource.file=/Users/you/rule.json
The resource name of this service is `org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService:hello(java.lang.String)` .
then use `@SentinelDataSource` to annotate DataSource:
You should handle SentinelRpcException if rpc invocation was be limited on Consumer side:
@SentinelDataSource("spring.cloud.sentinel.datasource")
private DataSource dataSource;
FooService service = applicationContext.getBean(FooService.class);
The value() of `@SentinelDataSource` is not required, it means the prefix of configuration. Default value is `spring.cloud.sentinel.datasource`.
for (int i = 0; i < 15; i++) {
try {
String message = service.hello("Jim");
} catch (SentinelRpcException ex) {
System.out.println("Blocked");
} catch (Exception ex) {
ex.printStackTrace();
spring.cloud.sentinel.datasource.type means the type of DataSource.
spring.cloud.sentinel.datasource.recommendRefreshMs means the recommendRefreshMs property of specified DataSource.
spring.cloud.sentinel.datasource.configParser means the name of spring bean that type is ConfigParser. If the bean is not exists, will throw exception.
Now datasource type support 4 categories: file, nacos, zk, apollo.
### User-defined DataSource
User-defined DataSource need 2 steps.
1. Define DataSource
public class CustomDataSource implements DataSource {
private String fieldA;
private String fieldB;
...
}
}
It will throw RpcException on Consumer side if it was be limited on Provider side, because Provider side throw SentinelRpcException in this scene.
2. Assemble DataSource. There are 2 ways to do this.
### Start Application
* Construct DataSource directly
@Bean
public CustomDataSource customDataSource() {
CustomDataSource customDataSource = new CustomDataSource();
customDataSource.setFieldA("valueA");
customDataSource.setFieldB("valueB");
...
return customDataSource;
}
* define DataSource metadata in `classpath:/META-INF/sentinel-datasource.properties`
custom = yourpackage.CustomDataSource
define configuration in `application.properties`
spring.cloud.sentinel.datasource.type = custom
spring.cloud.sentinel.datasource.fieldA = valueA
spring.cloud.sentinel.datasource.fieldB = valueB
Note: The AbstractDataSource of Sentinel need a ConfigParser as a constructor param and the subclass of AbstractDataSource was construct by multi-param constructor.
Now All DataSources in starter was construct by FactoryBean. If you want to do it in this way, you should register FactoryBean by SentinelDataSourceRegistry.
SentinelDataSourceRegistry.registerFactoryBean("custeom", CustomDataSourceFactoryBean.class);
You can startup ConsumerApplication after ServiceApplication startup.
It is no need to using SentinelDataSourceRegistry to register FactoryBean if your User-defined DataSource can inject fields.
ConsumerApplication init flow control rules after startup, so you will find some invocations have been blocked in console.
## More
For more information about Sentinel, see [Sentinel Project](https://github.com/alibaba/Sentinel).

@ -0,0 +1,18 @@
package org.springframework.cloud.alibaba.cloud.examples;
import java.util.List;
import com.alibaba.csp.sentinel.datasource.ConfigParser;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
/**
* @author fangjian
*/
public class JsonFlowRuleListParser implements ConfigParser<String, List<FlowRule>> {
@Override
public List<FlowRule> parse(String source) {
return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {});
}
}

@ -1,5 +1,6 @@
package org.springframework.cloud.alibaba.cloud.examples;
import com.alibaba.csp.sentinel.datasource.ConfigParser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
@ -23,6 +24,11 @@ public class ServiceApplication {
return new RestTemplate();
}
@Bean
public ConfigParser myParser() {
return new JsonFlowRuleListParser();
}
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}

@ -1,24 +0,0 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo;
import org.springframework.boot.Banner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.alibaba.cloud.examples.dubbo.provider.ProviderApplication;
import org.springframework.stereotype.Component;
/**
* @author fangjian
*/
@Component
public class DubboProviderRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
SpringApplicationBuilder providerBuilder = new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF).registerShutdownHook(false)
.logStartupInfo(false).web(WebApplicationType.NONE);
providerBuilder.sources(ProviderApplication.class).run(args);
}
}

@ -1,10 +0,0 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo;
/**
* @author fangjian
*/
public interface FooService {
String hello(String name);
}

@ -1,17 +0,0 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo.provider;
import org.springframework.cloud.alibaba.cloud.examples.dubbo.FooService;
import com.alibaba.dubbo.config.annotation.Service;
/**
* @author fangjian
*/
@Service
public class FooServiceImpl implements FooService {
@Override
public String hello(String name) {
return "hello, " + name;
}
}

@ -1,38 +0,0 @@
package org.springframework.cloud.alibaba.cloud.examples.dubbo.provider;
import org.springframework.context.annotation.Bean;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
/**
* @author fangjian
*/
@DubboComponentScan("org.springframework.cloud.alibaba.cloud.examples.dubbo.provider")
public class ProviderApplication {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("demo-provider");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("multicast://224.5.6.7:1234");
return registryConfig;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(25758);
return protocolConfig;
}
}

@ -3,3 +3,12 @@ server.port=18083
management.endpoints.web.exposure.include=*
spring.cloud.sentinel.port=8721
spring.cloud.sentinel.dashboard=localhost:8080
spring.cloud.sentinel.datasource.type=file
spring.cloud.sentinel.datasource.recommendRefreshMs=3000
spring.cloud.sentinel.datasource.bufSize=4056196
spring.cloud.sentinel.datasource.charset=utf-8
spring.cloud.sentinel.datasource.configParser=myParser
spring.cloud.sentinel.datasource.file=/Users/you/rule.json
Loading…
Cancel
Save