这一章节讲zuul的使用.

在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等信息,

这里Artifact填写eurekazuul, 再次next, 选择内容如下的pom.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.3.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.xum</groupId>
  12. <artifactId>eureka-zuul</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>eureka-zuul</name>
  15. <description>Demo project for Spring Boot</description>
  16.  
  17. <properties>
  18. <java.version>1.8</java.version>
  19. <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
  20. </properties>
  21.  
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-web</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.cloud</groupId>
  29. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.cloud</groupId>
  33. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-actuator</artifactId>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.springframework.cloud</groupId>
  41. <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.springframework.cloud</groupId>
  45. <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.springframework.boot</groupId>
  49. <artifactId>spring-boot-starter-test</artifactId>
  50. <scope>test</scope>
  51. </dependency>
  52. </dependencies>
  53.  
  54. <dependencyManagement>
  55. <dependencies>
  56. <dependency>
  57. <groupId>org.springframework.cloud</groupId>
  58. <artifactId>spring-cloud-dependencies</artifactId>
  59. <version>${spring-cloud.version}</version>
  60. <type>pom</type>
  61. <scope>import</scope>
  62. </dependency>
  63. </dependencies>
  64. </dependencyManagement>
  65.  
  66. <build>
  67. <plugins>
  68. <plugin>
  69. <groupId>org.springframework.boot</groupId>
  70. <artifactId>spring-boot-maven-plugin</artifactId>
  71. </plugin>
  72. </plugins>
  73. </build>
  74.  
  75. <repositories>
  76. <repository>
  77. <id>spring-milestones</id>
  78. <name>Spring Milestones</name>
  79. <url>https://repo.spring.io/milestone</url>
  80. </repository>
  81. </repositories>
  82.  
  83. </project>

eureka-zuul模型结构如下:

1. 首先是EurekaZuulApplication.java内容如下:

  1. package com.xum.eurekazuul;
  2.  
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
  6. import org.springframework.cloud.netflix.turbine.EnableTurbine;
  7. import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
  8.  
  9. @SpringBootApplication
  10. @EnableZuulProxy // 这里是启用zuul路由的注解
  11. @EnableHystrixDashboard
  12. @EnableTurbine
  13. public class EurekaZuulApplication {
  14.  
  15. public static void main(String[] args) {
  16. SpringApplication.run(EurekaZuulApplication.class, args);
  17. }
  18.  
  19. }

2. application.yml内容如下:

  1. eureka:
  2. client:
  3. serviceUrl:
  4. defaultZone: http://localhost:8761/eureka/
  5. server:
  6. port: 8773
  7. zuul: // 这里定义了两个api接口的路由, 一个指向ribbon-consumer, 一个指向fegin-client
  8. routes:
  9. api-a:
  10. path: /api-a/**
  11. serviceId: ribbon-consumer
  12. api-b:
  13. path: /api-b/**
  14. serviceId: fegin-client
  15. turbine:
  16. aggregator:
  17. cluster-config: default
  18. app-config: '*'
  19. cluster-name-expression: new String("default")
  20. spring:
  21. application:
  22. name: eureka-zuul
  23. management:
  24. endpoint:
  25. health:
  26. show-details: always
  27. endpoints:
  28. web:
  29. exposure:
  30. include: '*'

3. 然后是PermissionsFilter.java内容如下:

  1. package com.xum.eurekazuul.filter;
  2.  
  3. import com.netflix.zuul.ZuulFilter;
  4. import com.netflix.zuul.context.RequestContext;
  5. import com.netflix.zuul.exception.ZuulException;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.stereotype.Component;
  9.  
  10. import javax.servlet.http.HttpServletRequest;
  11.  
  12. import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
  13.  
  14. @Component
  15. public class PermissionsFilter extends ZuulFilter {
  16.  
  17. private static final Logger LOG = LoggerFactory.getLogger(PermissionsFilter.class);
  18.  
  19. @Override
  20. public String filterType() {
  21. return PRE_TYPE;
  22. }
  23.  
  24. @Override
  25. public int filterOrder() {
  26. return 0;
  27. }
  28.  
  29. @Override
  30. public boolean shouldFilter() {
  31. return true;
  32. /*RequestContext ctx = RequestContext.getCurrentContext();
  33. return (boolean) ctx.get("isSuccess");*/
  34. }
  35.  
  36. @Override
  37. public Object run() throws ZuulException {
  38. RequestContext ctx = RequestContext.getCurrentContext();
  39. HttpServletRequest request = ctx.getRequest();
  40.  
  41. LOG.info(String.format("%s AccessNameFilter request to %s", request.getMethod(), request.getRequestURL().toString()));
  42. String name = request.getParameter("name");// 获取请求的参数
  43. if(null != name && "xum".equalsIgnoreCase(name)) { // 在向eureka-client项目里调用api的时候,检查带的name内容是否是xum
  44. ctx.setSendZuulResponse(true);
  45. ctx.setResponseStatusCode(200);
  46. ctx.set("isSuccess", true);
  47. return null;
  48. }else{
  49. ctx.setSendZuulResponse(false);
  50. ctx.setResponseStatusCode(401);
  51. ctx.setResponseBody("{\"result\":\"name is not correct!\"}");
  52. ctx.set("isSuccess", false);
  53. return null;
  54. }
  55. }
  56. }

