Nginx+Zuul Cluster Implements Highly Available Gateway

Keywords: Java Nginx Spring github SQL

Code reference: https://github.com/HCJ-shadow/Zuul-Gateway-Cluster-Nginx


Routing Forwarding in Zuul

preparation in advance

  • Build Eureka Service Registration Center

  • Service Provider msc-provider-5001 [Provide a hello request for testing]


    Create gateway-7001


  • pom dependency
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
  • yaml
server:
  port: 7001
spring:
  application:
    name: zuul-gateway

eureka:
  client:
    service-url:
      defaultZone: http://eureka2001.com:2001/eureka/,http://eureka2002.com:2002/eureka/,http://eureka2003.com:2003/eureka/
  • Main Class {Comment@EnableZuulProxy}
package zkrun.top;

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

test

Run Eureka, provider, and gateway in turn


Access: http://localhost:2001/

Access provider's Hello path: http://localhost:5001/hello

Default mapping path for gateway: http://localhost:7001/msc-provider/hello

Default routing rule: serviceId/path on Eureka for http://zuulhost:zuulport/microservice

The serviceId is in lowercase.

Custom Routing Rules

The default routing rule is routed by service name, or you can customize the name of the route to enhance the security of the service.

zuul:
  routes:
    api-a:
      path: /api-a/**
      serviceId: msc-provider
#    api-b:
#      path: /api-b/**
#      serviceId: service-feign

User Access:
http://localhost:7001/api-a/hello

These effects can also be achieved.Essentially, the name of the microservice is hidden.

Zuul's filter function

zuul's filters are primarily used for authentication.


Create a simple filter:

package zkrun.top.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 MyFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(MyFilter.class);

    /**
     * filterType: Returns a string representing the type of filter and defines four filter types for different life cycles in zuul, as follows:
     * pre: Before Routing
     * routing: When Routing
     * post:  After Routing
     * error: Send an incorrect call
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * filterOrder: Order of filtering
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }


    /**
     * shouldFilter: Here you can write a logical judgment whether you want to filter or not, this article true, always filter.
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * run: The specific logic of the filter.It can be complex to use, including checking sql, nosql to determine whether the request has access or not.
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        System.out.println(request);

        Object  token = request.getParameter("token");
        System.out.println(token);
        if(token == null) {
            log.info("fail");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);//401 means no permission
            try {
                ctx.getResponse().getWriter().write("token is empty");
            }catch (Exception e)
            {}
            return null;
        }
        log.info("pass");
        return null;

    }
}

Without token:

Added token:

http://localhost:7001/api-a/hello?token=1234

In the actual development, user information and form information are extracted from the database to match, and authentication function is implemented.

Nginx+Zuul Cluster Implements Highly Available Gateway

Two functions:

  • Nginx achieves load balancing through polling
  • Zuul achieves high availability through clustering

Roughly like this:

Ideas for implementation:

Each of the zuul gateways has the same routing for all filters except for port differences.

Create gateway for port 7001,7002,7003.


nginx configuration:

Download:

http://nginx.org/en/download.html

modify

  #Configure upstream server gateway port cluster, default polling mechanism
    upstream  backServer{
        server 127.0.0.1:7001 weight=1;
        server 127.0.0.1:7002 weight=1;
        server 127.0.0.1:7003 weight=1;

    }

    server {
        listen       80;
        server_name  nginxtest.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            ### Specify upstream server load balancing server
            proxy_pass http://backServer/;
            index  index.html index.htm;
        }

test

Start Eureka

Start Provider

Start Zuul Gateway Cluster

Start Nginx


Nginx startup: (double-click)

Visit

Poll to 7002


http://nginxtest.com/api-a/hello?token=2

Poll to 7001

Posted by dhvani on Fri, 23 Aug 2019 13:44:40 -0700