微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)

一、简介

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
 
Sentinel 具有以下特征 :
  • 丰富的应用场景 Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  •  
    完备的实时监控 Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  •  
    广泛的开源生态 Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 SpringCloud、 Dubbo gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
  •  
    完善的 SPI 扩展点 Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第1张图片
 
Sentinel Hystrix 的区别:
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第2张图片
 
有关的名词:
 
Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard 。核心库不依赖 Dashboard ,但是结合Dashboard 可以取得最好的效果。
 
使用 Sentinel 来进行熔断保护,主要分为几个步骤:
(1) 定义资源
(2) 定义规则
(3) 检验规则是否生效
 
资源 :可以是任何东西,一个服务,服务里的方法,甚至是一段代码。
 
规则 Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则
和 热点参数规则。 Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效 。
 
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
 
下载(您可以从官方网站中下载最新版本的控制台 jar 包):

https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar

java -Dserver.port=9090 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar
其中 - Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080
 
Sentinel 1.6.0 起, Sentinel 控制台引入基本的 登录 功能,默认用户名和密码都是 sentinel
 
注意: 启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
 
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第3张图片
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第4张图片
 
启动成功!!!
 
浏览器输入localhost:9090。
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第5张图片
 
登陆之后:
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第6张图片
 

 

二、微服务注册到sentinel

微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第7张图片

基础的项目目录。
 
首先父工程需要引入:
 
        
            
                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                2.1.0.RELEASE
                pom
                import
            
        
    

feign和rest子工程引入:

   
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        

配置文件放入:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:9090   #sentinel控制台的请求地址

分别启动两个子项目一个是9003端口,一个是9004。注册中心、以及消费者。

先分别访问两个接口:

之后刷新:

微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第8张图片

就出来了。对应的信息。

微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第9张图片

三、配置rest资源保护(熔断降级)

修改rest的order-service

package cn.itcast.order.controller;

import cn.itcast.order.entity.Product;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping("/order")
public class OrderController {

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * @SentinelResource
	 *      blockHandler : 声明熔断时调用的降级方法
	 *      fallback : 抛出异常执行的降级方法
	 *      value : 自定义的资源名称
	 *          * 不设置:当前全类名.方法名
	 */
	@SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback")
	@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
	public Product findById(@PathVariable Long id) {
		if(id != 1) {
			throw new RuntimeException("错误");
		}
		return restTemplate.getForObject("http://service-product/product/1",Product.class);
	}


	/**
	 * 定义降级逻辑
	 *  hystrix和sentinel
	 *      熔断执行的降级方法
	 *      抛出异常执行的降级方法
	 */
	public Product orderBlockHandler(Long id) {
		Product product = new Product();
		product.setProductName("触发熔断的降级方法");
		return product;
	}

	public Product orderFallback(Long id) {
		Product product = new Product();
		product.setProductName("抛出异常执行的降级方法");
		return product;
	}

}

这里我们有两个方法,分别是熔断执行的降级方法,和抛出异常执行的降级方法。在hystrix中这个是不区分的,但是在sentinel是区分开的。

配置降级规则:

微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第10张图片

输入:

过5s再访问就可以了。这种全都是fallback的降级处理。其他处理看表:
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第11张图片
 
微服务:SpringCloud 比hystrix牛的Sentinel(国人的骄傲!)_第12张图片

 

四、加载本地配置和另一种配置

大家有没有发现,如果我们重启项目之后,再sentinel中配置的东西就都没了。我们可以搞一个本地配置。

写一个json

[
  {
    "resource": "orderFindById",
    "controlBehavior": 0,
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0
  }
]
  •  resource:资源名,即限流规则的作用对象
  • count: 限流阈值
  • grade: 限流阈值类型(QPS 或并发线程数)
  • limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
  • strategy: 调用关系限流策略
  • controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)

然后在配置文件中加入,就可以了

cloud:
    sentinel:
      datasource:
        ds1:
          file:
            file: classpath:flowrule.json
            data-type: json
            rule-type: flow
另一种配置rest方法:
 
定义一个类:
package cn.itcast.order.exception;

import cn.itcast.order.entity.Product;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import feign.Feign;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;

public class ExceptionUtils {

	/**
	 * 静态方法
	 *      返回值: SentinelClientHttpResponse
	 *      参数 : request , byte[] , clientRquestExcetion , blockException
	 */
	//限流熔断业务逻辑
	public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
		Product product = new Product();
		product.setProductName("限流熔断");
		return new SentinelClientHttpResponse(JSON.toJSONString(product));
	}

	//异常降级业务逻辑
	public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body,
		ClientHttpRequestExecution execution, BlockException ex) {
		Product product = new Product();
		product.setProductName("异常降级");
		return new SentinelClientHttpResponse(JSON.toJSONString(product));
	}

}

启动类加入:

package cn.itcast.order;

import cn.itcast.order.exception.ExceptionUtils;
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EntityScan("cn.itcast.order.entity")
public class RestOrderApplication {

	/**
	 * sentinel支持对restTemplate的服务调用使用sentinel方法.在构造
	 *  RestTemplate对象的时候,只需要加载@SentinelRestTemplate即可
	 *
	 *  资源名:
	 *       httpmethod:schema://host:port/path :协议、主机、端口和路径
	 *       httpmethod:schema://host:port :协议、主机和端口
	 *
	 *  @SentinelRestTemplate:
	 *    异常降级
	 *      fallback      : 降级方法
	 *      fallbackClass : 降级配置类
	 *    限流熔断
	 *      blockHandler
	 *      blockHandlerClass
	 */

	@LoadBalanced
	@Bean
	@SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",
		blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class
	)
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

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

之后就不需要之前 @SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback") 的配置了。

配置sentinel

配置feign组件的熔断降级:
 
实际上什么都不用变,就将添加依赖和配置文件修改为支持sentinel就可以了
#激活sentinel的支持
feign:
  sentinel:
    enabled: true

 
 
 
 
源码:[email protected]:Zesystem/springclouddemosentinel.git
 
 

你可能感兴趣的:(微服务,分布式)