这一章节讲zuul的使用.

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

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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xum</groupId>
<artifactId>eureka-zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-zuul</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> <repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories> </project>

eureka-zuul模型结构如下:

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

package com.xum.eurekazuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication
@EnableZuulProxy // 这里是启用zuul路由的注解
@EnableHystrixDashboard
@EnableTurbine
public class EurekaZuulApplication { public static void main(String[] args) {
SpringApplication.run(EurekaZuulApplication.class, args);
} }

2. application.yml内容如下:

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8773
zuul: // 这里定义了两个api接口的路由, 一个指向ribbon-consumer, 一个指向fegin-client
routes:
api-a:
path: /api-a/**
serviceId: ribbon-consumer
api-b:
path: /api-b/**
serviceId: fegin-client
turbine:
aggregator:
cluster-config: default
app-config: '*'
cluster-name-expression: new String("default")
spring:
application:
name: eureka-zuul
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: '*'

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

package com.xum.eurekazuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; @Component
public class PermissionsFilter extends ZuulFilter { private static final Logger LOG = LoggerFactory.getLogger(PermissionsFilter.class); @Override
public String filterType() {
return PRE_TYPE;
} @Override
public int filterOrder() {
return 0;
} @Override
public boolean shouldFilter() {
return true;
/*RequestContext ctx = RequestContext.getCurrentContext();
return (boolean) ctx.get("isSuccess");*/
} @Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest(); LOG.info(String.format("%s AccessNameFilter request to %s", request.getMethod(), request.getRequestURL().toString()));
String name = request.getParameter("name");// 获取请求的参数
if(null != name && "xum".equalsIgnoreCase(name)) { // 在向eureka-client项目里调用api的时候,检查带的name内容是否是xum
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
return null;
}else{
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("{\"result\":\"name is not correct!\"}");
ctx.set("isSuccess", false);
return null;
}
}
}

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

package com.xum.eurekazuul.provider;

import com.netflix.hystrix.exception.HystrixTimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; @Component
public class ApiFallbackProvider implements FallbackProvider { private static final Logger LOG = LoggerFactory.getLogger(ApiFallbackProvider.class); @Override
public String getRoute() {
LOG.info("ApiFallbackProvider=>getRoute");
return "*";
} @Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
LOG.info(String.format("route:%s,exceptionType:%s,stackTrace:%s", route, cause.getClass().getName(), cause.getStackTrace()));
String message = "";
if (cause instanceof HystrixTimeoutException) {
message = "Timeout";
} else {
message = "Service exception";
}
return fallbackResponse(message);
} public ClientHttpResponse fallbackResponse(String message) { return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusCode");
return HttpStatus.OK;
} @Override
public int getRawStatusCode() throws IOException {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getRawStatusCode");
return 200;
} @Override
public String getStatusText() throws IOException {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusText");
return "OK";
} @Override
public void close() {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>close");
} @Override
public InputStream getBody() throws IOException {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getBody");
String bodyText = String.format("{\"code\": 999,\"message\": \"Service unavailable:%s\"}", message);
return new ByteArrayInputStream(bodyText.getBytes());
} @Override
public HttpHeaders getHeaders() {
LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getHeaders");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}

顺序启动一下项目:

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:

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:

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. redhat7查看系统版本 修改主机名

    在CentOS或RHEL中,有三种定义的主机名:静态的(static),瞬态的(transient),以及灵活的(pretty).“静态”主机名也称为内核主机名,是系统在启动时从 /etc/hostn ...

  2. Step by Step: 基于MFC下的COM组件开发-Helloworld

    http://blog.csdn.net/sybifei/article/details/45008745 [这篇文章有问题, 仅供参考] http://blog.csdn.net/define_us ...

  3. (转)接口自动化测试之http请求实践总结

    一.接口测试的基本思路 1.确定要测试接口的请求类型.接口是get请求还是post请求. 2.确定接口的参数.需要传输的参数有哪些,类型分别是什么,都有哪些要求等. 3.按照参数要求构造请求需要的参数 ...

  4. react 中文文档案例一 (倒计时)

    1.函数试组件 import React from 'react'; import ReactDOM from 'react-dom'; function Clock(props){ return( ...

  5. google ---gson字符串数组用GSON解析然后用逗号隔开拼接,去掉最后一个逗号

    public static void main(String[] args) { String ss= "[{\"type\":\"0\",\&quo ...

  6. Mybatis学习笔记(五) —— Mapper.xml(输入映射和输出映射)

    一.parameterType(输入类型) 1.1 传递简单类型 <!-- 根据用户id查询用户 --> <select id="queryUserById" p ...

  7. ajax加载菊花loading效果

    Ajax异步请求的时候,一般都会利用一个动态的gif小图片来制作一个Ajax Loading,以便增加用户体验. 这里我们可以使用Spin.js,该js脚本压缩后5k,可以不用任何图片,任何外部CSS ...

  8. MERGE批量增删查改数据

    MERGE优点: 在批量处理数据的时候,我可以用到merge一次完成数据处理. 示例代码一: MERGE INTO student AS t using ( AS age) s ON t.Age=s. ...

  9. java——如何通过class调用该类的方法并获得返回值?(反射)

    demo: public class T{ public static void main(String[] args) throws Exception{ //获得Person的Class对象 Cl ...

  10. 自定义element-ui主题

    自定义element主题颜色:主要参考这个文章https://blog.csdn.net/wangcuiling_123/article/details/78513245,再自己做了一遍成功.感谢. ...