- Sentinel整合ribbon+openFeign+fallback:
- 一、Sentinel整合Ribbon:
- 第一步:启动nacos和setinel后台服务:
- 第二步:创建提供者模块9003和9004:
- 第三步:创建消费者模块84:
- 二、Sentinel整合OpenFeign:
省略…
第二步:创建提供者模块9003和9004:(1)新建maven模块: cloudalibaba-provider-payment9003
(2)改pom:
com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discoverycom.alibaba.csp sentinel-datasource-nacoscom.alibaba.cloud spring-cloud-starter-alibaba-sentinelorg.springframework.cloud spring-cloud-starter-openfeignorg.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-actuatororg.springframework.boot spring-boot-devtoolsruntime true org.projectlombok lomboktrue cn.hutool hutool-core5.6.5
(3)写yml:
server:
port: 9003
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery: #注册中心的地址
server-addr: 192.168.211.205:1111 #这里做了nginx的均衡负载
management: #springboot端点暴露,这里我们暴露所有端点
endpoints:
web:
exposure:
exclude: '*'
(4)主启动类:com.fan.springcloud.PaymentProviderMain9003
package com.fan.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentProviderMain9003 {
public static void main(String[] args) {
SpringApplication.run(PaymentProviderMain9003.class,args);
}
}
(5)业务类:controller.PaymentController:
package com.fan.springcloud.controller;
import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
public static HashMap hashMap = new HashMap();
//模拟数据库,存了三条记录
static{
hashMap.put(1L,new Payment(1L,"1234567890QWERTYUIOP1"));
hashMap.put(2L,new Payment(2L,"1234567890QWERTYUIOP2"));
hashMap.put(3L,new Payment(3L,"1234567890QWERTYUIOP3"));
}
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult paymentSQL(@PathVariable("id") Long id ){
Payment payment = hashMap.get(id);
CommonResult paymentCommonResult =
new CommonResult<>(200, "来自数据库,端口号:" +
serverPort, payment);
return paymentCommonResult;
}
}
同理,新建一个提供者cloudalibaba-provider-payment9004:
测试:启动两个微服务9003和9004:
网页测试地址:localhost:9003/paymentSQL/1
第三步:创建消费者模块84:(1)新建消费者模块:cloudalibaba-consumer-nacos-order84
(2)修改pom:
com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discoverycom.alibaba.csp sentinel-datasource-nacoscom.alibaba.cloud spring-cloud-starter-alibaba-sentinelorg.springframework.cloud spring-cloud-starter-openfeignorg.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-actuatororg.springframework.boot spring-boot-devtoolsruntime true org.projectlombok lomboktrue cn.hutool hutool-core5.6.5
(3)写yml:
server:
port: 84
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: 192.168.211.205:1111
sentinel:
transport:
dashboard: localhost:8080 #配置sentinel 的仪表盘地址
port: 8719 #默认仪表盘8719端口
#消费者将要去访问的微服务的名称(注册成功进nacos的微服务提供者
service-url:
nacos-user-service: http://nacos-payment-provider
(4)主启动类:com.fan.springcloud.OrderNacosMain84
package com.fan.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain84 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain84.class,args);
}
}
(5)业务类:
负载均衡配置类:config.ApplicationContextConfig:
package com.fan.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
controller.CircleBreakerController类:分如下几种情况:
情况一:没有任何配置:给客户error页面,不友好
package com.fan.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@Slf4j
public class CircleBreakerController {
//依赖注入restTemplate
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}") //restful风格的路径参数
@SentinelResource(value = "fallback") //没有配置
public CommonResult fallback(@PathVariable("id") Long id){
log.info("测试fallback------");
CommonResult result =
restTemplate.getForObject("http://nacos-payment-provider/paymentSQL/"+id,CommonResult.class,id);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException:非法参数异常。。。。");
}else if(result.getData() == null){
throw new NullPointerException("NullPointerException:该id没有对应的记录,空指针异常!!!");
}
return result;
}
}
测试地址:localhost:84/consumer/fallback/1
多刷新几下地址:发现负载均衡到9003和9004端口:
换一个id测试:
当数据库没有查到数据的时候出现错误页面,不友好:
情况二:带fallback:
fallback只负责java业务逻辑异常:
package com.fan.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@Slf4j
public class CircleBreakerController {
//依赖注入restTemplate
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}") //restful风格的路径参数
//@SentinelResource(value = "fallback") //没有配置
@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责java业务逻辑异常
public CommonResult fallback(@PathVariable("id") Long id){
log.info("测试fallback------");
CommonResult result =
restTemplate.getForObject("http://nacos-payment-provider/paymentSQL/"+id,CommonResult.class,id);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException:非法参数异常。。。。");
}else if(result.getData() == null){
throw new NullPointerException("NullPointerException:该id没有对应的记录,空指针异常!!!");
}
return result;
}
//兜底应急fallback方法handlerFallback
public CommonResult handlerFallback(@PathVariable Long id,Throwable e){
Payment payment = new Payment(id,"null");
return new CommonResult(444,"兜底应急fallback方法handlerFallback," +
"异常内容"+e.getMessage(),payment);
}
}
测试:http://localhost:84/consumer/fallback/4
测试:http://localhost:84/consumer/fallback/5
情况三:带blockhandler:
blockHandler只负责sentinel控制台配置违规:
控制台配置:
测试:
情况四:两种都配置:
package com.fan.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@Slf4j
public class CircleBreakerController {
//依赖注入restTemplate
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}") //restful风格的路径参数
//@SentinelResource(value = "fallback") //没有配置
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责java业务逻辑异常
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
@SentinelResource(value = "fallback",blockHandler = "blockHandler",fallback = "handlerFallback") //blockHandler只负责sentinel控制台配置违规
public CommonResult fallback(@PathVariable("id") Long id){
log.info("测试fallback------");
CommonResult result =
restTemplate.getForObject("http://nacos-payment-provider/paymentSQL/"+id,CommonResult.class,id);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException:非法参数异常。。。。");
}else if(result.getData() == null){
throw new NullPointerException("NullPointerException:该id没有对应的记录,空指针异常!!!");
}
return result;
}
//兜底应急fallback方法handlerFallback
public CommonResult handlerFallback(@PathVariable Long id,Throwable e){
Payment payment = new Payment(id,"null");
return new CommonResult(444,"兜底应急fallback方法handlerFallback," +
"异常内容"+e.getMessage(),payment);
}
//blockHandler的限流异常处理
public CommonResult blockHandler(@PathVariable("id") Long id, BlockException blockException){
Payment payment = new Payment(id, "null");
return new CommonResult(445,"blockHandler-sentinel限流处理," +
"无此流水,blockException:"+blockException.getMessage());
}
}
控制台添加流控:
忽略异常:
测试:
pom:
yml:
主启动类:
原先不使用openFeign时,我们是在controler中通过中间的restTemplate来进行远程调用,现在换成接口调用的形式,方便。
接口:
接口的实现类:
controller:
测试:
看是否自动降级:



