首页 > 技术文章 > SpringCloud第四天

wpbing 2021-01-28 21:55 原文

SpringCloud限流时自定义异常处理

@Component
public class MyExceptionHandle implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        Map<String,Object> backMap=new HashMap<>();
        if (e instanceof FlowException){
            backMap.put("code",-1);
            backMap.put("msg","限流-异常啦");
        }else if (e instanceof DegradeException){
            backMap.put("code",-2);
            backMap.put("msg","降级-异常啦");
        }else if (e instanceof ParamFlowException){
            backMap.put("code",-3);
            backMap.put("msg","热点-异常啦");
        }else if (e instanceof SystemBlockException){
            backMap.put("code",-4);
            backMap.put("msg","系统规则-异常啦");
        }else if (e instanceof AuthorityException){
            backMap.put("code",-5);
            backMap.put("msg","认证-异常啦");
        }
        // 设置返回json数据
        httpServletResponse.setStatus(200);
        httpServletResponse.setHeader("content-Type","application/json;charset=UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(backMap));
    }
}

需要每个微服务都要配置

使用Feign整合Sentinel

在某一个微服务宕机的时候,可以给用户提供兜底数据

  1. 每个服务都加入依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. application.yml加入配置
feign:
  sentinel:
    enabled: true
  1. 在order服务中创建video服务的兜底数据
public class VideoServiceFallback implements VideoService {
    @Override
    public Video findById(int videoId) {
        Video video = new Video();
        video.setTitle("兜底数据");
        return video;
    }

    @Override
    public int save(Video video) {
        return 0;
    }
}
  1. 给原来的服务稍微添加一下注解
@FeignClient(value = "wpb-video-service", fallback = VideoServiceFallback.class)
public interface VideoService {

    @GetMapping("/api/v1/video/find_by_id")
    Video findById(@RequestParam("videoId") int videoId);


    @PostMapping("/api/v1/video/save")
    int save(@RequestBody Video video);

}

Long Term Support ⻓期⽀持的版本,如JDK8、JDK11都是属于LTS
以后学习springcloud最好把jdk改成11版本的

springcloud网关的使用

把路由接口都聚合起来,API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能

网关的初体验

  1. 创建一个新模块GateWay
  2. 添加依赖
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 加配置
server:
  port: 8888
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes: #数组形式
        - id: order-service  #路由唯一标识
          uri: http://127.0.0.1:8000  #想要转发到的地址
          order: 1 #优先级,数字越小优先级越高
          predicates: #断言 配置哪个路径才转发
            - Path=/order-server/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1  #去掉第一层前缀
        - id: video-service  #路由唯一标识
          uri: http://127.0.0.1:9000  #想要转发到的地址
          order: 1 #优先级,数字越小优先级越高
          predicates: #断言 配置哪个路径才转发
            - Path=/video-server/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1  #去掉第一层前缀

然后 我们把服务都启动起来,访问的话直接访问这个服务即可
这样存在的问题

  • 微服务地址写死
  • 负载均衡没做到

Gateway配置Nocas

  1. 在GateWay里面添加依赖
<!--添加nacos客户端-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 启动类开启支持
    @EnableDiscoveryClient
  2. 修改配置文件
server:
  port: 8888
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
​
    gateway:
      routes: #数组形式
        - id: order-service  #路由唯一标识
          #uri: http://127.0.0.1:8000  #想要转发到的地址
          uri: lb://wpb-order-service  # 从nacos获取名称转发,lb是负载均衡轮训策略
​
          predicates: #断言 配置哪个路径才转发
            - Path=/order-server/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1 #去掉第一层前缀
      discovery:
        locator:
          enabled: true  #开启网关拉取nacos的服务
​```

推荐阅读