博客详情

springcloud(八)--路由网关zuul (原创)

作者: 朝如青丝暮成雪
发布时间:2018-08-19 19:04:39  文章分类:springcloud   阅读(929)  评论(0)

如题,本篇我们介绍下spring cloud中的路由组件zuul。


zuul是什么?

在微服务架构中,需要几个关键的组件,服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,zuul就是起到只能路由(过滤)功能的组件。

zuul具有以下的功能。 

Authentication  
Insights   
Stress Testing
Canary Testing
Dynamic Routing
Service Migration
Load Shedding
Security
Static Response handling
Active/Active traffic management


我们新建两个maven工程sim-serviceA 、 sim-serviceB ,再建立zuul网关工程sim-zuul 。

sim-serviceA 工程  :

application.yml 


server:
  port: 6001
  context-path: /
  
  
#devtool 热加载工具
spring:
  devtools:
    restart:
      enabled: true
      exclude: resources/**
#spring应用名称  、实例id配置
  application:
    name: sim-serviceA
    
eureka: 
  instance: 
    hostname: localhost  #eureka客户端主机实例名称
    prefer-ip-address: true
  client: 
    service-url: 
      defaultZone: http://localhost:8761/eureka  
         


pom.xml中引入


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
springboot 启动类



package com.tingcream.simServiceA;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class SimServiceAApp {
	public static void main(String[] args) {
        SpringApplication.run(SimServiceAApp.class, args);
    }
}
ServiceAController.java



package com.tingcream.simServiceA.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class ServiceAController {
	
	@Value("${spring.application.name}")
	private String applicationName;
	@Value("${server.port}")
	private String port ;

	@GetMapping("/")
	public String index(){
		 return "ServiceAController: 你好,我是"+applicationName+",服务端口:"+port;
	}
	
	@GetMapping("/hi")
	public String hi(String name){
		 return "ServiceAController: hi "+name+",我是"+applicationName+",服务端口:"+port;
	}
	
}


sim-serviceB 工程  :



application.yml 

server:
  port: 6002
  context-path: /
  
  
#devtool 热加载工具
spring:
  devtools:
    restart:
      enabled: true
      exclude: resources/**
#spring应用名称  、实例id配置
  application:
    name: sim-serviceB
    
eureka: 
  instance: 
    hostname: localhost  #eureka客户端主机实例名称
    prefer-ip-address: true
  client: 
    service-url: 
      defaultZone: http://localhost:8761/eureka  
         

pom.xml中引入

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
springboot 启动类



package com.tingcream.simServiceB;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 
@EnableEurekaClient
@SpringBootApplication
public class SimServiceBApp {
	
	public static void main(String[] args) {
        SpringApplication.run(SimServiceBApp.class, args);
    }
	
}
ServiceBController.java



package com.tingcream.simServiceB.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class ServiceBController {
	
	@Value("${spring.application.name}")
	private String applicationName;
	@Value("${server.port}")
	private String port ;

	@GetMapping("/")
	public String index(){
		 return "ServiceBController: 你好,我是"+applicationName+",服务端口:"+port;
	}

	@GetMapping("/hi")
	public String hi(String name){
		 return "ServiceBController: hi "+name+",我是"+applicationName+",服务端口:"+port;
	}

}
sim-zuul工程:


application.yml


server:
  port: 80
  context-path: /
  

spring: 
  application:
    name: sim-zuul
    
eureka: 
  instance: 
    hostname: localhost  #eureka客户端主机实例名称
    prefer-ip-address: true
  client: 
    service-url: 
      defaultZone: http://localhost:8761/eureka  
    
zuul:
  ignoredServices: sim-provider
  routes:
    serviceA: 
      path: /serviceA/**
      serviceId: sim-serviceA
    serviceB:
      path: /serviceB/**
      serviceId: sim-serviceB


pom.xml中引入


 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    


springboot启动类


package com.tingcream.simZuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
 

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class SimZuulApp {
  
	public static void main(String[] args) {
        SpringApplication.run(SimZuulApp.class, args);
    }
	
	
}

依次启动sim-eureka  、sim-zuul 、 sim-serviceA 、 sim-serviceB,访问http://localhost/8761


 


注: 由于使用到了zuul网关(提供外部用户访问的入口),我们将sim-zuul的端口设置为了80,将sim-consumer应用的端口修改为了6000

zuul有一些默认的路由配置规则,如果映射规则我们什么都不写,zuul也给我们提供了一套默认的配置规则,默认配置规则如下:
zuul.routes.serviceXXX.path=/serviceXXX/**
zuul.routes.serviceXXX.serviceId=serviceXXX


因此,即使我们没有配置 sim-consumer服务的路由规则,当我们请求 http://localhost/sim-consumer/student/list 也是可以访问成功的。还有点需要注意的是,zuul默认会给所有注册到eureka server上的应用配置默认的映射路由。而sim-provider是我们内部系统的一个微服务,是不能让外部用户直接访问,因而可以使用zuul.ignoredServices= xxx 来忽略掉特定服务的路由映射。如果使用zuul.ignoredServices= '*' 则表示忽略所有的微服务的路由映射,设置后我们需要再手动添加需要映射的服务。



------------------

zuul中的过滤器 ,例如自定义过滤器MyFilter,对所有请求进行拦截,判断是否有传token参数。 



package com.tingcream.simZuul;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

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

@Component 
public class MyFilter  extends ZuulFilter{
	 
	@Override
	public Object run() throws ZuulException {
		   RequestContext ctx = RequestContext.getCurrentContext();
	        HttpServletRequest request = ctx.getRequest();
	        System.out.println("请求方法:"+request.getMethod());
	        System.out.println("请求URL:"+request.getRequestURL().toString());
	        Object accessToken = request.getParameter("token");//获取param中 token, token不能为空
	        if(accessToken == null) {
	            ctx.setSendZuulResponse(false);
	            ctx.setResponseStatusCode(401);
	            try {
	                ctx.getResponse().getWriter().write("token is empty");
	            }catch (Exception e){
	            	e.printStackTrace();
	            }
	            return null;
	        }
	        System.out.println("token值为:"+accessToken);
	        System.out.println("zuul 中 MyFilter: 过滤器执行通过 ");
	        return null;
	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public int filterOrder() {
		return 0;
	}
	@Override
	public String filterType() {
		return "pre";
	}
    
}


filterType返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下: 
pre:路由之前
routing:路由之时
post: 路由之后
error:发送错误调用
filterOrder:过滤的顺序 
shouldFilter: 是否要过滤,true过滤,false不过滤
run:过滤器的具体逻辑。 

 

浏览器访问  http://localhost/serviceA/hi?name=小明&token=1212  ,http://localhost/serviceB/?token=1111 ,如果没加token参数则无法成功访问



关于zuul的更多配置信息,可以参见官网文档

http://cloud.spring.io/spring-cloud-static/Edgware.SR4/single/spring-cloud.html 

或者 http://projects.spring.io/spring-cloud/spring-cloud.html#_router_and_filter_zuul




关键字:  springcloud  路由  zuul
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号