Microservice component: routing gateway zuul
1. Introduction to zuul
Zuul is a framework for providing edge services such as dynamic routing, monitoring, resiliency, and security in microservices. The control authority mechanism of open services is realized without destroying the stateless characteristics of microservices.
zuul main functions:
① zuul URL mapping
② zuul serviceId mapping;
③ zuul filter;
2. zuul use
2-1 Start the service provider
java -jar -Dserver.port=8071 microservice-provider-user-0.0.1-SNAPSHOT.jar java -jar -Dserver.port=8072 microservice-provider-user-0.0.1-SNAPSHOT.jar
2-2 URL Mapping
All access to /user1/** is mapped to http://127.0.0.1:8071/
zuul: routes: movie: path: /user1/** # The path you want to map to url: http://127.0.0.1:8071/ # service address
Start API Gateway, @EnableZuulProxy enables zuul
@SpringBootApplication @EnableZuulProxy @EnableAutoConfiguration public class ZuulApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ZuulApiGatewayApplication.class, args); } }
access:
http://127.0.0.1:8050/user1/1
2-3 serviceId mapping
Zuul queries the eureka service registration information and maps all /user/** accesses to the microservice-provider-user service provider
eureka: instance: hostname: gateway client: serviceUrl: defaultZone: http://localhost:8762/eureka/,http://localhost:8761/eureka/ zuul: routes: movie: path: /user/** # The path you want to map to service-id: microservice-provider-user # Eureka中的serviceId
access:
http://127.0.0.1:8050/user/1
2-3 Filters
Using the zuul filter, the security mechanism of external services can be realized, and the client can only access the resources it should access through security measures;
/** * Verify the token parameter of the request * * @author mengka * @date 2017/07/15. */ @ Slf4j public class AccessFilter extends ZuulFilter { /** * Returns a string representing the type of filter, four different life cycle filter types are defined in zuul * 1) pre: called before the request is routed; * 2) route: called when routing requests; * 3) post: called after routing and error filters; * 4) error: called when an error occurs while processing the request; * * @return */ @Override public String filterType() { return ZuulFilterTypeEnums.PRE.getName(); } /** * Define the execution order of the filter by int value * * @return */ @Override public int filterOrder() { return 50000; } /** * Returns a boolean to determine whether the filter should be executed * * @return */ @Override public boolean shouldFilter() { return RequestContext.getCurrentContext().getRequest().getRequestURI().matches("/user/.*"); } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("accessToken"); if (accessToken == null) { log.warn("access token is empty"); ctx.setSendZuulResponse(false);//Let zuul filter the request and not route it ctx.setResponseStatusCode(401);//The error code returned return null; } log.info("access token ok"); return null; } }
@Configuration public class AppConfig { @Bean public AccessFilter accessFilter() { return new AccessFilter(); } }
Test token verification:
@Test public void test_zuul_token_filter_02() { log.info("test_zuul_token_filter_02.."); Response response = RestAssured.get("http://127.0.0.1:8050/user/2"); assertEquals(401, response.getStatusCode()); } @Test public void test_zuul_token_filter_01() { log.info("test_zuul_token_filter_01.."); Response response = RestAssured.get("http://127.0.0.1:8050/user/2?orgCode=123456&accessToken=123456"); assertEquals(200, response.getStatusCode()); String result = response.getBody().asString(); JSONObject jsonObject = JSON.parseObject(result); assertEquals("Tom", jsonObject.getString("username")); }