所有代碼都在github上:https://github.com/demonruin/cloud2020/tree/master
Sentinel集成Ribbon:
1、準備服務提供者cloudalibaba-nacos-provider-payment9001,cloudalibaba-nacos-provider-payment9002,主要是端口不一樣,其他一致,下面附上pom、yml和主業務類代碼,這裏自己建module即可
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web組件 -->
<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>
server:
port: 9001
spring:
application:
name: nacos-provider-payment
cloud:
nacos:
discovery:
server-addr: localhost:8848
#暴露所有端點,和actuator監控有關
management:
endpoints:
web:
exposure:
exclude: "*"
package com.king.springcloud.controller;
import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
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;
/**
* created by king on 2020/5/8 12:38 下午
*/
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
/**
* 此方法與接口是爲了測試sentinel的fallback服務降級
* @param id
* @return
*/
public static HashMap<Integer, Payment> hashMap = new HashMap();
static {
hashMap.put(1, new Payment(1L, "28a8c1e3bc2742d8848569891fb42181"));
hashMap.put(2, new Payment(2L, "bba8c1e3bc2742d8848569891ac32182"));
hashMap.put(3, new Payment(3L, "6ua8c1e3bc2742d8848569891xt92183"));
}
@GetMapping("/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Integer id) {
Payment payment = hashMap.get(id);
CommonResult<Payment> result = new CommonResult(200, "from mysql,serverPort: " + serverPort, payment);
return result;
}
}
主啓動類就是正常的主啓動類
package com.king.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* created by king on 2020/5/8 12:08 下午
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderPaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(NacosProviderPaymentMain9001.class,args);
}
}
2、主要是構建服務消費者微服務,這裏pom中添加nacos/sentinel/openFeing等依賴,yml中添加nacos和sentinel的配置,再有測試業務類
<!--SpringCloud openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot整合Web組件 -->
<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>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>com.king.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
server:
port: 83
spring:
application:
name: nacos-consumer-order
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
dashboard: localhost:8080
port: 8719
package com.king.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* created by king on 2020/5/8 4:01 下午
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosConsumerOrderMain83 {
public static void main(String[] args) {
SpringApplication.run(NacosConsumerOrderMain83.class, args);
}
}
業務類CircleBreakerController
package com.king.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import com.king.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
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;
/**
* created by king on 2020/5/29 11:19 上午
*/
@RestController
@Slf4j
public class CircleBreakerController {
private static String SERVICE_URL="http://nacos-provider-payment/";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
@SentinelResource(value = "fallback") //沒有配置
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只負責業務異常
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只負責sentinel控制檯配置違規
// @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
// exceptionsToIgnore = {IllegalArgumentException.class})
public CommonResult<Payment> fallback(@PathVariable Long id)
{
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/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
public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(444,"兜底異常handlerFallback,exception內容 "+e.getMessage(),payment);
}
//本例是blockHandler
public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(445,"blockHandler-sentinel限流,無此流水: blockException "+blockException.getMessage(),payment);
}
//==================OpenFeign===================
@Resource
private PaymentService paymentService;
@GetMapping(value = "/consumer/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
{
return paymentService.paymentSQL(id);
}
}
3、此時測試代碼準備完畢,進行測試
- 當@SentinelResource(value = "fallback") //沒有其他任何配置的時候,根據代碼處理,
- 當我們id=1或2或3時,是能正常響應的
- 當我們id=4時,會IllegalArgumentException,非法參數異常....
- 當我們id=5時,會NullPointerException,該ID沒有對應記錄,空指針異常
- 當@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只負責業務異常
- 當我們id=1或2或3時,是能正常響應的
- 當我們id=4時,會有 handlerFallback來處理異常
- 當我們id=5時,會有 handlerFallback來處理異常
- 當@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只負責sentinel控制檯配置違規
- 當我們id=1或2或3時,1qps是能正常響應的,快速訪問會觸發流控規則,返回自定義的處理方法結果
- 當我們id=4時,1qps是能正常響應的,快速訪問會觸發流控規則,返回自定義的處理方法結果
- 當我們id=5時,1qps是能正常響應的,快速訪問會觸發流控規則,返回自定義的處理方法結果
我們對@SentinelResource的value值進行流控限制
- 當@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class})
- 當我們id=1或2或3時,1qps是能正常響應的,快速訪問會觸發流控規則,返回自定義的處理方法結果
- 當我們id=4時,因爲exceptionsToIgnore = {IllegalArgumentException.class},忽略了這個異常,所以1qps訪問還是會正常報錯頁面的,快速訪問會觸發流控規則,返回自定義的處理方法結果
- 當我們id=5時,1qps是能正常響應的,快速訪問會觸發流控規則,返回自定義的處理方法結果
對了,多次刷新訪問id=1的時候,會有Ribbon的輪訓功能,會輪訓請求9001和9002端口的服務~~~~~~~
至此是Sentinel集成Ribbon的案例,及@SentinelResource的fallback演示~~
Sentinel集成OpenFeign
1、在上述基礎上,添加feign調用接口代碼:
帶@FeignClient註解的業務接口 :PaymentService接口
package com.king.springcloud.service;
import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* created by king on 2020/5/29 1:30 下午
*/
@FeignClient(value = "nacos-provider-payment", fallback = PaymentServiceFallback.class)
public interface PaymentService {
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
fallback = PaymentServiceFallback.class :PaymentServiceFallback處理方法:注意加@Component註解
package com.king.springcloud.service;
import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import org.springframework.stereotype.Component;
/**
* created by king on 2020/5/29 1:33 下午
*/
@Component
public class PaymentServiceFallback implements PaymentService{
@Override
public CommonResult<Payment> paymentSQL(Long id) {
return new CommonResult<>(44444,"服務降級返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
}
}
controller中的fengin代碼上面已經粘貼了,現在附上主要代碼
//==================OpenFeign===================
@Resource
private PaymentService paymentService;
@GetMapping(value = "/consumer/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
{
return paymentService.paymentSQL(id);
}
在yml文件中添加 激活Sentinel對Feign的支持
feign:
sentinel:
enabled: true # 激活Sentinel對Feign的支持
2、進行測試~~
①、正常請求接口,能正常訪問,返回結果
②、測試83調用9001,此時故意關閉9001微服務提供者,看83消費側自動降級,不會被耗死
此時調用了服務降級,說明OpenFeign的fallback處理邏輯生效了~~
至此Sentinel對OpenFeign的集成案例演示完畢~~