SpringCloud的学习记录(7)
这一章节讲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)的更多相关文章
- SpringCloud的学习记录(1)
最近一段时间重新学习一边SpringCloud(有半年不用了),这里简单记录一下. 我用的是IntelliJ IDEA开发工具, SpringBoot的版本是2.1.3.RELEASE. 1. 构建M ...
- SPRINGCLOUD 开发学习记录
一个简单的微服务系统:服务注册和发现,服务消费,负载均衡,断路器,智能路由,配置管理 服务注册中心: eureka是一个高可用组件,没有后端缓存,每一个实例注册后向注册中心发送心跳,默认情况下,eru ...
- SpringCloud的学习记录(8)
这一章节讲zipkin-server. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等 ...
- SpringCloud的学习记录(6)
这一章节讲fegin的使用. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等信息, 这 ...
- SpringCloud的学习记录(5)
这一章节讲如何使用ribbon和hystrix. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Arti ...
- SpringCloud的学习记录(3)
这一章节讲搭建config-server的项目. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Arti ...
- SpringCloud的学习记录(2)
这一章节主要讲如何搭建eureka-client项目. 在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和A ...
- SpringCloud的学习记录(4)
本篇基于上一篇写的, 在git上更改配置后, eureka-client如何更新. 我们只需要在配置文件中配置 spring-cloud-starter-bus-amqp; 这就是说我们需要装rabb ...
- SpringCloud基础教程学习记录
这个学习记录是学习自翟永超前辈的SpringCloud的基础教程. 自己写这个教程的目的主要是在于,想要更凝练总结一些其中的一些实用点,顺便做个汇总,这样自己在复习查看的时候更加方便,也能顺着自己的思 ...
随机推荐
- linux中tomcat内存溢出
刚开始测试服务器与线上后台都不能上传10分钟以上的视频,后来只要是视频就不能上传,进入服务器查日志得到如下错误: Caused by: java.lang.OutOfMemoryError: Java ...
- Exadata LVM snapshot备份失败
一台X4-2 的计算节点进行image升级,在正式升级之前利用LVM snapshot备份操作系统时备份失败,并且报大量IO错误,提示无法找到LVM snapshot的挂载点.检查文件系统状态: [r ...
- 分页插件PageHelper
一.PageHelper说明 如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件. 该插件目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,Po ...
- 一个基于QT简单登录对话框(带验证码功能)
1. 对话框样式 2. 源代码 ①. main.cpp #include <QtGui/QApplication> #include "QLoginDialog.h" ...
- Socket 代码收藏
class SocketHelper { public delegate void Uplistbox(string txt); public Uplistbox u ...
- 利用Content-disposition实现无刷新下载图片文件
今天在使用 tinypng.com 这个在线压缩图片的网站时,对其处理完图片后,可以无刷新下载图片感到好奇,于是了解了一下相关实现.无刷新下载可以利用MIME type或者设置Content-disp ...
- SQL server数据库端口访问法
最近数据库连接,也是无意中发现了这个问题,数据库可根据端口来连接 我用的是sql2014测试的,在安装其他程序是默认安装了sql(sql的tcp/ip端口为xxx),服务也不相同,但是由于比较不全,我 ...
- thinkPHP5.0验证器自定义验证规则
自定义验证规则 protected $rule = [ 'views' => 'require|number|checkviews:0',//checkviews为自定义验证规则,0是传过去的规 ...
- java——int、args[]传参、标签、数字塔?、一个输入格式
1.当int型整数超出自己范围时,会从它的上界重新开始. public class exp { public static void main(String[] args) { int i = 214 ...
- 转 Python3 错误和异常/ Python学习之错误调试和测试
########sample 0 https://www.cnblogs.com/Simon-xm/p/4073028.html except: #捕获所有异常 except: <异常名> ...