spring clude ---服务网关组件Netflix Zuul

介绍:服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。
Zuul是Netflix开源的微服务网关,他可以和Eureka,Ribbon,Hystrix等组件配合使用。Zuul组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:
#身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求
#审查与监控:
#动态路由:动态将请求路由到不同后端集群
#压力测试:逐渐增加指向集群的流量,以了解性能
#负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
#静态响应处理:边缘位置进行响应,避免转发到内部集群

搭建一个Zuul服务网关


1.新建模块ZuulGateWay,增加所需依赖包
 <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>

注意,eureka-client导包,是:spring-cloud-starter-netflix-eureka-client
不是:spring-cloud-netflix-eureka-client


2.在程序启动类增加注解@EnableZuulProxy开启Zuul

@SpringCloudApplication注解,通过源码我们看到,它整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker,主要目的还是简化配置。

package com.offcn;

import com.offcn.filter.AccessFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringCloudApplication //组合注解
@EnableZuulProxy
public class ZuulGatwayStarter {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(ZuulGatwayStarter.class,args);
    }

    //初始化过滤器为bean
    @Bean
    public AccessFilter createAccessFilter(){
    
    
        return new AccessFilter();
    }
}


3.修改application.yml属性配置文件
spring:
  application:
    name: ZUULGATEWAY
server:
  port: 80

完成上面的工作后,Zuul已经可以运行了,但是如何让它为我们的微服务集群服务,还需要我们另行配置,下面详细的介绍一些常用配置内容。



Zuul服务网关路由配置


方式一:通过url直接映射

1.修改项目ZuulGateWay的属性配置文件application.yml
zuul:
  routes:
    userprovider001:
      path: /userprovider001/**
      url: http://localhost:9003/
    userprovider002:
      path: /userprovider002/**
      url: http://localhost:9004/  

该配置,定义了,所有到Zuul中的规则为:/userprovider001/**的访问都映射到http://localhost:9003/上,也就是说当我们访问http://localhost/userprovider001/的时候,Zuul会将该请求路由到:http://localhost:9003/上
注意:配置属性zuul.routes.userprovider001.path中的userprovider001部分为路由的名字,可以任意定义,但是一组映射关系的path和url要相同

2测试url直接映射方式

(测试该服务的某个接口功能)
http://localhost/userprovider001/user/getAll

方式二:通过在Eureka服务注册的serviceId进行映射

通过url映射的方式对于Zuul来说,并不是特别友好,Zuul需要知道我们所有微服务的地址,才能完成所有的映射配置。而实际上,我们在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,我们就可以实现对serviceId的映射。

1.修改服务网关ZuulGateWay的属性配置文件application.yml
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
zuul:
  routes:
    userprovider:
      path: /service/**   #自定义访问规则
      service-id: USERPROVIDER  #注册的提供服务名,就不需要再配置服务地址了
2.测试ServiceId映射方式

http://localhost/service/user/getAll

3.修改客户端调用Zuul网关地址

使用Fegin方式实现接口的
1.修改注解FeignClient
@FeignClient(value = “ZUULGATEWAY”,configuration = feignConfig.class,fallback = UserServiceImpl.class)
2.调用方法按照Zuul定义的规则修改即可
例:
@GetMapping("/service/user/getAll")
public List getAll(…);



Zuul服务网关过滤器使用

在服务网关中定义过滤器只需要继承ZuulFilter抽象类实现其定义的四个抽象函数就可对请求进行拦截与过滤。

比如下面的例子,定义了一个Zuul过滤器,实现了在请求被路由之前检查请求中是否有accessToken参数,若有就进行路由,若没有就拒绝访问,返回401 Unauthorized错误。

1.编写Zuul过滤器(在模块ZuulGateWay下)

在这里插入图片描述

package com.offcn.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

import javax.servlet.http.HttpServletRequest;

public class AccessFilter extends ZuulFilter {
    
    
   //设置过滤器的类型,决定了过滤器的执行时间
   @Override
   public String filterType() {
    
    
       //常见过滤器类型pre 路由请求转发之前执行  routing 在路由转发同时执行  post 在routing和error过滤器之后被调用  error:处理请求时发生错误时被调用
       return "pre";
   }

   @Override
   public int filterOrder() {
    
    
       return 0;  //过滤器的执行顺序,数字越小越先执行
   }

   //开关
   @Override
   public boolean shouldFilter() {
    
    
       return true;  //true 表示丐萝氯气处于可运行状态  false表示该过滤器不可用
   }

   //该过滤器做身份验证
   @Override
   public Object run() throws ZuulException {
    
    
       //获取到当前请求上下文环境
       RequestContext context = RequestContext.getCurrentContext();
       //从上下文环境获取当前请求对象
       HttpServletRequest request = context.getRequest();
       //从请求对象获取传递的凭证
       String token = request.getParameter("token");
       //判断凭证是否存在
       if(token==null){
    
    
           //凭证不存在,禁止路由转发
           context.setSendZuulResponse(false);
           //提示错误状态码   401 权限不足的意思
           context.setResponseStatusCode(401);
       }
       return null;
   }
}
2.实例化该过滤器

在这里插入图片描述

我们只需要在启动类中增加如下内容:

	@Bean
	public AccessFilter accessFilter() {
    
    
		return new AccessFilter();
	}
3.测试过滤器

http://localhost/service/user/getAll
发现:
在这里插入图片描述
因为没有传token的值,所以被过滤器拦截了
我们再测试:
http://localhost/service/user/getAll?token=token
可以发现能正常访问该接口了

猜你喜欢

转载自blog.csdn.net/JavaSupeMan/article/details/105802514