本文转自:http://blog.csdn.net/qq_22841811/article/details/67637786#准备工做html
刚开始写博客,先从摘录开始吧。后续陆续将有道的笔记迁移过来~~~。java
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud-microservice-study</artifactId> <groupId>com.clsaa.learn.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-gateway-zuul</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> </dependencies> </project>
package com.clsaa.learn.zuul; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; /** 使用@EnableZuulProxy注解激活zuul。 * 跟进该注解能够看到该注解整合了@EnableCircuitBreaker、@EnableDiscoveryClient,是个组合注解,目的是简化配置。 * Created by Egg on 2017/7/25 */ @SpringBootApplication @EnableZuulProxy public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class,args); } }
配置文件:application.ymlweb
spring: application: name: microservice-gateway-zuul server: port: 8040 eureka: instance: hostname: localhost # 指定该Eureka实例的主机名 prefer-ip-address: true client: serviceUrl: defaultZone: http://username:password@localhost:8761/eureka
咱们如今访问http://localhost:8050/microservice-provider-user/1试试。会惊人地看到:正则表达式
{"id":1,"username":"Tom","age":12}
这不正是microservice-provider-user服务中id=1的用户信息吗?spring
因此咱们能够总结出规律:访问apache
将会访问到 http://GATEWAY:GATEWAY_PORT/想要访问的Eureka服务id的小写/**http://想要访问的Eureka服务id的小写:该服务端口/**
上文咱们已经完成了经过API Gateway去访问微服务的目的,是经过http://GATEWAY:GATEWAY_PORT/想要访问的Eureka服务id的小写/**
的形式访问的,那么若是咱们想自定义在API Gateway中的路径呢?譬如想使用http://localhost:8050/user/1
就可以将请求路由到http://localhost:8000/1呢?后端
只须要作一点小小的配置便可:api
spring: application: name: microservice-api-gateway server: port: 8050 eureka: instance: hostname: gateway client: serviceUrl: defaultZone: http://discovery:8761/eureka/ # 下面整个树都非必须,若是不配置,将默认使用 http://GATEWAY:GATEWAY_PORT/想要访问的Eureka服务id的小写/** 路由到:http://想要访问的Eureka服务id的小写:该服务端口/** zuul: routes: user: # 能够随便写,在zuul上面惟一便可;当这里的值 = service-id时,service-id能够不写。 path: /user/** # 想要映射到的路径 service-id: microservice-provider-user # Eureka中的serviceId
若是咱们如今只想将microservice-consumer-movie-ribbon服务暴露给外部,microservice-provider-user不想暴露,那么应该怎么办呢?安全
依然只是一点小小的配置便可:服务器
spring: application: name: microservice-api-gateway server: port: 8050 eureka: instance: hostname: gateway client: serviceUrl: defaultZone: http://discovery:8761/eureka/ zuul: ignored-services: microservice-provider-user # 须要忽视的服务(配置后将不会被路由) routes: movie: # 能够随便写,在zuul上面惟一便可;当这里的值 = service-id时,service-id能够不写。 path: /movie/** # 想要映射到的路径 service-id: microservice-consumer-movie-ribbon-with-hystrix # Eureka中的serviceId
zuul: routes: users: path: /myusers/** url: http://example.com/users_service
zuul: routes: users: path: /myusers/** serviceId: users ribbon: eureka: enabled: false users: #这是ribion要请求的serviceID ribbon: listOfServers: http://localhost:7900,http://localhost:7901
@Bean public PatternServiceRouteMapper serviceRouteMapper() { return new PatternServiceRouteMapper( "(?<name>^.+)-(?<version>v.+$)", "${version}/${name}"); }
zuul: ignoredPatterns: /**/admin/** routes: users: /myusers/**
This means that all calls such as “/myusers/101” will be forwarded to “/101” on the “users” service. But calls including “/admin/” will not resolve.
若是你须要你的路由以保留它们的顺序,你须要使用YAML文件,由于使用属性文件将会丢失顺序。 例如:若是要使用属性文件,则旧路径可能会在用户路径前面显示,致使用户路径没法访问。
zuul: routes: first: path: /first/** url: http://first.example.com second: path: /second/** url: forward:/second third: path: /third/** url: forward:/3rd # 本地的转发 legacy: path: /** url: http://legacy.example.com
package com.clsaa.learn.zuul.fallback; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; 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; @Component public class MyFallbackProvider implements ZuulFallbackProvider { @Override public String getRoute() { //route 如 return "microservice-provider-user"; } @Override public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return 200; } @Override public String getStatusText() throws IOException { return "OK"; } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream(("fallback"+MyFallbackProvider.this.getRoute()).getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }
Zuul大部分功能都是经过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
10.2 编写zuul过滤器
package com.clsaa.learn.zuul; 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 PreZuulFilter extends ZuulFilter{ private final static Logger LOGGER = LoggerFactory.getLogger(PreZuulFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1;//数字越大越靠后 } @Override public boolean shouldFilter() { return true; } @Override public Object run() { HttpServletRequest servletRequest = RequestContext.getCurrentContext().getRequest(); String host = servletRequest.getRemoteHost(); PreZuulFilter.LOGGER.info("request host : " + host); return null; } }
479/5000
Zuul for Spring Cloud在代理和服务器模式下默认启用了一些ZuulFilter bean。 有关已启用的可能过滤器,请参阅zuul过滤器包。 若是你想禁用一个,只需设置:
zuul.<SimpleClassName>.<filterType>.disable=true
按照惯例,过滤器以后的包是Zuul过滤器类型。 例如,禁用
org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter set zuul.SendResponseFilter.post.disable = true