Spring Cloud advanced Road 7: service gateway (zuul)

 

For reprint, please indicate the author and source:

Author: Galactic architect

Original link: https://blog.csdn.net/liuminglei1987/article/details/104003890

Brief introduction

Official statement

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups as appropriate.

In short, Zuul is the gateway to all requests from devices and websites to the back end of applications, aiming at dynamic routing, monitoring, flexibility and security.

What can zuul do

Zuul uses filters with different types that perform the following functions:

  • Authentication and security, identifying the authentication requirements for each resource, and rejecting requests that do not meet the requirements.

  • Tracking monitoring, tracking meaningful data and statistics at the boundary, so as to provide us with accurate production view.

  • Dynamic routing, dynamically routing requests to different back-end clusters as needed.

  • Stress testing, gradually increasing traffic to the cluster to assess performance.

  • Load control, which allocates capacity for each type of request and discards requests that exceed the limit.

  • Static response processing, which builds the response directly at the boundary rather than forwarding it to the internal service cluster

Why a gateway

In short, a gateway is routing and forwarding + request filtering.

As mentioned at the beginning of this article, it is very convenient to complete a series of cross-section functions in the service gateway, such as permission verification, audit, interface monitoring, current limiting and log collection. Moreover, it can also be linked with the service registry to avoid the complicated configuration of many microservices, such as addresses and ports. It can be found and called automatically through service discovery directly.

If these features are done once for each downstream microservice, the difficulty and workload can be imagined. Therefore, the importance of gateway is self-evident.

For details, please refer to the article: Why there should be a service gateway.

 

Create commodity project

Reuse the xmall product project in the previous article and start it with port 8080.

 

Create Gateway project

pom dependence

<?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>    <parent>        <groupId>com.luas.cloud</groupId>        <artifactId>java-boot-parent-2.1</artifactId>        <version>1.0.0-SNAPSHOT</version>        <relativePath>../../java-boot-parent-2.1</relativePath>    </parent>    <groupId>com.luas.xmall</groupId>    <artifactId>xmall-zuul</artifactId>    <version>1.0.0-SNAPSHOT</version>    <name>xmall-zuul</name>    <description>Gateway service</description>    <properties>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>        </dependency>        <!-- nacos cloud -->        <dependency>            <groupId>com.alibaba.cloud</groupId>            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>        </dependency>        <dependency>            <groupId>com.alibaba.cloud</groupId>            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>            <exclusions>                <exclusion>                    <groupId>org.junit.vintage</groupId>                    <artifactId>junit-vintage-engine</artifactId>                </exclusion>            </exclusions>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>

nacos configuration

spring:  application:    name: xmall-zuul  cloud:    nacos:      config:        server-addr: 127.0.0.1:8848        file-extension: yml      discovery:        server-addr: 127.0.0.1:8848

Routing rules

Configure the routing rules in application.yml.

server:  port: 5566zuul:  prefix: /gateway  sensitive-headers:  routes:    product:      path: /product/**      service-id: xmall-product      strip-prefix: true

Among them, prefix is the uniform prefix, which plays the role of identity and path unification and can be automatically filtered (zuul. Strip prefix = true). Routing rules routes have the following meanings:

  • Rule ID, which uniquely identifies the routing rule, has no other special meaning. It may be used by other components in the future.

  • Path, ant style path matching rules, such as / product / * *, means that every path beginning with "/ product" is forwarded to the xmall product service

  • strip-prefix, whether to filter the prefix. This prefix is the prefix in the path. If it is filtered, this prefix will be filtered out in the real forwarding path.

Take this configuration as an example, visit http://localhost:5566/gateway/product/sku/1122, the real request path to the xmall product service is / sku/1122, and the gateway and product have been filtered out.

Turn on the gateway function

Enable zuul gateway function through @ EnableZuulProxy annotation.

package com.luas.xmall.gateway;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@EnableZuulProxy@SpringBootApplicationpublic class XmallZuulApplication {    public static void main(String[] args) {        SpringApplication.run(XmallZuulApplication.class, args);    }}

Start the gateway project with port 5566.

Visit http://localhost:8080/sku/1122 to display product information normally.

Visit http://localhost:5566/gateway/product/sku/1122 to display the product information normally.

zuul gateway successfully routed the request to the commodity service.

 

identity authentication

As mentioned before, an important role of gateway is identity authentication. Identity authentication includes two aspects, authentication and authentication. Here is just a brief introduction to authentication.

Create a pre authentication filter

zuul filters are divided into four types, namely:

  • pre, before routing.

  • route, called when routing

  • post, called after routing

  • Error, called when an error occurs

Create an authentication filter of pre type to authenticate the request. Take token (query type) as an example.

package com.luas.xmall.gateway.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 org.springframework.stereotype.Component;
​
import javax.servlet.http.HttpServletRequest;
​
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
​
@Component
public class PreAuthenticationFilter extends ZuulFilter {
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    @Override
    public String filterType() {
        return PRE_TYPE;
    }
​
    @Override
    public int filterOrder() {
        return 0;
    }
​
    @Override
    public boolean shouldFilter() {
        return true;
    }
​
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
​
        logger.info(String.format("[%s] url process", request.getRequestURL().toString(), request.getMethod()));
​
        String token = request.getParameter("token");
​
        if (StringUtils.isBlank(token)) {
            logger.warn("token is empty");
​
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
​
            try {
                ctx.getResponse().getWriter().write("token is empty.");
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
        
        return null;
    }
}

The filterOrder method returns the filter execution order. The smaller the number, the higher the order.

The shouldFilter method is a judgment method that returns whether the filtering logic needs to be executed, that is, the run method. You can write judgment logic by yourself according to business scenarios.

As for the run method, of course, it is the filter important logic itself, which can do many operations. For example, take token (in the form of query parameter) from request, judge and make corresponding judgment and response.

Restart the gateway project and visit http://localhost:5566/gateway/product/sku/1122 again. The results are as follows:

The console outputs the Request Method and url information, and warns that the token is empty.

Suppose we visit the authorized service, get the token, and visit http://localhost:5566/gateway/product/sku/1122?token=0000 again, displaying the product information normally.

PreAuthenticationFilter has taken effect successfully. Unauthorized requests have been blocked and authorized requests have been ignored.

 

Source code

github

https://github.com/liuminglei/SpringCloudLearning/tree/master/07/

gitee

https://gitee.com/xbd521/SpringCloudLearning/tree/master/07/


End of text

 

Wechat search [Galaxy architect] to find more exciting content.

 

Published 16 original articles, won praise 1, visited 1526

Tags: Spring Maven Apache Java

Posted on Wed, 15 Jan 2020 23:52:20 -0800 by Design