您现在的位置是:首页 > 文章详情

SpringCloud Finchley 实战入门(基于springBoot 2.0.3)【九 zuul 微服务网关配置】

日期:2018-07-31点击:328

网关介绍

API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、 负载均衡、 校验过滤等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。

入门例子

创建一个moudle,命名为eureka-zuul,创建时选择一些的组件依赖:


img_dca2630fbff0b6925eea7126fb14fbb5.png
1533108772510.png

pom.xml文件如下:

<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>eureka-zuul</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-zuul</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 

配置application.yml

server: port: 1100 spring: application: name: service-zuul 

application.yml只是设置基本信息,结合之前创建的配置中心,我们把主要把配置的主要信息通过eureka-config-git配置中心获取。所以添加一个bootstrap.yml配置文件。

spring: cloud: config: profile: dev #dev开发环境配置文件,test测试环境配置文件,pro正式环境文件 label: master #git仓库对应的分支名称 config-label-test # label: config-label-test #git仓库对应的分支名称 config-label-test # uri: http://localhost:7001/ #config-server name: service-zuul discovery: serviceId: config-server-git #基于服务注册发现的方式查找 enabled: true eureka: client: serviceUrl: defaultZone: http://peer1:8762/eureka/,http://peer2:8763/eureka/ management: #配置暴露监控节点地址 endpoints: web: exposure: include: "*" cors: allowed-origins: "*" allowed-methods: "*" #注册中心eureka.client.service-url.defaultZone = 一定要放在boostrap文件中,不然启动会报错 

这里的配置主要就是指向配置中心。

项目的主类添加EnableZuulProxy注解

/*@SpringBootApplication EnableEurekaClient*/ @EnableZuulProxy//注解@EnableZuulProxy以开启zuul特性 @SpringCloudApplication //使用@SpringCloudApplication包括, // Springboot注解,注册服务到注册中心注解,熔断器注解 // 在SpringCloud看来这是每一微服务所必须应有的三个注解,所以才推出了@SpringCloudApplication注解 public class EurekaZuulApplication { public static void main(String[] args) { SpringApplication.run(EurekaZuulApplication.class, args); } 

另外config-repo这个配置文件中心的项目有个zuul的配置文件bootstrap.yml主要配置的就是指向了这个config-repo的配置文件。
service-zuul-dev.yml

zuul: ignoredServices: '*' #忽略所有未配置的service,每一个微服务的路由配置都需要配置 host: connect-timeout-millis: 20000 socket-timeout-millis: 20000 routes: ribbon-service: #自定义名称 path: /ribbon/** serviceId: service-user-ribbon #/ribbon/开头的路径转发至service-user-ribbon微服务 sensitiveHeaders: true #springcloud项目中经过网关zuul转发请求后发生session失效问题,这是由于zuul默认会丢弃原来的session并生成新的session #所以这里对制定的路由开启自定义敏感头。除了设置为true,也可以设置为空。zuul.sensitiveHeaders= 只是全局设置的做法。不推荐!破坏了默认设置的用意 hystrix: #hystrix配置 command: default: execution: isolation: thread: timeoutInMilliseconds: 2500 ribbon: #ribbon负载均衡参数配置 ReadTimeout: 5000 ConnectTimeout: 5000 eureka: client: serviceUrl: defaultZone: http://peer1:8762/eureka/,http://peer2:8763/eureka/ 

相关的配置注释已经说得很清楚了

接下来我们新建一个类来测试zuul功能。
创建一个UserFallbackProvider类实现FallbackProvider接口

 @Component public class UserFallbackProvider implements FallbackProvider { @Override public String getRoute() { return "service-user-ribbon"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { 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".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } } 
img_280150dbec721e90d55d6c3b1f17ce70.png
1533110129632.png

依次启动服务注册中心=>configGit=>serviceUser=>serviceUserRibbon=>zuul


img_97ba0658190d1d9818368c3a9502d609.png
1533110998412.png

img_621e837619e770bf5d841a68aaf4f4ef.png
1533110900002.png

img_b1ed68f5fb12f9bbe869eb1a5405ab70.png
1533111016759.png

服务确保正常,我们访问zuul的服务地址:http://localhost:1100/ribbon/listUsersByRibbon

img_eaf372f3aa6d28091366f405716b3b60.png
1533111048541.png

数据正常返回,说明zuul项目配置正常。

过滤器

上面的演示是用zuul实现一个基本的接口请映射请求,zuul主要的主要是认证和鉴权这方面的功能。我们下面实现一个过滤器的功能;在上面的项目基础上,我们新建一个过滤器AccessFilter实现ZuulFilter接口

@Log public class AccessFilter extends ZuulFilter { @Override public String filterType() { /** * pre 代表请求被路由前执行 */ return "pre"; } @Override public int filterOrder() { /** * 过滤器执行的顺序 */ return 0; } @Override public boolean shouldFilter() { /** * 判断过滤器是否执行 */ return true; } /** * 具体的过滤逻辑 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); log.info("send " + request.getMethod() + " Request to " + request.getRequestURL().toString()); String token = request.getParameter("token"); if (StringUtils.isBlank(token)) { log.warning("access token is empty"); currentContext.setSendZuulResponse(false); currentContext.setResponseStatusCode(401); try { HttpServletResponse response = currentContext.getResponse(); response.setCharacterEncoding("utf-8"); //设置字符集 response.setContentType("text/html; charset=utf-8"); //设置相应格式 response.getWriter().write("token 验证失败"); } catch (IOException e) { log.info("response io异常"); e.printStackTrace(); } return null; } return null; } } 

这里的过滤器主要的作用是拦截请求,然后从请求体中获取参数token。判断有没有token这个参数,如果有的话,就通过;如果获取不到token参数,就直接响应一个401的状态。
然后在项目的主类中注入该过滤器:

/** * 启用过滤器功能 * * @return */ @Bean public AccessFilter accessFilter() { return new AccessFilter(); } 

重启zuul服务,重新访问地址:http://localhost:1100/ribbon/listUsersByRibbon
当我们没有在请求地址中加上token的参数时,该接口响应token校验失败了。

img_37d9050d6a3dab1441648a9ac6b1371a.png
1533111845622.png

我们在通过地址http://localhost:1100/ribbon/listUsersByRibbon?token=token
在加上token参数的情况下,过滤器校验通过就可以正常的响应接口了。

img_17dff9ccda89bd9883902f1ade90ac90.png
1533111890497.png

github 项目源码

原文链接:https://yq.aliyun.com/articles/654249
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章