entinel的官方网址: https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5
-
feign组件是依赖于ribbon的,为什么这么说呢?feign是为了满足于我们的编程习惯,在没有使用feign时,通过ribbon调用远程服务方式:
//String.class 指的是远程方法返回的数据类型 restTemplate.getForObject("http://nacos-provide/hi",String.class);
当添加了feign后,接口定义如下:
@FeignClient(name="nacos-provide") public interface Provide { @RequestMapping("/getConfigName") public String get(); }
该接口添加了@FeignClient注解,controller调用该接口的get方法时的写法如下
@RequestMapping("/getProvide") public String get() { return provide.get(); }
为什么说feign依赖于ribbon呢?因为feign的作用就是把接口拼接起来,写法provide.get();就能调用,实际上是通过feign拼接成:http://nacos-provide/getConfigName,然后通过ribbon解析域名进行服务调用。
-
现在我们谈谈sentinel组件
在进行整合sentinel的时候,我们一定得要注意sentinel的版本号要与feign的版本对应上,不然会报错,我刚开始整合的时候采用了feign的版本为2.0.0.RELEASE,而sentinel采用了2.2.0.RELEASE的版本,导致一直报错,后面采用了sentinel的版本号为2.0.0.RELEASE才能成功启动项目。 -
sentinel进行降级
降级的意思就是说:当客户端调用服务的时候,服务不可用时,最后调用的是本地的一个方法进行处理,避免直接报错返回以及避免等待时间过长,这是一种策略;一些无关紧要的业务可以采用这种策略,只要最后的结果正确就行,比如添加积分业务,在核心的业务上,不可能因为积分服务死掉而导致整个系统不可用的,当积分服务死掉的时候,可以通过降级处理,记录下来该为哪个客户添加积分,然后通过定时任务后续加上对应的积分即可。 -
setinel降级实战
在客户端添加依赖如下<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.0.0.RELEASE</version> </dependency>
注意:因为我用的spring-cloub的版本为Finchley.RELEASE,里面不包含sentinel,所以再引入sentinel的时候,要写明版本号。
配置application.yml文件,开启sentinel
feign: sentinel: enabled: true
在客户端(也就是调用其他服务的项目)定义服务1和服务2。
服务1接口定义:import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; @FeignClient(name="nacos-provide") public interface Provide { @RequestMapping("/getConfigName") public String get(); }
服务2接口定义:
import nacosConsumer.server.impl.OrderServerImpl; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @FeignClient(name = "nacos-provide2", fallback = OrderServerImpl.class) public interface OrderServer { @GetMapping("/order/{id}/{name}") public String getOrder(@PathVariable("id") int id, @PathVariable("name") String name); }
注意服务2比服务1的FeignClient注解上多了fallback = OrderServerImpl.class;这是当服务2机器死掉的时候,调用本地定义的OrderServerImpl类的实现OrderServer接口的方法
先看一下OrderServerImpl类:
import nacosConsumer.server.OrderServer; import org.springframework.stereotype.Component; @Component public class OrderServerImpl implements OrderServer { @Override public String getOrder(int id, String name) { System.out.println("进行降级了-----------------"); return "调用失败,进行熔断"; } }
OrderServerImpl实现了OrderServer接口,当调用远程服务nacos-provide2/order/{id}/{name}失败的时候,会降级去调用OrderServerImpl类的方法。实现高可用。
定义controller:
@RestController public class MyController { @Autowired private Provide provide; @Autowired private OrderServer orderServer; @RequestMapping("/getProvide") public String get() { provide.get(); orderServer.getOrder(10,"100"); return "success---------------"; } }
测试:我把服务2停掉,运行结果:
虽然服务2坏掉了,但是通过sentinel的熔断降级功能,可以保证主流程的正常执行,而不会报错!!!类似于第一条路走不通,选择走第二条路的意思。
-
sentinel实现流量削峰控制
假如一个系统最高每秒能抗住10万次请求,但是突然某一天,一秒钟来了一百万次的请求,如果我们的系统没有对应的处理策略的话,那么系统会宕机导致服务不可用,这是我们不能接受的。此时sentinel的限流就能派上用场了。 -
sentinel的限流实战
下载:sentinel-dashboard-1.6.3.jar
下载地址:https://github.com/alibaba/Sentinel/releases
进入文件夹,运行cmd,运行:java -jar sentinel-dashboard-1.6.3.jar启动sentinel服务。访问:http://localhost:8080/;账号密码都是sentinel,登录进去
在客户端系统的application.yml文件中配置sentinel控制台地址spring: application: name: nacos-consumer cloud: nacos: discovery: server-addr: 127.0.0.1:8848 sentinel: transport: # 制定sentinel的控制台地址 dashboard: localhost:8080 # 指定和控制台通信的IP,若不配置,会自动选择一个IP注册 client-ip: 127.0.0.1 # 指定和控制台通信的端口,默认值8719 # 若不配置,会自动扫猫从8719开始扫猫,依次+1,知道值找到未被占用的端口 port: 8719 # 心跳发送周期,默认值null # 但在SimpleHttpHeartbeatSender会用默认值10秒 heartbeat-interval-ms: 10000
启动服务以及客户端,访问以下客户端的controller地址,然后进入sentinel控制台:
刚才被访问的地址就能显示出来,为什么能sentinel控制台能感应到并且显示出来呢?在sentinel包里面有一个filter过滤器的实现,客户端所有的http请求会通过filter转发到sentinel的web服务上,因此sentinel控制台能显示出访问的接口地址等等,从而进行限流配置流量控制配置:
QPS代表的是每秒钟允许的访问次数,线程数指的是每秒钟能允许多少个线程进行访问!
在一秒中内快速访问多次:http://localhost:860/getProvide(一秒钟内我点了有七八下)
当过去一秒后,重新访问(点击一次),系统又能被正常访问了哟!
至此,利用sentinel限流成功(sentinel的限流策略有很多,我这里只举例了其中一种)
-
利用sentinel实现熔断降级
在上面我们聊到利用sentinel实现降级,那么熔断又是怎么回事呢?在系统调用远程服务的时候,有可能远程服务已经不可用了,如果远程服务是一直都无法使用的话,客户端每次请求还继续尝试调用远程服务的话,那就没有必要了。那么可以怎么做呢?通过sentinel可以配置熔断策略,比如配置在10秒内如果调用远程服务的失败率达到80%的话,那就在这10秒内的剩余时间直接不调用远程服务,而是直接调用本地的降级方法;超过10后又重新开始调用远程服务,失败率达到配置的阈值后,又继续熔断,一直循环配置熔断降级实战:
1.选择服务,点击降级
2.配置熔断策略
调用接口的异常概率大于等于0.5的时候,跳过该接口的调用,直接降级;指导下一个十秒,异常概率清零,规则重新生效,一直循环