API Gateway is a very important part of the microservices architecture, there are many different services provided to external use, API gateway can be a unified portal, can also be done on the gateway for protocol conversion, permission control and request statistics and limit flow and other work
Spring-cloud encapsulates the open source API gateway implemented by Netflix Zuul, and we can easily launch an instance of a Zuul gateway, support registering with Eureka, and proxy for services already registered on Eureka
Use idea's spring initializer to create a Zuul project
Fill in the relevant group type information, choose to use Gradle to build
Select Zuul and Eureka Client
Select the location of the project and Gradle installation:
Add @EnableZuulProxy annotations on the startup class, which is a @enablezuulserver version of the Zuul Server that identifies the Eureka registry and the load Balancer Ribbon
Code to start the class:
package com.jiaoyiping.springcloud.zuul;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@SpringBootApplication@EnableZuulProxypublic class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); }}
Zuul the most essential function is to do reverse proxy, route forwarding and interception and processing of requests, routing forwarding configuration in the configuration file, Zuul can do several forms of forwarding:
Redirect the request to an external URL,
If we want to configure, the request that conforms to/baidu prefix is redirected to baidu.com, can do the following configuration:
zuul: routes: baidu: path: /baidu/** url: http://www.baidu.com
Forward the request to the internally provided request path, using Forforward:
For example, if our gateway itself provides a service that begins with/session, and we want the request to start with/session in the gateway request to be handled by the gateway itself, you can configure the following
zuul: routes: session: path: /session/** url: forward:/session
Proxy and request forwarding for services that are already registered with Eureka, only the Serviceid of the service in the Eureka is required
zuul: routes: provider: path: /provider/** serviceId: PROVIDER #(去请求目标服务的时候)是否丢掉前缀,根据需求来配置 stripPrefix: true
The complete configuration is as follows:
Spring:application:name:zuul cloud:inetutils:preferred-networks:192.168.1.server:port:808 4 Tomcat:uri-encoding:utf-8 Servlet:context-path:/logging:config:classpath:logback.xmlzuul:routes:bai Du:path:/baidu/** url:http://www.baidu.com provider:path:/provider/** serviceid:provider # Whether or not to drop the prefix when requesting the target service, configure Stripprefix:true Session:path as required:/session/** Url:forward:/sessioneureka: instance:hostname:192.168.1.5 prefer-ip-address:true Instance-id:192.168.1.5:${server.port} client:healt Hcheck:enabled:true registerwitheureka:true fetchregistry:true service-url:defaultzone:http://127 .0.0.1:8081/eureka/hystrix:command:default:execution:isolation:thread:timeoutinm Illiseconds:25000ribbon:maxautoretries:2 maxautoretriesnextserver:3 restclient:enabled:true
The configuration of filter in Zuul, Zuul provides three types of Filter,prefilter,routefilter and Postfilter, respectively, corresponding to the different stages in the request, for the same request, there is a RequestContext object , shared in three-phase filter
Suppose we want to develop a function of statistical request time, we need to record the start time in Prefilter, and put the whole start time in RequestContext, get the start time in Postfilter, subtract the start time with the current time, is the time of request execution
Define a Prefilter:
Package Com.jiaoyiping.springcloud.zuul.filter;import Com.netflix.zuul.zuulfilter;import Com.netflix.zuul.context.requestcontext;import Com.netflix.zuul.exception.zuulexception;import Org.slf4j.Logger; Import Org.slf4j.loggerfactory;import org.springframework.cloud.netflix.zuul.filters.support.filterconstants;/** * Created with Intellij idea * * @author: Jiaoyiping * Mail: [email protected] * date:2018/04/05 * time:16:24 * to Change this template use File | Settings | Editor | File and Code Templates */public class Timecostprefilter extends Zuulfilter {public static final String Start_time_key = "Start_time"; Private Logger Logger = Loggerfactory.getlogger (Timecostprefilter.class); @Override public String FilterType () {return filterconstants.pre_type; } @Override public int filterorder () {return 0; }/** * Determines if the logic to intercept is * * @return */@Override public boolean shouldfilter () {return true; } @Override PUblic Object Run () throws Zuulexception {Long startTime = System.currenttimemillis (); Requestcontext.getcurrentcontext (). Set (Start_time_key, startTime); return null; }}
Defined with Postfilter:
Package Com.jiaoyiping.springcloud.zuul.filter;import Com.netflix.zuul.zuulfilter;import Com.netflix.zuul.context.requestcontext;import Com.netflix.zuul.exception.zuulexception;import Org.slf4j.Logger; Import Org.slf4j.loggerfactory;import org.springframework.cloud.netflix.zuul.filters.support.filterconstants;/** * Created with Intellij idea * * @author: Jiaoyiping * Mail: [email protected] * date:2018/04/05 * time:16:37 * to Change this template use File | Settings | Editor | File and Code Templates */public class Timecostpostfilter extends Zuulfilter {private static final String Start_time_k E = "Start_time"; Private Logger Logger = Loggerfactory.getlogger (Timecostpostfilter.class); @Override public String FilterType () {return filterconstants.post_type; } @Override public int filterorder () {return 0; } @Override public Boolean shouldfilter () {return true; } @Override public Object run () throws Zuulexception { Long startTime = (long) requestcontext.getcurrentcontext (). get (Start_time_ke); Logger.info ("request completed, time {} seconds", (System.currenttimemillis ()-StartTime)/1000); return null; }}
Inject these two filter in a configuration class:
package com.jiaoyiping.springcloud.zuul.config;import com.jiaoyiping.springcloud.zuul.filter.PDSFilter;import com.jiaoyiping.springcloud.zuul.filter.TimeCostPostFilter;import com.jiaoyiping.springcloud.zuul.filter.TimeCostPreFilter;import com.netflix.zuul.ZuulFilter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * Created with Intellij IDEA * * @author: jiaoyiping * Mail: [email protected] * Date: 2018/04/05 * Time: 17:32 * To change this template use File | Settings | Editor | File and Code Templates */@Configurationpublic class FilterConfig { @Bean public ZuulFilter timeCostPreFilter() { return new TimeCostPreFilter(); } @Bean public ZuulFilter timeCostPostFilter() { return new TimeCostPostFilter(); } @Bean public ZuulFilter pdsFilter() { return new PDSFilter(); }}
Starting the project, you can see that the Zuul gateway is already registered on the Eureka:
Request provide corresponding address, found that Zuul can successfully invoke the corresponding service on Eureka and return the result correctly:
Spring-cloud-based MicroServices (4) API Gateway Zuul