前言
本章相对于之前的学习,我们第一是要转变一个思想概念。
概念
本章的代码内容并不多,可重要要学习的就只有一个:思想的转变!!!
为什么说是思想的转变呢?
之前:消费者A对于服务者B而言,消费者A确实是消费者A,因为是相对而言,消费者A在服务者那里进行了一个服务的消费,所以消费者A才被称之为消费者。消费者A其实也可以是一个服务者A,因为对于C来说:消费者C也可以在服务者A中进行一个服务的消费。
现在:其实所有的A,B,C相对于zuul网关而言都是一个个拥有自己功能的微服务项目。在现在所有的客户端可以通过网关来发送请求,而那个请求(ip+端口)
还要加上我们微服务的名字(比如之前的microservice-student)才能指定要访问的微服务,当然还是要通过服务注册中心来获取每一个在注册中心注册过的微服务地址。
小结:之前的案例讲解中的消费者和服务者实际上都是一个个微服务,都能进行自己模块的功能提供。每一个微服务之间的资源调用都是像我们之前的案例一样进行,而如今是zuul网关去调用每一个微服务的资源。
如果不能理解,也就是这样
zuul的简单部署
增加一个zuul项目: microservice-zuul-3001
pom.xml增加了:
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
全部的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--保持使用版本的一致1.0-SNAPSHOT-->
<parent>
<groupId>com.liwangwang</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>microservice-zuul-3001</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--相当于全局的一个依赖关系,这个导入能确保整个项目使用的包版本一致
比如全局中的: spring-cloud-dependencies
spring-boot-dependencies
druid-spring-boot-starter
-->
<dependency>
<groupId>com.liwangwang</groupId>
<artifactId>microservice-common</artifactId>
</dependency>
<!--处理web请求-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--test测试的包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- actuator监控引入,点击后的追责 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--添加注册中心Eureka相关配置,就是说这个是客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--Hystrix相关依赖,用来处理服务处理异常情况-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<!-- Hystrix,Feign是基于Hystrix的 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml文件的配置
server:
port: 3001
context-path: /
spring:
application:
name: microservice-zuul
eureka:
instance:
instance-id: microservice-zuul:3001 #客户端实例名称
prefer-ip-address: true #是否显示IP
client:
service-url:
#设置与Eureka注册中心交互的地址,是所有注册中心
defaultZone: http://eureka2001.javawwl.com:2001/eureka/,http://eureka2002.javawwl.com:2002/eureka/,http://eureka2003.javawwl.com:2003/eureka/ #把服务注册到eureka注册中心
info:
groupId: com.liwangwang.springcloud
artifactId: microservice-zuul-3001
version: 1.0-SNAPSHOT
userName: http://www.javawwl.com
phone: 123456
启动类:
ok,可以直接输入:
http://zuul.javawwl.com:3001/microservice-student/student/hystrix
记得要修改host
提高zuul安全措施
1、隐藏真实请求路径
在yml文件中加上:
zuul:
routes: # 所有的路由都要配置在这里
studentServer.serviceId: microservice-student
studentServer.path: /studentServer/**
ignored-services: "*"
prefix: /javawwl
这样就行了
那么我的一个请求就变成了:http://zuul.javawwl.com:3001/javawwl/studentServer/student/hystrix
2、定义过滤规则
AccessFilter
package com.liwangwang.microservicezuul3001.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
/**
* @author 李旺旺
* @site www.javawwl.com
* @company
* @create 2019-04-30 16:05
*/
public class AccessFilter extends ZuulFilter {
Logger logger=Logger.getLogger(AccessFilter.class);
/**
* 判断该过滤器是否要被执行
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体执行逻辑
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String parameter = request.getParameter("accessToken");
logger.info(request.getRequestURL().toString()+" 请求访问");
if(parameter==null){
logger.error("accessToken为空!");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("{\"result\":\"accessToken is empty!\"}");
return null;
}
// token判断逻辑
logger.info(request.getRequestURL().toString()+" 请求成功");
return null;
}
/**
* 过滤器的类型 这里用pre,代表会再请求被路由之前执行
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤器的执行顺序
*/
@Override
public int filterOrder() {
return 0;
}
}
ZuulConfig
package com.liwangwang.microservicezuul3001.config;
import com.liwangwang.microservicezuul3001.filter.AccessFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ZuulConfig {
@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
}
那么请求路径就为
http://zuul.javawwl.com:3001/javawwl/studentServer/student/hystrix?accessToken=1
有的时候
没有的时候
zuul的服务断路处理
这个有两种方法:
Zuul作为服务网关为了保证自己不被服务拖垮,本身已经集成了Hystrix对路由转发进行隔离。 为了方便开发人员对服务短路进行自定义处理,
ZuulFallbackProvider :Zuul 提供了 ZuulFallbackProvider 接口,开发人员可以通过实现该接口来完成自定义Hystrix Fallback
FallbackProvider :Spring Cloud Zuul 提供了 FallbackProvider替代了ZuulFallbackProvider接口。
但是本次本次只使用ZuulFallbackProvider接口来演示
package com.liwangwang.microservicezuul3001.fallback;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
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;
/**
* @authorliwangwang
* @site www.liwangwang.com
* @company xxx公司
* @create 2019-11-26 14:18
*/
@Component
public class ZuulFallBack implements ZuulFallbackProvider {
@Override
public String getRoute() {
return "*";
}
/**
* 在给zuul整合回退功能时,只要类实现ZuulFallbackProvider接口,并且注册bean即可。
*
* 不过需要注意的时,这个回退只有服务掉线或者超时的情况下才会触发(Camden.SR4版本测试是这样),
* 如果服务程序出现异常,此回退程序是不能处理的,异常会直接返回给调用者,比如页面。
*
* @return
*/
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//application/json;charset=UTF-8
return headers;
}
@Override
public InputStream getBody() throws IOException {
String msg = "服务繁忙,请稍后";
//new ByteArrayInputStream("{\"code\":-1,\"msg\":\"服务暂不可用\"}".getBytes(StandardCharsets.UTF_8))
return new ByteArrayInputStream(msg.getBytes());
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.BAD_REQUEST.getReasonPhrase();//400
}
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.BAD_REQUEST;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.BAD_REQUEST.value();//"Bad Request"
}
@Override
public void close() {
}
};
}
}
方法名 | 说明 |
---|---|
getRoute() | 该Provider应用的Route ID,例如:testservice,如果设置为 * ,那就对所有路由生效 |
fallbackResponse() | 快速回退失败/响应,即处理异常并返回对应输出/响应内容。 |
后记
整理整理:
本章的代码内容并不多,可重要要学习的就只有一个:思想的转变!!!
为什么说是思想的转变呢?
之前:消费者A对于服务者B而言,消费者A确实是消费者A,因为是相对而言,消费者A在服务者那里进行了一个服务的消费,所以消费者A才被称之为消费者。消费者A其实也可以是一个服务者A,因为对于C来说:消费者C也可以在服务者A中进行一个服务的消费。
现在:其实所有的A,B,C相对于zuul网关而言都是一个个拥有自己功能的微服务项目。在现在所有的客户端可以通过网关来发送请求,而那个请求(ip+端口)
还要加上我们微服务的名字(比如之前的microservice-student)才能指定要访问的微服务,当然还是要通过服务注册中心来获取每一个在注册中心注册过的微服务地址。
小结:之前的案例讲解中的消费者和服务者实际上都是一个个微服务,都能进行自己模块的功能提供。每一个微服务之间的资源调用都是像我们之前的案例一样进行,而如今是zuul网关去调用每一个微服务的资源。
一、 zuul简单配置
1、 导入pom.xml
2、 配置yml文件
3、 为启动类加上注解:@EnableZuulProxy
二、 zuul网关安全措施
1、 改变路由真实路径
2、 加上过滤条件认证
① 写好一个AccessFilter extends(实现)ZuulFilter接口
② 实现过滤类的Bean注入(config)
三、 zuul的服务断路处理
Zuul作为服务网关为了保证自己不被服务拖垮,本身已经集成了Hystrix对路由转发进行隔离。 为了方便开发人员对服务短路进行自定义处理,
ZuulFallbackProvider :Zuul 提供了 ZuulFallbackProvider 接口,开发人员可以通过实现该接口来完成自定义Hystrix Fallback
FallbackProvider :Spring Cloud Zuul 提供了 FallbackProvider替代了ZuulFallbackProvider接口。
在pom依赖中导入依赖
写好一个回调类继承上面的两个接口之一就行
φ(* ̄0 ̄)这样就差不多了