惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
云风的 BLOG
云风的 BLOG
小众软件
小众软件
雷峰网
雷峰网
博客园 - 【当耐特】
V
V2EX
WordPress大学
WordPress大学
IT之家
IT之家
Last Week in AI
Last Week in AI
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
有赞技术团队
有赞技术团队
The Cloudflare Blog
Jina AI
Jina AI
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

任霏博客

我将关闭服务器:AI彻底掐死了奄奄一息的个人博客 - 博客文章 - 任霏的个人博客网站 Vibe Coding 实现本地模型 Token 自由 IntelliJ IDEA + LM Studio + LM Link + Continue - 博客文章 - 任霏的个人博客网站 1Password涨价后,别急着退订1Password,这个操作能帮你省25% - 博客文章 - 任霏的个人博客网站 我,吃饱了撑的注册了个域名,Cloudflare账号没了,不建议将域名放在Cloudflare - 博客文章 - 任霏的个人博客网站 临时邮箱:保护隐私与免骚扰的新方式 - 博客文章 - 任霏的个人博客网站 价值4100万美元SOL被盗SwissBorg在Solana上遭遇安全事件超200万枚ETH排队退出质押 - 博客文章 - 任霏的个人博客网站 注意 Web3 钱包遭遇 NPM 超大规模供应链攻击投毒事件 - 博客文章 - 任霏的个人博客网站 我受到以太坊ERC-20假代币地址投毒攻击记录一下大家谨防上当受骗 - 博客文章 - 任霏的个人博客网站 在2025年使用显卡 NVIDIA RTX 2080 Ti 挖矿收益记录和分析还能不能挖矿 - 博客文章 - 任霏的个人博客网站 分享我是如何成功戒烟的经验(包含失败的经验) - 博客文章 - 任霏的个人博客网站 在 OpenWRT 中配置 PassWall2 插件的教程记录 - 博客文章 - 任霏的个人博客网站 Office Professional Plus 2019 VL 版下载与 KMS 激活 - 博客文章 - 任霏的个人博客网站 最近几天我的 CDN 流量受到来自电信[山东烟台]、[江苏扬州]两地家庭宽带的攻击 - 博客文章 - 任霏的个人博客网站 自建AI服务器使用PVE配置显卡直通虚拟机安装驱动、CUDA和cuDNN运行LLM大模型进行AI炼丹 - 博客文章 - 任霏的个人博客网站 各代英特尔Intel芯片组主板适配兼容的CPU和DDR内存数据统计 - 博客文章 - 任霏的个人博客网站 GitLab Global 国际站将在60天内删除中国大陆、香港、澳门地区的账号 - 博客文章 - 任霏的个人博客网站 Github Copilot Free 开放免费版所有人均可使用 OpenAI GPT-4o、Anthropic Claude 3.5 AI 代码生成服务 - 博客文章 - 任霏的个人博客网站 Cloudflare 更新了订阅协议明确禁止优选IP和搭建梯子的行为 - 博客文章 - 任霏的个人博客网站 Linux(systemd)手动离线安装二进制(binary)MairaDB数据库指定版本 - 博客文章 - 任霏的个人博客网站 流程引擎 Flowable/Activiti 无法启动报错:liquibase - Waiting for changelog lock.... - 博客文章 - 任霏的个人博客网站 Spring Boot 全局异常捕获 ControllerAdvice 无法捕获 过滤器(Filter)和拦截器(Interceptor)中的异常 - 博客文章 - 任霏的个人博客网站 Freenom 收回了全部免费域名(.tk/.cf/.gq/.ga/.ml) - 博客文章 - 任霏的个人博客网站 Alibaba Druid 数据库连接池 takeLast() AQS 死锁导致程序无响应 - 博客文章 - 任霏的个人博客网站 你的网站加入 HSTS preload 预加载列表了吗 - 博客文章 - 任霏的个人博客网站 我的博客网站接入使用 Cloudflare 的架构分享 - 博客文章 - 任霏的个人博客网站 在 Ubuntu 上的 Nginx 高并发配置实践 - 博客文章 - 任霏的个人博客网站 技术分析黑客敲诈勒索站长的新手法百度对此也无能为力 - 博客文章 - 任霏的个人博客网站 百度站长平台快速收录权限和sitemap提交权限被全部收回 - 博客文章 - 任霏的个人博客网站 极狐 GitLab 免费时代结束不升级付费账号将禁止登陆 - 博客文章 - 任霏的个人博客网站 免费.ml域名10年委托合同到期被马里共和国收回域名经营权 - 博客文章 - 任霏的个人博客网站
Spring Cloud 微服务入门教程(八):Spring Cloud Zuul 服务...
任霏 · 2020-02-29 · via 任霏博客

Spring Cloud 微服务入门教程(一):微服务介绍 Spring Cloud 微服务入门教程(二):服务注册与发现-Eureka Spring Cloud 微服务入门教程(三):微服务的注册 Spring Cloud 微服务入门教程(四):微服务间的调用消费-FeignClient Spring Cloud 微服务入门教程(五):统一配置中心-ConfigService Spring Cloud 微服务入门教程(六):Spring Cloud BUS 消息总线实现配置中心动态更新配置文件 Spring Cloud 微服务入门教程(七):Spring Cloud Stream 消息队驱动式的微服务 Spring Cloud 微服务入门教程(八):Spring Cloud Zuul 服务网关动态路由和Cookie头信息传递和跨域 Spring Cloud 微服务入门教程(九):网关 Zuul 整合 Swagger2 实现自动生成 RESTful API 文档 Spring Cloud 微服务入门教程(十):Spring Cloud Hystrix 服务熔断和服务降级 Spring Cloud 微服务入门教程(十一):Spring Cloud Sleuth zipkin 服务追踪链路监控 Spring Cloud 微服务入门教程(十二):Spring Cloud Docker 容器化部署

代码 将在https://github.com/NeilRen/SpringCloudDemo进行分享,按不同的分支分享不同的章节代码,Master分支就是最后所有的内容合集。本章节代码在:https://github.com/NeilRen/SpringCloudDemo/tree/feature/spring-cloud-zuul

原创 本篇文章是原创文章,作者:任霏,转载请注明作者和出处

上一节我们讲了微服务只间通过消息队列实现异步通讯,本节将介绍微服务中的网关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 sensitiveHeaders = new LinkedHashSet(Arrays.asList(“Cookie”, “Set-Cookie”, “Authorization”));,如果你的头信息不是这三个,可以自己在配置文件中自定义。ignored-patterns的意思是忽略这些地址不做转发。

网关Zuul的核心其实就是一堆过滤器,所以在网关这里会写很多过滤器,由于有点多,我直接上一个表格:

类型顺序过滤器功能
pre-3ServletDetectionFilter标记处理 Servlet 的类型
pre-2Servlet30WrapperFilter包装 HttpServletRequest 请求
pre-1FormBodyWrapperFilter包装请求体
route1DebugFilter标记调试标志
route5PreDecorationFilter处理请求上下文供后续使用
route10RibbonRoutingFilterserviceId
route100SimpleHostRoutingFilterurl 请求转发
route500SendForwardFilterforward 请求转发
post0SendErrorFilter处理有错误的请求响应
post1000SendResponseFilter处理正常的请求响应

我们去继承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);
	    }
	}

代码中已经有了注释,就不再啰嗦了,一个基本的网关就搭建好了。