SpringCloudZuul服务网关

spring-boot版本:2.0.4.RELEASE,spring-cloud版本:Finchley.RELEASE,java版本:1.8

一、快速启动一个zuul

1.新建一个父项目,依赖如下

<?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>

    <groupId>com.taikang.bd</groupId>
    <artifactId>spring-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging><!--声明pom为父-->

    <!--子项目-->
    <modules>
        <module>eureka-8761</module>
        <module>zuul-8800</module>
        <module>myservice-9001</module>
    </modules>


    <!--项目名和描述-->
    <name>SpringCloud</name>
    <description>This  is  a  Spring  project</description>

    <!--父依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--属性-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--spring boot web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--spring boot 启动依赖,集成好多依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--spring boot 测试依赖-->
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>


    </dependencies>

    <!--spring cloud 管理-->
    <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>


</project>

创建子项目eureka-server,引入依赖

        <!--eureka-server的核心依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!--其他基本依赖,父项目有了已经-->

配置文件:

spring:
  application:
    name: eureka-server
server:
  port: 8761
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    register-with-eureka: false #不注册自己
    fetch-registry: false

然后主启动类

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

2.然后写一个简单的微服务,作为eureka的客户端注册到eureka

新建子项目my-service,引入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

配置文件

server:
  port: 9001
spring:
  application:
    name: my-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

新建一个controller


@RestController
public class HelloController {
    @Value("${server.port}")
    private String port;
    @GetMapping("/hi")
    public String hello(){
        return "hello,The port is :"+port;
    }
}

主启动类

@SpringBootApplication
@EnableDiscoveryClient //注册到eureka
public class MyService {
    public static void main(String[] args) {
        SpringApplication.run(MyService.class,args);
    }
}

3.接下来新建子项目zuul-server,引入依赖

        <!--zuul的核心依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!--安全验证的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

 zuul的配置文件,如下设置的安全密码在访问路由的时候需要验证

spring:
  application:
    name: zuul-server
  security:  #设置安全密码
    user:
      name: root
      password: root
server:
  port: 8800
eureka:  #只有注册到了eureka才可以发现服务,才可以访问
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

zuul的启动类:

@SpringBootApplication
@EnableZuulProxy //开启网关服务功能,默认注册到eureka
public class ZuulServer {
    public static void main(String[] args) {
        SpringApplication.run(ZuulServer.class,args);
    }
}

zuul的配置文件暂时还没有设置路由,浏览器输入localhost:8800/my-service/hi   即可访问到。

在这里我的服务名是my-service,我的请求路径是/hi。

3.1配置下路由信息:

spring:
  application:
    name: zuul-server
  security:  #设置安全密码
    user:
      name: root
      password: root
server:
  port: 8800
eureka:  #只有注册到了eureka才可以发现服务,才可以访问
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
zuul:
  routes:
    route-1: #路由名,保证唯一即可
      path: /163
      #sensitiveHeaders: Cookie,Set-Cookie,Authorization #不传递请求头的一些信息
      url: http://www.163.com #也可以写 forward:转发,后面跟上url
    route-2:
      path: /app/**  #表示这个服务下的所有接口都可以访问
      serviceId: my-service  #你注册到eureka的服务名,如果这你指定的是url,那他就没有ribbon和hystrix了
    legacy: #其他服务这样访问
      path: /**
  prefix: /qz #配置一个前缀,访问路由都得带上这个
  ignore-security-headers: false #禁用安全,不会过滤一些请求头
#  ignored-services: my-service #不想代理的服务名
#================================
#如果禁用了ribbon,如何做负载均衡
#zuul:
#  routes:
#    route-1:
#     path: /163
#     serviceId: my-service
#ribbon:
#   eureka:
#      enabled: false
#my-service:
#   ribbon:
#      listOfServers: baidu.com,google.com
spring:
  application:
    name: zuul-server
  security:  #设置安全密码
    user:
      name: root
      password: root
server:
  port: 8800
eureka:  #只有注册到了eureka才可以发现服务,才可以访问
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
zuul:
  routes:
    route-1: #路由名,保证唯一即可
      path: /163
      #sensitiveHeaders: Cookie,Set-Cookie,Authorization #不传递请求头的一些信息
      url: http://www.163.com #也可以写 forward:转发,后面跟上url
    route-2:
      path: /app/**  #表示这个服务下的所有接口都可以访问
      serviceId: my-service  #你注册到eureka的服务名,如果这你指定的是url,那他就没有ribbon和hystrix了
#    legacy: #其他服务这样访问
#      path: /**
#  prefix: /qz #配置一个前缀,访问路由都得带上这个
#  ignore-security-headers: false #禁用安全,不会过滤一些请求头
#  ignored-services: my-service #不想代理的服务名
#================================
#如果禁用了ribbon,如何做负载均衡
#zuul:
#  routes:
#    route-1:
#     path: /163
#     serviceId: my-service
#ribbon:
#   eureka:
#      enabled: false
#my-service:
#   ribbon:
#      listOfServers: baidu.com,google.com

4.zuul的fallback功能

只需实现一个接口即可

@Component
public class MyZuulFacllBack implements FallbackProvider {

    @Override
    public String getRoute() {
        return "my-service";//服务id,如果需要所有服务支持回退就return "*"或return null
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "OK";
            }

            @Override
            public void close() {
            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("The service is unavailable.".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }

        };
    }


}

如果一个服务网挂掉了,他将返回the service is unavailable。

5.zuul的过滤器

临时先写个简单的,明天做jwt鉴权

package com.taikang.bd.Filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

public class MyZuulFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(MyZuulFilter.class);

    @Override
    public String filterType() {
        return "pre";//4种,pre 在之前执行  post   error  routing
    }

    @Override
    public int filterOrder() {
        return 0;//数字越小,优先级越高
    }

    @Override
    public boolean shouldFilter() {
        return true;//true 表示执行这个过滤器,false表示不执行
    }

    @Override
    public Object run() throws ZuulException {//执行过滤的逻辑
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");// 获取请求的参数
        logger.info("---------------------token is --------------------"+ token);
        if (StringUtils.isNotBlank(token)) {
            ctx.setSendZuulResponse(true); //对请求进行路由
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess", true);
            return null;
        } else {
            ctx.setSendZuulResponse(false); //不对其进行路由
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("token is empty");
            ctx.set("isSuccess", false);
            return null;
        }
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值