• springcloud搭建实战<十>【zuul网关】


    ZUUL基础知识

    zuul是spring cloud提供的一个通用api网关组件

    在这里插入图片描述

    ZUUl过滤器

    1、4种类型

    pre、routing、post、error

    顺序:pre>routing>post

     

    2、参数配置

     注意:

    /zuul 路径下网关会跳过dispatcherServlet  而由zuulServlet处理

    3、实现服务降级

    zuul包下是带hystrix包

    1. #ribbonTimeout = (ReadTimeout + ConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
    2. ribbon:
    3. ReadTimeout: 10000
    4. ConnectTimeout: 10000
    5. hystrix:
    6. command:
    7. default:
    8. execution:
    9. isolation:
    10. thread:
    11. timeoutInMilliseconds: 60000

    实战环境

    工具:IntelliJ IDEA 2019.2.4

    JDK:1.8

    父项目以及注册中心、服务方详见之前博客。

    【消费方与之前服务方步骤一致,以下文章步骤基本一致】

    步骤

    1、打开父项目,file->new module  

     2、填写项目信息、next

     3、pom文件新增连个依赖包

    1. org.springframework.cloud
    2. spring-cloud-starter-netflix-zuul
    3. org.springframework.cloud
    4. spring-cloud-starter-netflix-eureka-client
    5. org.springframework.boot
    6. spring-boot-starter-test
    7. test
    8. org.junit.vintage
    9. junit-vintage-engine

    4、yml文件:

    1. server:
    2. port: 8000
    3. spring:
    4. application:
    5. name: cloud-zuul
    6. eureka:
    7. client:
    8. service-url:
    9. defaultZone: http://user:123456@localhost:8080/eureka
    10. healthcheck:
    11. enabled: true #健康检查(需要spring-boot-starter-actuator依赖)
    12. instance:
    13. prefer-ip-address: true
    14. lease-renewal-interval-in-seconds: 10 # 续约更新时间间隔(默认30秒)
    15. lease-expiration-duration-in-seconds: 10 # 续约到期时间(默认90秒)
    16. #zuul代理配置 zuul.routes.服务名.path,服务名要与注册的一致
    17. zuul:
    18. routes:
    19. api-provider:
    20. path: /api-provider/**
    21. service-id: cloud-provider #应用名映射
    22. api-consumer:
    23. path: /api-consumer/**
    24. service-id: cloud-consumer #应用名映射
    25. ignored-patterns: /**/admin/** #过滤掉匹配URL
    26. sensitive-headers: #默认会过滤 "Cookie", "Set-Cookie", "Authorization" 会影响统一授权
    27. # strip-prefix: true #默认时或true时 转发到服务的请求是/**,如果stripPrefix=false,转发的请求是直接/api-consumer/**
    28. # prefix: /api #会对所有的path增加一个/api前缀

    5、application加入Zuul注解

    @EnableZuulProxy

    6.启动,查看注册中心

    7、通过ZUUL调用

    访问provider

    http://localhost:8000/api-provider/sayHi

    访问:consumer

    http://localhost:8000/api-consumer/houseManage//queryCustomerInfoByTel?tel=232

    8、新增权限校验AcessFiltler

     访问:http://localhost:8000/api-consumer/houseManage/queryCustomerInfoByTel?tel=232&acessToken=123

    1. package com.cloud.zuul.filter;
    2. import com.alibaba.fastjson.JSONObject;
    3. import com.netflix.zuul.ZuulFilter;
    4. import com.netflix.zuul.context.RequestContext;
    5. import com.netflix.zuul.exception.ZuulException;
    6. import org.apache.http.HttpStatus;
    7. import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    8. import org.springframework.stereotype.Component;
    9. import javax.servlet.http.HttpServletRequest;
    10. import java.util.HashMap;
    11. import java.util.Map;
    12. /**
    13. * @author 10450
    14. * @description 权限token校验
    15. * @date 2022/9/2 14:45
    16. */
    17. @Component
    18. public class AcessFilter extends ZuulFilter {
    19. @Override
    20. public String filterType() {
    21. return FilterConstants.PRE_TYPE;
    22. }
    23. @Override
    24. public int filterOrder() {
    25. return FilterConstants.PRE_DECORATION_FILTER_ORDER - 2;//最前进行校验
    26. }
    27. @Override
    28. public boolean shouldFilter() {
    29. return true;
    30. }
    31. @Override
    32. public Object run() throws ZuulException {
    33. //1、获取request对象
    34. RequestContext ctx = RequestContext.getCurrentContext();
    35. HttpServletRequest request = ctx.getRequest();
    36. //2、获取token参数
    37. String token = request.getParameter("acessToken");
    38. //3、对比token
    39. if(token == null || !("123".equals(token))){//假设token查到为123
    40. //4、token校验失败,直接响应数据
    41. Map result = new HashMap<>();
    42. result.put("code",HttpStatus.SC_UNAUTHORIZED);
    43. result.put("msg","存在SQL注入风险");
    44. ctx.getResponse().setContentType("text/html;charset=UTF-8");
    45. ctx.setResponseBody(JSONObject.toJSONString(result));
    46. ctx.setSendZuulResponse(false);//不响应
    47. // ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);//401
    48. }
    49. return null;
    50. }
    51. }

    9、新增服务降级

    1. package com.cloud.zuul.fallback;
    2. import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
    3. import org.springframework.http.HttpHeaders;
    4. import org.springframework.http.HttpStatus;
    5. import org.springframework.http.MediaType;
    6. import org.springframework.http.client.ClientHttpResponse;
    7. import org.springframework.stereotype.Component;
    8. import java.io.ByteArrayInputStream;
    9. import java.io.IOException;
    10. import java.io.InputStream;
    11. /**
    12. * @author 10450
    13. * @description ZUUL实现降级
    14. * @date 2022/9/2 14:36
    15. */
    16. @Component
    17. public class ZuulFallback implements FallbackProvider {
    18. @Override
    19. public String getRoute() {
    20. return "*"; //指定全部出现问题的服务都走这个降级方法
    21. }
    22. @Override
    23. public ClientHttpResponse fallbackResponse(String route, Throwable cause) {//route表示服务名
    24. System.out.println("降级的服务:"+route);
    25. cause.printStackTrace();//问题打印
    26. return new ClientHttpResponse() {
    27. @Override
    28. public HttpStatus getStatusCode() throws IOException {
    29. return HttpStatus.INTERNAL_SERVER_ERROR;
    30. }
    31. @Override
    32. public int getRawStatusCode() throws IOException {
    33. return HttpStatus.INTERNAL_SERVER_ERROR.value(); //500状态码
    34. }
    35. @Override
    36. public String getStatusText() throws IOException {
    37. //指定错误信息
    38. return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
    39. }
    40. @Override
    41. public void close() {
    42. }
    43. @Override
    44. public InputStream getBody() throws IOException {
    45. String msg = "当前服务:"+ route + ",出现问题";
    46. return new ByteArrayInputStream(msg.getBytes());
    47. }
    48. @Override
    49. public HttpHeaders getHeaders() {
    50. //指定响应头信息
    51. HttpHeaders headers = new HttpHeaders();
    52. headers.setContentType(MediaType.APPLICATION_JSON);
    53. return headers;
    54. }
    55. };
    56. }
    57. }

  • 相关阅读:
    Linux 中的内部命令和外部命令
    MyBatisPlus分页实现
    无人直播系统源码==技术搭建(源头)
    C#语言高阶开发
    LeetCode刷题笔记【29】:动态规划专题-1(斐波那契数、爬楼梯、使用最小花费爬楼梯)
    专用短程通讯(DSRC)技术介绍
    [杂记]关于C++中友元的一些理解
    vue监听表单项填写完整
    Grafana+Prometheus+Windows_exporter+Mysql_exporter
    【附源码】Python计算机毕业设计企业员工考勤管理系统
  • 原文地址:https://blog.csdn.net/chenlu4ever/article/details/126640285