从零搭建Spring Cloud Gateway网关(一)
2020-03-18 18:45
501 查看
# 新建Spring Boot项目
怎么新建Spring Boot项目这里不再具体赘述,不会的可以翻看下之前的博客或者直接百度。这里直接贴出对应的pom文件。
pom依赖如下:
```xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.5.RELEASE
com.lifengdi
gateway
0.0.1-SNAPSHOT
gateway
Demo project for Spring Boot
1.8
Hoxton.SR3
org.springframework.cloud
spring-cloud-starter-gateway
org.projectlombok
lombok
1.18.12
true
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
org.springframework.boot
spring-boot-starter-actuator
org.apache.commons
commons-pool2
commons-io
commons-io
2.5
compile
com.alibaba
fastjson
1.2.58
org.springframework.boot
spring-boot-starter-mail
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
```
由于是网关项目,所以不需要`spring-boot-starter-web`相关的依赖。
配置文件如下:
```yaml
server:
port: 8080
spring:
application:
name: spring-cloud-gateway-demo
cloud:
gateway:
discovery:
locator:
enabled: true #启用路由访问
routes:
- id: path_route
# 指定域名
uri: http://localhost:8081
predicates:
- Path=/jar/**
filters:
# 熔断配置
- name: Hystrix
args:
name: default
fallbackUri: forward:/fallback
- id: path_route2
# 指定域名
uri: http://localhost:8082
predicates:
- Path=/war/**
filters:
# 熔断配置
- name: Hystrix
args:
name: hystrix1
fallbackUri: forward:/fallback
mvc:
throw-exception-if-no-handler-found: true
# 默认熔断超时时间30s
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
hystrix1:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
```
# 熔断(接口或者项目)
熔断相关jar包如下:
```xml
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
```
默认的熔断回调接口:
```java
package com.lifengdi.gateway.hystrix;
import com.lifengdi.gateway.exception.BaseException;
import com.lifengdi.gateway.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: Li Fengdi
* @date: 2020-03-18 16:35
*/
@RestController
@Slf4j
public class DefaultHystrixController {
@RequestMapping("/fallback")
public ResponseResult fallback(){
log.error("触发熔断......");
return ResponseResult.fail(BaseException.DEFAULT_HYSTRIX.build());
}
}
```
具体配置文件说明如下:
```yaml
routes:
- id: path_route
# 指定域名
uri: http://localhost:8081
predicates:
- Path=/jar/**
filters:
# 熔断配置
- name: Hystrix
args:
name: default
fallbackUri: forward:/fallback
- id: path_route2
# 指定域名
uri: http://localhost:8082
predicates:
- Path=/war/**
filters:
# 熔断配置
- name: Hystrix
args:
name: hystrix1
fallbackUri: forward:/fallback
mvc:
throw-exception-if-no-handler-found: true
# 默认熔断超时时间30s
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
hystrix1:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
```
`default`、`hystrix1`为自定义的参数,可以配置多个熔断策略,不同的接口、服务可以单独配置对应的超时时间,不需要额外的进行开发,不过需要增加额外的配置文件。
# 全局session共享
依赖jar包:
```xml
org.springframework.boot
spring-boot-starter-data-redis-reactive
org.springframework.session
spring-session-data-redis
org.apache.commons
commons-pool2
org.springframework.boot
spring-boot-starter-security
```
相关yml配置:
```yaml
spring:
redis:
database: 0
host: localhost
port: 6379
password: 123456
lettuce:
pool:
max-active: 300
max-idle: 8
max-wait: -1ms
min-idle: 0
session:
store-type: redis
```
`spring.session.store-type`Spring默认就是redis实现的,也有其他的,配置不同罢了。
增加代码如下:
权限相关,这里默认全部放行:
```java
package com.lifengdi.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfig {
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity serverHttpSecurity)
throws Exception {
serverHttpSecurity
.csrf().disable()
.authorizeExchange().pathMatchers("/**").permitAll()
.anyExchange()
.authenticated();
return serverHttpSecurity.build();
}
}
```
session相关:
```java
package com.lifengdi.gateway.config;
import com.lifengdi.gateway.resolver.MyCookieWebSessionIdResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseCookie;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
import org.springframework.web.server.session.CookieWebSessionIdResolver;
import org.springframework.web.server.session.WebSessionIdResolver;
import java.util.function.Consumer;
@Configuration
@EnableRedisWebSession(maxInactiveIntervalInSeconds = 10*60*60, redisNamespace = "my:spring:session")
public class WebSessionConfig {
@Bean
public WebSessionIdResolver webSessionIdResolver() {
CookieWebSessionIdResolver resolver = new MyCookieWebSessionIdResolver();
resolver.setCookieName("SESSIONID");
Consumer consumer = responseCookieBuilder -> {
responseCookieBuilder.path("/");
};
resolver.addCookieInitializer(consumer);
return resolver;
}
}
```
注意这里使用的是`@EnableRedisWebSession`注解,而不是`@EnableRedisHttpSession`,这个是和zuul不一样的地方。
用zuul做网关的时候,直接使用`@EnableRedisHttpSession`在配置里面就可以通过redis共享session信息
Spring同时提供了`@EnableRedisWebSession`来对WebFlux的支持。
值得一提的是这两个注解内部实现并不相同,需要自定义的配置也不一样。
这里自定义cookieName、path等是自定义了`webSessionIdResolver`来实现的,而不是`cookieSerializer`。如果使用`cookieSerializer`的话,对`@EnableRedisWebSession`来说是不起作用的。这个坑之前坑了好半天!
MyCookieWebSessionIdResolver代码如下:
```java
package com.lifengdi.gateway.resolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpCookie;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.session.CookieWebSessionIdResolver;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 自定义WebSessionId解析器,以兼容{@link org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession}
*
* 使用EnableRedisHttpSession时{@link DefaultCookieSerializer}中useBase64Encoding默认为true,将cookie中的sessionId使用base64 * 加密,但是如果使用{@link org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession},默认 * 的解析器没有将sessionId解密,导致获取不到正确的session *
* * @author: Li Fengdi * @date: 2020/3/16 15:41 */ @Slf4j public class MyCookieWebSessionIdResolver extends CookieWebSessionIdResolver { @Override public List resolveSessionIds(ServerWebExchange exchange) { MultiValueMap cookieMap = exchange.getRequest().getCookies(); List cookies = cookieMap.get(getCookieName()); if (cookies == null) { return Collections.emptyList(); } return cookies.stream().map(HttpCookie::getValue).map(this::base64Decode).collect(Collectors.toList()); } /** * base64解码 * * @param base64Value base64Value * @return 解码后的字符串 */ private String base64Decode(String base64Value) { try { byte[] decodedCookieBytes = Base64.getDecoder().decode(base64Value); return new String(decodedCookieBytes); } catch (Exception ex) { log.debug("Unable to Base64 decode value: " + base64Value); return null; } } } ``` 其实这段代码本就是参考了`cookieSerializer`中的代码来实现的。 > 如果指定了useBase64Encoding为false,即不加密sessionId,那么就不需要这一段代码了。 代码已上传到git上,需要的可以去看看。 git代码地址:[https://github.com/lifengdi/spring-cloud-gateway-demo](https://github.com/lifengdi/spring-cloud-gateway-demo) 原文地址:[https://www.lifengdi.com/archives/article/1776](https://www.lifengdi.com/archives/article/1776)相关文章推荐
- Android开发日记(1) android开发环境搭建(ubuntu)
- zookeeper搭建
- 解决在DHCP环境下私自指定IP和私自搭建DHCP服务器的方法
- 基于Linux-RHEL5——搭建LAMP平台以及Postfix邮件系统(一)
- 超简单的iOS主流MVC APP框架搭建
- nginx php环境搭建
- 使用Eclipse搭建Python开发环境
- CentOS下基于hadoop0.20.2搭建hbase0.90.4操作实录
- 用qemu搭建CentOS 6 for colinux虚拟系统――《Windows下搭建CentOS 6开发环境之一》
- phoneGap-Android开发环境搭建
- Spring 4 + Hibernate 4 搭建web项目
- Windows服务器配置与管理-------DHCP服务器搭建与管理
- Centos搭建xwiki+mysql+tomcat
- flume-ng单节点搭建
- HBase 分布式安装搭建/独立Zookeeper集群
- eclipse中SSH三大框架环境搭建<二>
- TensorFlow识别复杂验证码以及搭建生产环境(5)—— 设计神经网络
- redmine一键搭建
- 数据切分——Atlas读写分离Mysql集群的搭建
- maven+spring boot搭建简单微服务