4. 其次就是ApiFallbackProvider.java内容如下:

  1. package com.xum.eurekazuul.provider;
  2.  
  3. import com.netflix.hystrix.exception.HystrixTimeoutException;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
  7. import org.springframework.http.HttpHeaders;
  8. import org.springframework.http.HttpStatus;
  9. import org.springframework.http.MediaType;
  10. import org.springframework.http.client.ClientHttpResponse;
  11. import org.springframework.stereotype.Component;
  12.  
  13. import java.io.ByteArrayInputStream;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16.  
  17. @Component
  18. public class ApiFallbackProvider implements FallbackProvider {
  19.  
  20. private static final Logger LOG = LoggerFactory.getLogger(ApiFallbackProvider.class);
  21.  
  22. @Override
  23. public String getRoute() {
  24. LOG.info("ApiFallbackProvider=>getRoute");
  25. return "*";
  26. }
  27.  
  28. @Override
  29. public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
  30. LOG.info(String.format("route:%s,exceptionType:%s,stackTrace:%s", route, cause.getClass().getName(), cause.getStackTrace()));
  31. String message = "";
  32. if (cause instanceof HystrixTimeoutException) {
  33. message = "Timeout";
  34. } else {
  35. message = "Service exception";
  36. }
  37. return fallbackResponse(message);
  38. }
  39.  
  40. public ClientHttpResponse fallbackResponse(String message) {
  41.  
  42. return new ClientHttpResponse() {
  43. @Override
  44. public HttpStatus getStatusCode() throws IOException {
  45. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusCode");
  46. return HttpStatus.OK;
  47. }
  48.  
  49. @Override
  50. public int getRawStatusCode() throws IOException {
  51. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getRawStatusCode");
  52. return 200;
  53. }
  54.  
  55. @Override
  56. public String getStatusText() throws IOException {
  57. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusText");
  58. return "OK";
  59. }
  60.  
  61. @Override
  62. public void close() {
  63. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>close");
  64. }
  65.  
  66. @Override
  67. public InputStream getBody() throws IOException {
  68. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getBody");
  69. String bodyText = String.format("{\"code\": 999,\"message\": \"Service unavailable:%s\"}", message);
  70. return new ByteArrayInputStream(bodyText.getBytes());
  71. }
  72.  
  73. @Override
  74. public HttpHeaders getHeaders() {
  75. LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getHeaders");
  76. HttpHeaders headers = new HttpHeaders();
  77. headers.setContentType(MediaType.APPLICATION_JSON);
  78. return headers;
  79. }
  80. };
  81. }
  82. }

顺序启动一下项目:

1. eureka-server

2. config-server

3. eureka-client

4. fegin-client

5. ribbon-consumer

6. zuul-client

然后再浏览器或则post man中输入http://localhost:8773/api-a/ribbonconsumer/test?name=xum, 显示内容如下:

在eureka-zuul项目里Event log打印出如下类似的log:

  1. 2019-03-31 14:52:51.881 INFO 1976 --- [nio-8773-exec-9] c.x.eurekazuul.filter.PermissionsFilter : POST AccessNameFilter request to http://localhost:8773/api-a/ribbonconsumer/test

