1. nacos的集群模式
1.1 分析
1.2 实现
1. 修改conf/application.properties文件
2.创建数据库nacos并导入sql语句
3. 修改cluster.conf.example文件
#it is ip
#example 注意:把虚拟机的ip关闭
ip:端口号
ip:端口号
ip:端口号
4. 修改bin文件中的startup.cmd配置文件为集群
5. 在设置中关闭VM网络
6. 启动三台nacos服务
7. 微服务连接
2. Gateway网关
2.1 概述
2.2 常用的网关组件
- nginx+lua
- Kong
- Zuul 1.0(慢 servlet 2.0)zuul2.0没出来
- Spring Cloud Gateway
2.3 概述gateway网关
- 优点
- 性能强劲:是第一代网关Zuul的1.6倍
- 功能强大:内置了很多实用的功能,例如转发、监控、限流等
- 设计优雅,容易扩展
- 缺点
- 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
- 不能将其部署在Tomcat、Jetty等Servlet容器里,只能达成jar包执行web.jar
- 需要springboot 2.0以及上的版本,才支持
2.4 使用gateway网关-转发地址写死
1. 创建网关微服务
2. 添加依赖
<dependencies>
<!--如果引入了gateway的依赖,不能再引用spring-boot-starter-web,否则会报错。因为web内置了tomcat服务器,而gateway内置netty服务器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
3. 创建yml配置文件,配置网关
server:
port: 88
spring:
application:
name: zmq-gateway
#配置路由转发
cloud:
gateway:
routes:
- id: zmq-product #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成
uri: http://localhost:8001 #表示路由真实转发的微服务的地址
predicates:
- Path=/product/**
- id: zmq-order
uri: http://localhost:9001
predicates:
- Path=/order/**
4. 在com.zmq
包下创建主启动类
@SpringBootApplication
public class Gateway {
public static void main(String[] args) {
SpringApplication.run(Gateway.class,args);
}
}
5. 测试
- 若资源路径中的断言路径写错,报错如下图所示
- 若资源路径中的后面路径写错,报错如下图所示
2.5 增强版—转发地址解耦
实现步骤
1. 引入nacos依赖
<!--nacos依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2. 修改配置文件
server:
port: 88
spring:
application:
name: zmq-gateway
#配置路由转发
cloud:
gateway:
routes:
- id: zmq-product #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成
uri: lb://zmq-product #表示路由真实转发的微服务的地址
predicates:
- Path=/product/**
- id: zmq-order
uri: lb://zmq-order
predicates:
- Path=/order/**
#nacos的配置
nacos:
discovery:
server-addr: localhost:8848
register-enabled: false #是否注册到nacos上
2.6 简洁版-自动定位模式
实现步骤
1. 修改配置文件
- 删除关于转发路径的配置
- 添加开启gateway的定位功能的配置
server:
port: 88
spring:
application:
name: zmq-gateway
#nacos的配置
nacos:
discovery:
server-addr: localhost:8848
# register-enabled: false #是否注册到nacos上
cloud:
gateway:
discovery:
locator:
enabled: true #开启gateway的定位功能
2. 在访问资源时,需要在原本的路径上加上微服务的名称
3. Gateway用于认证校验
实现步骤
1. 创建登录过滤器类
//在网关中定义的过滤器,只能在网关中使用
@Component
public class LoginFilter implements GlobalFilter, Ordered {
@Autowired
private UrlVo urlVo;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取request对象
ServerHttpRequest request = exchange.getRequest();
//获取response对象
ServerHttpResponse response = exchange.getResponse();
//获取上述两个对象是为了便于获取path和token
//1.获取请求路径
String path = request.getPath().toString();
System.out.println(path);
//对获取到的请求路径字符串进行截取,获取符合的地址路径【断言+资源路径】,便于后面比较判断是否放行
path = path.substring(1);
System.out.println(path);
path=path.substring(path.indexOf("/"));//从第一个/的下标开始截取,indexOf,获取指定字符的索引
System.out.println(path);
//2.判断该路径是否属于放行路径——类似于白名单
if(urlVo.getWhite().contains(path)){
//放行
return chain.filter(exchange);
}
//3. 判断用户是否登录
String token = request.getHeaders().getFirst("token");
//4. 校验token是否为空,以及是否合法
if(StringUtils.hasText(token)&&"admin".equals(token)){
//放行
return chain.filter(exchange);
}
//4.2 封装返回数据
Map<String,Object> map=new HashMap<>();
map.put("msg","未登录");
map.put("code",501);
//4.3 JSON转换
byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
// 4.4 调用bufferFactory方法,生成DataBuffer对象
DataBuffer wrap = response.bufferFactory().wrap(bytes);
//5. 调用Mono中的just方法,返回要写给前端的JSON数据
return response.writeWith(Mono.just(wrap));
}
//优先级,值越小优先级越高
@Override
public int getOrder() {
return 0;
}
}
-
配置文件
url: white: - /login - /register - /sendMsg
-
UrlVo类
@Component @ConfigurationProperties(prefix="url") @Data @AllArgsConstructor @NoArgsConstructor public class UrlVo { private List<String> white; }
-
测试
在postman中进行测试,此时测试时需要带上token
此时,该程序并没有连接关于用户登录的数据库,仅将token写死来测试
- token不正确
- token正确
测试时需要在原有的路径上面加上微服务的名称,因为使用的是自动定位模式
4. Gateway解决跨域问题【2种】
在不做跨域解决时,点击按钮,会报错,出现跨域问题
4.1 通过配置类
package com.zmq.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 允许认证
config.addAllowedOrigin("*"); // 允许任何源
config.addAllowedHeader("*"); // 允许任何头
config.addAllowedMethod("*"); // 允许任何方法
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
-
测试时,需要手动加上token——token值为admin
4.2 通过配置文件
配置类和配置文件只能择其一
在配置文件中添加相关配置
cloud:
gateway:
discovery:
locator:
enabled: true #开启gateway的定位功能
globalcors: #全局的跨域处理
add-to-simple-url-handler-mapping: true #解决浏览器向服务器发options请求被拦截问题,这样网关就不拦截这个请求了
cors-configurations:
'[/**]': #拦截一切请求
allowedOrigins: "*" #允许任意域的跨域请求
allowedMethods: "*" #允许的跨域ajax的请求方式
allowedHeaders: "*" #允许在请求中携带的头信息,这里是允许所有的请求头
allowCredentials: true #是否允许携带cookie
maxAge: 360000 #这次跨域检测的有效期