本文主要是为了通过整合sentinel和ribbon,openFeign,nacos等,通过一个小demo来串联知识
业务需求:创建两个服务提供者nacos9001,nacos9002,一个消费者nacosOrder,在nacosOrder中配置sentinel指定fallback和blockHandler达到降级效果,并通过远程调用ribbon或者openFeign调用服务提供者的接口
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
public static HashMap<Long, Payment>map=new HashMap<>();
static{
map.put(1L,new Payment(1L,"qweoiwetewrt"));
map.put(2L,new Payment(2L,"lllllasdzxc"));
map.put(3L,new Payment(3L,"pppppqwe,asdf"));
}
@GetMapping("/payment/nacos/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Integer id){
Payment payment=(Payment) map.get(Long.valueOf(id));
return new CommonResult<Payment>(200,"from mysql serverport:"+serverPort,payment);
}
}
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*' #监控
服务消费者9003
<dependencies>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--springcloud alibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--springcloud alibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //RestTemplate结合Ribbon做负载均衡一定要加@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
@RestController
public class OrderNacosController {
/*
因为在yml中配置了service-url.nacos-user-service,
这里不需要再定义要访问微服务名常量,而是通过boot直接读出来
*/
@Value("${service-url.nacos-user-service}")
private String serverURL;
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/nacos/{id}")
@SentinelResource(value = "fallback")
public CommonResult<Payment> paymentInfo(@PathVariable("id") Long id){
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id, CommonResult.class);
}
}
方案一:只配置fallback
@GetMapping("/consumer/payment/nacos/{id}")
@SentinelResource(value = "fallback",fallback = "handlerFallback")
public CommonResult<Payment> paymentInfo(@PathVariable("id") Long id){
CommonResult<Payment> result=restTemplate.getForObject(serverURL+"/payment/nacos/"+id, CommonResult.class);
if(id==4){
throw new IllegalArgumentException("illegalArgumentException||非法参数---");
}
else if(result.getData()==null){
throw new NullPointerException("该ID没有应对记录,空指针异常--");
}
return result;
}
public CommonResult<Payment>handlerFallback(@PathVariable("id") Long id,Throwable e){
Payment payment=new Payment(id,"null");
return new CommonResult<>(444,"兜底异常内容:"+e.getMessage(),payment);
}
方案二:同时配置blockHandler和fallback(上一篇文章中有提到)
@GetMapping("/consumer/payment/nacos/{id}")
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")
public CommonResult<Payment> paymentInfo(@PathVariable("id") Long id){
CommonResult<Payment> result=restTemplate.getForObject(serverURL+"/payment/nacos/"+id, CommonResult.class);
if(id==4){
throw new IllegalArgumentException("illegalArgumentException||非法参数---");
}
else if(result.getData()==null){
throw new NullPointerException("该ID没有应对记录,空指针异常--");
}
return result;
}
public CommonResult<Payment>handlerFallback(@PathVariable("id") Long id,Throwable e){
Payment payment=new Payment(id,"null");
return new CommonResult<>(444,"兜底异常内容:"+e.getMessage(),payment);
}
public CommonResult<Payment>blockHandler(@PathVariable("id") Long id, BlockException exception){
Payment payment=new Payment(id,"null");
return new CommonResult<>(500,"sentinel限流,block:"+exception,payment);
}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderNacosMain8005 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain8005.class,args);
}
}
@FeignClient(value = "nacos-payment-provider",fallback = orderServiceImpl.class)
//注册中心的服务名称
public interface orderService {
//服务提供者的接口名字,原原本本搬过来
@GetMapping("/payment/nacos/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") long id);
}
@Service
public class orderServiceImpl implements orderService{
@Override
public CommonResult<Payment> getPayment(long id) {
return new CommonResult<>(444,"服务降级返回,--",new Payment(0,"errorSerial"));
}
}
@RestController
public class orderController {
@Resource
orderService service;
@GetMapping("/consumer1/payment/nacos/{id}")
@SentinelResource(value = "fallback1")
public CommonResult<Payment> paymentInfo(@PathVariable("id") Long id){
return service.getPayment(id);
}
}