当输入http://localhost:8773/api-a/ribbonconsumer/test, 不带任何参数的时候, 显示内容如下, 路由网关提示name不正确.

然后再post man中输入http://localhost:8773/api-b/feign/feignconsumer?name=xum, 内容如下:

也能在eureka-client项目的Event log里看到如下类似的log:

  1. 2019-03-31 14:58:27.395 INFO 1976 --- [nio-8773-exec-5] c.x.eurekazuul.filter.PermissionsFilter : POST AccessNameFilter request to http://localhost:8773/api-b/feign/feignconsumer

相同的道理, 如果参数没有name或则name只不对, 路由网关都会提示出错.

当eureka-client项目没有启动的时候, Hyrtrix会进行相应自我保护.

SpringCloud的学习记录(7)的更多相关文章

  1. SpringCloud的学习记录(1)

    最近一段时间重新学习一边SpringCloud(有半年不用了),这里简单记录一下. 我用的是IntelliJ IDEA开发工具, SpringBoot的版本是2.1.3.RELEASE. 1. 构建M ...

  2. SPRINGCLOUD 开发学习记录

    一个简单的微服务系统:服务注册和发现,服务消费,负载均衡,断路器,智能路由,配置管理 服务注册中心: eureka是一个高可用组件,没有后端缓存,每一个实例注册后向注册中心发送心跳,默认情况下,eru ...

  3. SpringCloud的学习记录(8)

    这一章节讲zipkin-server. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等 ...

  4. SpringCloud的学习记录(6)

    这一章节讲fegin的使用. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等信息, 这 ...

  5. SpringCloud的学习记录(5)

    这一章节讲如何使用ribbon和hystrix. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Arti ...

  6. SpringCloud的学习记录(3)

    这一章节讲搭建config-server的项目. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Arti ...

  7. SpringCloud的学习记录(2)

    这一章节主要讲如何搭建eureka-client项目. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和A ...

  8. SpringCloud的学习记录(4)

    本篇基于上一篇写的, 在git上更改配置后, eureka-client如何更新. 我们只需要在配置文件中配置 spring-cloud-starter-bus-amqp; 这就是说我们需要装rabb ...

  9. SpringCloud基础教程学习记录

    这个学习记录是学习自翟永超前辈的SpringCloud的基础教程. 自己写这个教程的目的主要是在于,想要更凝练总结一些其中的一些实用点,顺便做个汇总,这样自己在复习查看的时候更加方便,也能顺着自己的思 ...

随机推荐

  1. matplotlib类

    1.plt.subplot 在matplotlib下,一个Figure对象可以包含多个子图(Axes),可以使用subplot()快速绘制,其调用形式如下:subplot(numRows, numCo ...

  2. [LOJ2027] [SHOI2016] 黑暗前的幻想乡

    题目链接 LOJ:https://loj.ac/problem/2027 洛谷:https://www.luogu.org/problemnew/show/P4336 Solution 这题很像[ZJ ...

  3. django内置服务器

    单进程多线程的 多线程用来并发,各个线程之间不会阻塞,每个线程对应一个连接

  4. spring boot中 启用aspectj

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  5. C#工具类之字典扩展类

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  6. IP 地址分类

    1.1 网络IP地址分类 网络通讯过程中数据封装与解封过程(网际互联通讯过程) TCP/IP模型 1)应用层 总结记录一些常见网络协议以及对应的端口号(FTP HTTP telnet) 2)主机到主机 ...

  7. Photoshop入门教程(三):图层

    学习心得:图层可以说是Photoshop的核心,看似简单,但是对于图像的各种编辑都是基于图层.他就像一层透明的.没有厚度的玻璃纸,每张玻璃纸设置不同的效果,层层叠加,最后显现出绚烂的效果. 在进行图像 ...

  8. Filter责任链模式

    Filter责任链的创建 org.apache.catalina.core.ApplicationFilterFactory#createFilterChain,  此方法是被org.apache.c ...

  9. django-filter version 2.0 改动

    今天使用django-filter时候遇到了下面这个问题: django-filter: TypeError at /goods/ init() got an unexpected keyword a ...

  10. js字符串与数字之间的比较

    //1.纯数字之间比较 console.log(1<3);//true //2.纯字符串比较,先转成ASCII码,按位依次比较 console.log("1"<&quo ...