@
目录
前言
项目版本
网关访问
鉴权配置
限流配置
前言
由于项目采用了微服务架构, 业务功能都在相应各自的模块中, 每个业务模块都是以独立的项目运行着, 对外提供各自的服务接口, 如没有类似网关之类组件的话, 相应的鉴权, 限流等功能实现起来不能够进行统一的配置和管理, 有了网关后一切都是如此的优雅. 刚好新项目中采用了 SpringCloud Gateway 组件作为网关, 就记录下项目中常用的配置吧.
项目版本
- spring-boot-version:2.2.5.RELEASE
- spring-cloud.version:Hoxton.SR3
网关访问
示例项目还是延续 SpringCloud 系列原先的示例代码, 引入网关仅仅只需新增 spring-cloud-gateway 项目即可.
核心 pom.xml(详细信息查看示例源码, 在文章末尾)
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
Bootstrap.YAML
- server:
- port: 9005
- spring:
- application:
- name: springcloud-gateway-service
- cloud:
- config:
- discovery:
- enabled: true
- service-id: config-server
- profile: dev
- label: master
- gateway:
- enabled: true #开启网关
- discovery:
- locator:
- enabled: true #开启自动路由, 以服务 id 建立路由, 服务 id 默认大写
- lower-case-service-id: true #服务 id 设置为小写
- eureka:
- client:
- service-url:
- defaultZone: http://localhost:9003/eureka/
ApiGatewayApplication.java
- @EnableDiscoveryClient
- @SpringBootApplication
- public class ApiGatewayApplication {
- public static void main(String[] args) {
- SpringApplication.run(ApiGatewayApplication.class, args);
- }
- }
访问原先 spring-cloud-system-server 模块对外提供的接口
http://localhost:9004/web/system/getEnvName
通过网关进行访问
请求能正常返回, 那就说明网关组件已集成进来了, 是不是很简单呢, 一行配置项就搞定了, 便于展现这边采用 properties 配置方式说明
spring.cloud.gateway.discovery.locator.enabled=true
到此网关的基础配置应用已完成, 通过网关访问的请求路径格式如下
http:// 网关地址: 网关端口 / 各自服务 id / 各自服务对外提供的 URL 访问
鉴权配置
这边将 spring-cloud-system-server 模块引入 spring security 安全认证组件, 上代码.
pom.xml
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
- application.properties
- spring.security.user.name=test
- spring.security.user.password=123456
服务模块调整完后, 重新启动该模块, 访问对外请求接口, 出现认证登录界面说明配置成功.
http://localhost:9004/Web/system/getEnvName
输入上述配置项中配置的用户名和密码后, 接口请求返回正常.
请求网关地址, 访问服务接口按下回车键时会跳转至服务项目认证页面, 如下
接下来对网关模块进行相应调整
Bootstrap.YAML
- spring:
- application:
- name: springcloud-gateway-service
- security:
- user:
- name: test
- password: 123456
新增安全认证过滤类
SecurityBasicAuthorizationFilter.java
- @Component
- public class SecurityBasicAuthorizationFilter implements GlobalFilter, Ordered {
- @Value("${spring.security.user.name}")
- private String username;
- @Value("${spring.security.user.password}")
- private String password;
- public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
- String auth = username.concat(":").concat(password);
- String encodedAuth = new sun.misc.BASE64Encoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
- String authHeader = "Basic" +encodedAuth;
- //headers 中增加授权信息
- ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().header("Authorization", authHeader).build();
- ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
- return chain.filter(build);
- }
- /**
- * 优先级
- * 数字越大优先级越低
- * @return
- */
- public int getOrder() {
- return -1;
- }
- }
重启网关项目, 重新访问服务地址, 返回正常数据. 这边说明下在测试时最好新开一个无痕窗口或者清理浏览器缓存后再进行测试, 不然因会话缓存会导致安全认证没有生效的假象.
限流配置
SpringCloud Gateway 自带限流功能, 但是基于 Redis, 这边简单演示下, 项目中没有使用而是使用了阿里开源的 sentinel, 后续将介绍下集成 sentinel 组件.
pom.xml
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis-reactive</artifactId>
- </dependency>
Bootstrap.YAML
- spring:
- cloud:
- gateway:
- enabled: true #开启网关
- discovery:
- locator:
- enabled: true #开启自动路由, 以服务 id 建立路由, 服务 id 默认大写
- lower-case-service-id: true #服务 id 设置为小写
- routes:
- - id: baidu_route
- uri: https://www.baidu.com/
- predicates:
- - Path=/baidu/**
- filters:
- - name: RequestRateLimiter
- args:
- key-resolver: "#{@apiKeyResolver}"
- Redis-rate-limiter.replenishRate: 1 #允许每秒处理多少个请求
- Redis-rate-limiter.burstCapacity: 5 #允许在一秒钟内完成的最大请求数
- Redis:
- host: 192.168.28.142
- pool: 6379
- password: password
- database: 1
RequestRateLimiterConfig.java
- @Configuration
- public class RequestRateLimiterConfig {
- @Bean
- @Primary
- public KeyResolver apiKeyResolver() {
- //URL 限流, 超出限流返回 429 状态
- return exchange -> Mono.just(exchange.getRequest().getPath().toString());
- }
- }
重新启动网关项目, 访问如下请求地址, 会请求跳转至百度首页, 目前配置项配置为 1s 内请求数 5 次, 超过 5 次就会触发限流, 返回 429 状态码, 多次刷新就会出现如下页面
http://localhost:9005/baidu/test
通过 monitor 命令实时查看 Redis 信息
本次网关项目目录结构
同系列文章
1-SpringCloud 系列之配置中心 (Config) 使用说明
2-SpringCloud 系列之服务注册发现 (Eureka) 应用篇
示例源码 https://gitee.com/wuyubin/SpringCloudDemo
来源: https://www.cnblogs.com/chinaWu/p/12731796.html