Spring Cloud 微服务入门教程(八):Spring Cloud Zuul 服务网关动态路由和Cookie头信息传递和跨域
上一节我们讲了微服务只间通过消息队列实现异步通讯,本节将介绍微服务中的网关Spring Cloud Zuul,可以实现统一管理众多的接口、实现负载均衡等功能。
新建一个网关模块
新建一个Maven的网关模块,依赖spring-cloud-starter-netflix-zuul,修改POM文件:
<?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>cloud</artifactId>
<groupId>net.renfei</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>net.renfei</groupId>
<artifactId>gateway</artifactId>
<version>1.0.0</version>
<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-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
</project>
添加一个程序启动类,作为启动入口,并增加@EnableZuulProxy注解:
package net.renfei.gateway;
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;
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
以及配置文件bootstrap.yml,可以实现动态获取配置,为了方便演示,我将配置直接写入bootstrap.yml,现实中是写到Git远程配置中心的:
spring:
application:
name: Gateway
cloud:
config:
discovery:
service-id: config
enabled: true
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 8080
zuul:
routes:
democlientroute:
path: /DC/**
service-id: DemoClient
sensitiveHeaders:
demoserviceroute:
path: /DS/**
service-id: DemoService
ignored-patterns:
- /admin
- /myadmin
zuul.routes后面的名称是可以自己定义的,path是指请求的路径匹配,service-id是对应路由到哪个服务的服务名称,sensitiveHeaders的作用是为了让Zuul将请求的头信息包括Cookie转发给后端服务,这个配置默认是在org.springframework.cloud.netflix.zuul.filters.ZuulProperties#sensitiveHeaders,我们可以看到默认的是private Set<String> sensitiveHeaders = new LinkedHashSet(Arrays.asList("Cookie", "Set-Cookie", "Authorization"));,如果你的头信息不是这三个,可以自己在配置文件中自定义。ignored-patterns的意思是忽略这些地址不做转发。
Zuul的过滤器
网关Zuul的核心其实就是一堆过滤器,所以在网关这里会写很多过滤器,由于有点多,我直接上一个表格:
类型 | 顺序 | 过滤器 | 功能 |
---|---|---|---|
pre | -3 | ServletDetectionFilter | 标记处理 Servlet 的类型 |
pre | -2 | Servlet30WrapperFilter | 包装 HttpServletRequest 请求 |
pre | -1 | FormBodyWrapperFilter | 包装请求体 |
route | 1 | DebugFilter | 标记调试标志 |
route | 5 | PreDecorationFilter | 处理请求上下文供后续使用 |
route | 10 | RibbonRoutingFilter | serviceId |
route | 100 | SimpleHostRoutingFilter | url 请求转发 |
route | 500 | SendForwardFilter | forward 请求转发 |
post | 0 | SendErrorFilter | 处理有错误的请求响应 |
post | 1000 | SendResponseFilter | 处理正常的请求响应 |
我们去继承com.netflix.zuul.ZuulFilter,看看都有哪些设置:
package net.renfei.gateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 授权过滤器,可以判断用户是否有权访问
*
* @author RenFei
*/
@Component
public class AuthorizationFilter extends ZuulFilter {
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
//在此处执行判断逻辑
return null;
}
}
是不是很简单,先设置一个类型,然后设置执行的顺序,run()里面执行我们想要做的逻辑。
Zuul路由的动态刷新
网关会管理众多的服务接口,如果每次配置都重启非常影响生产,之前的章节我们已经搭建好SpringCloudBUS消息总线,实现了动态配置更新,我们就利用BUG总线消息刷新配置,POM中依赖spring-cloud-starter-config,然后我们新建一个配置类,加上@RefreshScope注解就可以实现动态刷新了。由于我是演示,就不去Git上面折腾配置文件了,给出参考代码:
package net.renfei.gateway.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.stereotype.Component;
/**
* Zuul的配置实现动态从配置中心拉取
*
* @author RenFei
*/
@Component
public class ZuulConfig {
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
return new ZuulProperties();
}
}
Zuul网关的跨域设置
我们新建一个配置类CorsConfig,注册一个Bean:CorsFilter然后进行设置,代码如下:
package net.renfei.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
/**
* 跨域配置
*
* @author RenFei
*/
@Component
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//是否支持Cookie跨域
config.setAllowCredentials(true);
//原始域列表
config.setAllowedOrigins(Arrays.asList("*"));
//允许的头
config.setAllowedHeaders(Arrays.asList("*"));
//允许的方法,GET、POST....
config.setAllowedMethods(Arrays.asList("*"));
//允许跨域时间,时间段内不再检查跨域
config.setMaxAge(300L);
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", config);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
代码中已经有了注释,就不再啰嗦了,一个基本的网关就搭建好了。
商业用途请联系作者获得授权。
版权声明:本文为博主「任霏」原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接及本声明。
相关推荐
猜你还喜欢这些内容,不妨试试阅读一下评论与留言
以下内容均由网友提交发布,版权与真实性无法查证,请自行辨别。微信订阅号
扫码关注「任霏博客」微信订阅号- 大佬 引入jar包那里的 driver class 怎么选的?
- 我也遇到了这个问题,已经解决了,在此分享一下 1、宿主机也要创建kingbase的用户和用户组,并且要查看一下用户和用户组的ID(这个很重要) 2、把data目录的用户和用户组设置为kingbase 3、先不要把data路径挂载到宿主机上,这时就可以正常启动,启动后进入容器,查看一下容器内的kingbase的用户和用户组ID是多少,和第一步的ID是否一致,如果ID一致,那正常挂载目录就行;如果ID不一致,那就需要修改Dockerfile文件,在构建镜像时,修改容器内的用户和用户组ID,必须和宿主机的保持一致。然后重新构建镜像,就可以正常挂载宿主机目录了 4、其实直接修改宿主机的用户和用户组ID也是可以的,但是容器内的ID一般是1000,但是宿主机的这个ID很可能已经被占用了,无法修改,就只能修改容器内的ID
- 接口已经允许跨域请求,也就是说你可以在你的页面上调用,获取用户的公网 IP。 如果你还需要其他需求,可以提交 Issue 给我。
- V008R003C002B0320 这个对应的jdbc链接驱动你在哪里找到的?我也遇到了这个问题。
- WARNING: max_connections should be less than orequal than 10 (restricted by license) HINT: the value of max_connect is set 10 WARNING: max_connections should be less than orequal than 10 (restricted by license) HINT: the value of max_connect is set 10 kingbase: superuser_reserved_connections must be less than max_connections 我按照文档修改了以后,不知道如何重启。
- 然后把数字都改成 1 再启动。 如何重新启动?
- ksql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.KINGBASE.54321"
- 进入容器查看一下日志,是不是启动失败了,日志文件在:/opt/kingbase/logfile
- ksql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.KINGBASE.54321"?
- 先通过 docker exec -it 容器名/id /bin/bash 进入容器,然后在容器中使用 ksql 客户端进行连接数据库:/opt/kingbase/Server/bin/ksql -U system test
- 免费.ml域名10年委托合同到期被马里共和国收回域名经营权
- 从极狐Gitlab看各种中间件技术选型
- 时隔十年首次收到 Google AdSense 的付款
- ga域名被加蓬共和国从Freenom公司手中收回域名经营权
- Freenom 被 Meta(Facebook) 起诉导致暂停 .tk/.ga/.ml/.cf/.gq 等新域名注册
- 生花妙笔信手来 – 基于 Amazon SageMaker 使用 Grounded-SAM 加速电商广告素材生成 [1]
- github.renfei.net 不再完整代理 Github 页面改为代理指定文件
- 优雅的源代码管理(三):本地优雅的使用 Git Rebase 变基
- 优雅的源代码管理(二):Git 的工作原理
- 优雅的源代码管理(一):版本控制系统 VCS(Version Control System)与软件配置管理 SCM(Software Configuration Management)