您现在的位置是:首页 > 学无止境 > Spring Cloud

Spring cloud入门基础(7)路由网关zuul

贾继涛 2019-01-22 2279人围观

在微服务架构中,需要几个关键的组件,服务注册与发现、服务消费、负载均衡、断路器、

智能路由、配置管理等,由这几个组件可以组建一个简单的微服务架构。

下边来介绍路由网关zuul

1.首先看下我整理的项目目录结构如下

 png

2. 创建File->New->Directory创建文件夹hello-spring-cl-zuul目录结构类似如下

png


3.pom.xml其中依赖的父



<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>com.jjt.cloud</groupId>
        <artifactId>hello-spring-cl-den</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../hello-spring-cl-den/pom.xml</relativePath>
    </parent>
    <artifactId>hello-spring-cl-zuul</artifactId>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--eureka server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Zuul的主要功能是路由和过滤器。路由功能是微服务的一部分,
        比如/api/user映射到user服务,/api/shop映射到shop服务。
        zuul实现了负载均衡。以下是微服务结构中,
        Zuul的基本流程。在接下来的步骤中,我们来创建一个zuul服务
        将/api-feign/**映射到我们之前创建feign-service,
        将/api-ribbon/**映射到之前的ribbon-service服务。
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!--zipkin链路追踪-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.jjt.hello.hello.ServiceZuulApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


4.启动main方法



package com.jjt.hello.hello;
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;
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ServiceZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceZuulApplication.class,args);
    }
}


5.网关实现熔断机制 类



package com.jjt.hello.hello.provider;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
import java.util.HashMap;
import java.util.Map;
@Component
public class FeignFallBackProvider implements  FallbackProvider {
/*
* zuul集成了hystrix,也可以实现fallback,
  实现fallback时需要实现 FallbackProvider(springboot2.0)
* */
  @Override
    public String getRoute() {
      //return "hello-spring-cl-sumer-feign";
  //服务id,可以用* 或者 null 代表所有服务都过滤
      return null;
  }
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
/**
 * 网关向api服务请求是失败了,但是消费者客
   户端向网关发起的请求是OK的,
 * 不应该把api的404,500等问题抛给客户端
 * 网关和api服务集群对于客户端来说是黑盒子
   **/
 return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value();
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
Map<String ,Object> map=new HashMap<String , Object>();
map.put("status","200");
map.put("message","无法连接,请检测您的网络刷新重试!!");
ObjectMapper objectMapper=new ObjectMapper();
return new ByteArrayInputStream(
objectMapper.writeValueAsString(map).getBytes("utf-8")
);
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
//和body中的内容编码一致,否则容易乱码
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
};
}
}


6.网关过滤器ZuulFilter



package com.jjt.hello.hello.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class DemoFilter extends ZuulFilter {
    private static Logger log = LoggerFactory.getLogger(DemoFilter.class);
    /**
     * pre:路由之前
     routing:路由之时
     post: 路由之后
     error:发送错误调用
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }
    /**
     *
     * filterOrder:过滤的顺序
     pre:路由之前
     routing:路由之时
     post: 路由之后
     error:发送错误调用
     */
    @Override
    public int filterOrder() {
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String s ="-"+ String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString());
        log.info(s);
        return null;
    }
}


7.配置文件application


spring:
  application:
        name: hello-spring-cl-zuul
server:
    port: 8767
eureka:
    client:
        serviceUrl:
            defaultZone: http://127.0.0.1:8761/eureka/
#http://127.0.0.1:8767/api-ribbon/hello-consumer
#http://127.0.0.1:8767/api-feign/hello-consumer?msg=1111111111111111111111
zuul:
  routes:
    ribbo:
      path: /api-ribbon/**
      serviceId: hello-spring-cl-sumer
    feign:
      path: /api-feign/**
      serviceId: hello-spring-cl-sumer-feign


8.启动测试 访问

http://127.0.0.1:8767/api-ribbon/hello-consumer

http://127.0.0.1:8767/api-feign/hello-consumer?msg=1111111111111111111111

9.其中过滤器中可添加登录验证。熔断机制停止服务就会出现。

我的代码公开在码云 其中包括pom中 父依赖

https://gitee.com/jiajitao/springCloudFirst


您的支持