【微服务全家桶】-实用篇-1-SpringCloud
1 导学
1.1 微服务定义
微服务是一种经过良好架构设计的分布式架构方案
微服务特征:
(1)单一职责(2)面向服务(3)自治:团队独立,技术独立,数据独立(4)隔离性强
1.2 微服务技术对比
1.3 认识微服务
SpringCloud和SpringBoot需要兼容
1.4 服务拆分注意事项
1.5 服务远程调用Demo-基于RestTemplate
(1)注册RestTemplate
在order-service中的OrderApplication中注册RestTemplate
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
(2)在Service中注入RestTemplate
(3)调用其方法,GET用getForObject,POST用postForObject,并封装
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用RestTemplate发起http请求,查询用户
String url = "http://userservice/user/" + order.getUserId();
User user= restTemplate.getForObject(url, User.class);
//3.封装user到order中
order.setUser(user);
// 4.返回
return order;
}
}
2 Eureka
2.1 提供者与消费者
2.2 Eureka基本原理
2.3 Eureka的实现
2.3.1 搭建注册中心
(1)引入依赖
引入spring-cloud-starter-netflix-eureka-server的依赖,要修改eureka-server模块的pom中maven的版本,降到8,JDK版本1.8
(2)编写启动类
编写启动类EurekaApplication,添加注解***@EnableEurekaServer和@SpringBootApplication***
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run( EurekaApplication.class, args );
}
}
(3)添加application.yml文件
server:
port: 10086
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka/
(4)启动SpringBoot,打开10086端口
注册到Eureka中的示例,UP表示正常,后面接ip地址
2.3.2 服务注册
将user-service、order-service服务注册到eureka-server中,以order-service为例
(1)在user-service引入依赖
在user-service引入spring-cloud-starter-netflix-eureka-client的依赖
(2)配置application.yml文件
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: 123sjbsjb
driver-class-name: com.mysql.cj.jdbc.Driver
application:
name: orderservice
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka/
(3)启动多个orderApplication类,并添加端口
添加-Dserver.port=8082,打开Eureka显示注册成功
2.3.3 服务发现
服务拉取事基于服务名称获取服务列表,然后对服务列表做负载均衡。例子采用order-service完成服务拉取。
(1)修改OrderService的代码
修改OrderService的代码,用服务名替换ip和端口(要与application.yml的服务名称一致)
String url = "http://localhost:8081/user/" + order.getUserId();
User user= restTemplate.getForObject(url, User.class);
改为
String url = "http://user-service/user/" + order.getUserId();
User user= restTemplate.getForObject(url, User.class);
(2)在order-service的启动类添加负载均衡的注解
在order-service的启动类OrderApplication中的RestTemplate添加负载均衡的注解,负载均衡注解***@LoadBalanced***
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
(3)启动spring
启动spring,依次访问localhost:8080/order/101和localhost:8080/order/102
发现已经实现负载均衡
3 Ribbon 负载均衡
3.1 负载均衡流程
3.2 负载均衡策略
3.3 修改负载均衡策略
3.3.1 定义一个新的IRule
在order-service中的OrderApplication中定义一个新的IRule,这是针对全局的设置
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients(defaultConfiguration = FeginClientConfiguration.class)
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public IRule randomRule() {
return new RandomRule();
}
}
3.3.2 在配置文件中修改规则
在order-service的application.yml中,添加新的规则,只针对某个微服务而言。
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
3.4 饥饿加载
ribbon默认进行懒加载,第一次访问时才会创建LoadBalanceClient。而修改为饥饿加载则会在项目启动时创建,降低第一次访问的耗时
ribbon:
eager-load:
enabled: true
clients: userservice
如果有多个clients,-xxservice
ribbon:
eager-load:
enabled: true
clients:
- userservice
- xxservice
4 Nacos注册中心
4.1 认识Nacos
Nacos是阿里巴巴的产品,现在是SpringCloud产品的一个组件,比Eureka功能更加丰富
4.1.1 启动nacos
在bin目录下打开cmd,输入命令
startup.cmd -m standalone
点击console的地址,ctrl+单击
账号密码均为nacos,成功进入nacos管理后台
4.2 Nacos注册中心
4.2.1 注册服务到Nacos
(1)在父工程中添加依赖
在cloud-demo的父工程中添加spring-cloud-alibaba的管理依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
(2)注释依赖
注释掉order-service和user-service原有的eureka依赖
(3)添加客户端依赖
为order-service和user-service添加nacos的客户端依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
(4)修改yml文件
修改order-service和user-service的yml文件
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user
username: root
password: 123sjbsjb
driver-class-name: com.mysql.cj.jdbc.Driver
application:
name: userservice
cloud:
nacos:
server-addr: localhost:8848
(5)启动nacos
startup.cmd -m standalone
点击服务管理-》服务列表
4.3 Nacos服务分级存储模型
4.3.1 配置nacos集群
(1)修改application.yml
为user-service修改application.yml
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ #集群名称 杭州
启动实例后修改cluster-name,可以实现多集群cluster-name: SH
(2)nacos管理
(3)为order-service配置
要求order-service优先调用本地的user-service
修改order-service的application.yml,与(2)同理
第一次运行发现各个实例轮询访问,并未实现优先调用,是因为ribbon负载均衡的调用策略是轮询。因此要在order-service中设置负载均衡的IRule为NacosRule,这个规则会优选寻找属于同一集群的服务。
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
改为
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
重启order-service发现没有使用上海集群
如果停掉杭州集群,只留上海集群,order-service则会爆出警告
4.3.2 为集群配置权重
点击编辑,可以修改其权重
当权重为0时代表不会访问该实例。这样就可以实现平滑上线。灰度发布,升级迭代后的产品权重值设的较小,放入少量用户测试。
4.4 Nacos环境隔离
默认都在命名空间public下,group为默认分组
点击命名空间,创建新的命名空间
生成唯一的uuid命名空间ID,返回服务列表,出现dev的命名空间
如果想将服务放到命名空间中,则需要在对应服务的application.yml中添加namespace
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ #集群名称 杭州
namespace: bcc7eea2-5231-4b3a-9250-4afde546ca27
现在user-service和order-service已经是两个世界的人,重启order-service。如果想让两个服务能相互访问,则需要放在同一个namespace下。
4.5 Nacos注册中心细节
4.5.1 设置临时实例和非临时实例
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: SH #集群名称 杭州
ephemeral: false #设置非临时实例
即使停掉order-service,nacos也不会剔除
4.6 Nacos与Eureka的对比
5 Nacos 配置管理
5.1 Nacos实现配置管理
发布后
5.2 微服务配置拉取
5.2.1 引入Nacos配置管理客户端依赖
为userservice添加配置管理依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
5.2.2 创建bootstrap.yml文件
在userservice的resource中创建bootstrap.yml
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
删除application.yml中重复的配置
尝试读取配置
在UserController中添加导入配置信息
@Slf4j
@RestController
@RequestMapping("/user")
//RefreshScope
public class UserController {
@Autowired
private UserService userService;
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("/now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
}
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
}
注意namespace的位置,bootstrap的命名空间要与userservice一致
5.3 实现配置的热更新
Nacos实现热更新有两种方式,配置注入不同,使用的注解也不同
5.3.1 方式一,注解***@RefreshScope***
在@Value注入的变量所在的类中加上注解***@RefreshScope***
5.3.2 方式二,使用***@ConfigurationProperties***(推荐)
(1)创建配置类PatternProperties
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}
(2)注入PatternProperties
在UserController注入PatternProperties,这里不需要@RefreshScope
@Slf4j
@RestController
@RequestMapping("/user")
//RefreshScope
public class UserController {
@Autowired
private UserService userService;
// @Value("${pattern.dateformat}")
// private String dateformat;
@Autowired
private PatternProperties patternProperties;
@GetMapping("/prop")
public PatternProperties prop() {
return patternProperties;
}
@GetMapping("/now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
}
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
}
5.4 多环境配置共享
5.4.1 针对单环境
在nacos中添加userservice.yaml
在配置类中读取envSharedValue
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
private String envSharedValue;
}
在UserController中读取
@GetMapping("/prop")
public PatternProperties prop() {
return patternProperties;
}
5.4.2 修改实例环境
重启服务,8081可以读取到dev的环境变量,而8082则读取不到
5.4.3 配置优先级
5.5 Nacos 集群搭建
5.5.1 搭建数据库,初始化数据库表结构
5.5.2 下载Nacos,配置Nacos
(1)修改conf下cluster.conf.example改成cluster.conf
(2)在cluster.conf下#example下添加ip和端口
127.0.0.1:8845
127.0.0.1.8846
127.0.0.1.8847
(3)修改application.properties下文件,添加数据库配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123sjbsjb
(4)复制nacos文件三份,分别命名1/2/3,并分别修改各自application.properties,修改server.port为8845/8846/8847
(5)分别启动nacos节点 startup.cmd
(6)nginx做反向代理,修改nginx下conf/nginx.conf文件,加入nginx下http中,将nacos的server等监听端口加入
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
(7)修改userservice下的application.yml或bootstraps.yml文件
spring:
cloud:
nacos:
server-addr: localhost:80 # Nacos地址
6 Http客户端Feign
Feign都是基于调用者的,即orderservice
6.1 RestTemplate调用
代码可读性差,编程体验不统一
参数复杂,URL难以维护
6.2 定义和使用Feign客户端
6.2.1在orderservice中引入依赖
<!-- feign http配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
6.2.2 开启Feign功能,@EnableFeignClients
在orderservice的启动类中添加注释,开启Feign功能,@EnableFeignClients
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
6.2.3 编写Feign的客户端,@FeignClient
在orderservice中创建clients定义接口UserClient,@FeignClient
@FeignClient(value = "userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
6.2.4 改造OrderService
将原有的使用url调用的restTemplate改造
public class OrderService {
@Autowired
private OrderMapper orderMapper;
/*@Autowired
private RestTemplate restTemplate;*/
@Autowired
private UserClient userClient;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
/*//2.利用RestTemplate发起http请求,查询用户
String url = "http://userservice/user/" + order.getUserId();
User user= restTemplate.getForObject(url, User.class);*/
//2.利用Feign发起http请求,查询用户
User user = userClient.findById(order.getUserId());
//3.封装user到order中
order.setUser(user);
// 4.返回
return order;
}
}
Feign包含ribbon,自动对客户端进行负载均衡
6.3 Feign的自定义配置
6.3.1 方式一 配置文件方式
修改orderservice的application.yml文件
(1)全局生效
feign:
client:
config:
default:
loggerLevel: FULL
(2)局部生效
-使用default就默认全局,userservice指定服务名就针对某个微服务
feign:
client:
config:
userservice:
loggerLevel: FULL
6.3.2 Java代码配置方式
(1)先声明一个Bean
public class FeginClientConfiguration {
@Bean
public Logger.Level loglevel() {
return Logger.Level.BASIC;
}
}
(2)全局配置,@EnableFeignClients
如果是全局配置,则把他放到orderservice的启动类@EnableFeignClients这个注解中
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
(3)局部配置,@FeignClient
如果是局部配置,则把他放到自定义接口UserClient的@FeignClient注解中
@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)
6.4 Feign性能调优
6.4.1 Feign连接池配置
Feign连接池配置,为Feign添加HttpClient支持
(1)引入HttpClient依赖
<!-- feign的httpclient的连接池配置-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
(2)配置连接池
feign:
client:
config:
default: #default全局配置
loggerLevel: BASIC #日志级别,BASIC基本请求和相应信息
httpclient:
enabled: true # 支持HttpClient的开关
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 单个路径的最大连接数
6.5 Feign的最佳实践
6.5.1 方式一 继承
给消费者的FeignClient和提供者的Controller定义统一的父接口作为标准
6.5.2 方式二 抽取
将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放在这个模块中,提供给所有消费者使用
6.5.3 方式二 实现
步骤
(1)创建一个module,命名feign-api,然后引入feign的starter依赖
<dependencies>
<!-- feign http配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- feign的httpclient的连接池配置-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
</dependencies>
(2)将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
(3)在order-service中引入feign-api的依赖
<!--引入fegin-api依赖 -->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>feign-api</artifactId>
<version>1.0</version>
</dependency>
(4)修改order-service中所有与上述三个组件有关的import部分,改成导入feign-api中的包
(5)重启测试
解决报错
发现orderservice报错,找不到UserClient
分析原因,spring的自动配置只能扫描当前启动类下的包,因此OrderApplication扫描不到feign-api下的UserClient
当定义的FeignClient不在SpringBootApplication的扫描包的范围时,这些FeignClient无法使用,提供两种解决方式
(1)指定FeignClient所在包
注解@EnableFeignClients指定参数basePackages包所在位置
@EnableFeignClients(defaultConfiguration = FeginClientConfiguration.class,basePackages = "cn.itcast.feignapi.clients")
(2)指定FeignClient的字节码
@EnableFeignClients(defaultConfiguration = FeginClientConfiguration.class,client)
多个字节码用{}进行包裹
7 Gateway 网关
7.1 认识网关
SpringCloud中网关的实现包括两种:gateway(响应式编程)和zuul(阻塞式)
7.2 搭建网关
7.2.1 创建模块,引入依赖,创建启动类
创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖
<dependencies>
<!-- Nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!-- Spring Cloud Gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
添加启动类GatewayApplication
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
// 启动SpringBoot应用
SpringApplication.run(GatewayApplication.class, args);
}
}
7.2.2 编写路由配置及naocs地址
路由配置包括:路由id,路由目标uri,路由断言predicates,路由过滤器filters
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
7.2.3 服务细节
7.3 断言工厂
配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断条件
7.4 路由过滤器GatewayFilter
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理
7.4.1 路由过滤器
添加请求头
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
filters:
- AddRequestHeader=Truth, Itcast is freaking awesome! # 这个是添加请求头,可以添加多个
在userservice中验证,打开userservice的controller,添加参数
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,
@RequestHeader(value="Truth",required = false) String truth) {
System.out.println("truth = " + truth);
return userService.queryById(id);
}
重启userservice和gateway
7.4.2 默认过滤器
default-filters: 默认过滤器
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: # 这个是默认过滤器,所有的路由都会经过这个过滤器
- AddRequestHeader=Truth,Itcast is freaking awesome! # 这个是添加请求头,可以添加多个
7.4.3 全局过滤器
全局过滤器GlobalFilter的作用也是处理一切进入网关的请求和微最务响应,与GatewayFilter的作用一样。
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。
定义方式是需要实现GlobalFilter接口
//@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
//2.获取参数中的authorization参数
String auth = params.getFirst("authorization");
//3.判断authorization是否有效
if("admin".equals(auth)){
//4.有效,放行
return chain.filter(exchange);
}
//5.如果无效,拦截
//5.1.设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
@Component注解把AuthorizeFilter注入到Spring中作为一个Bean对象,AuthorizeFilter类实现GlobalFilter, Ordered两个接口及其方法。
GlobalFilter其方法 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
,exchange.getRequest()
获取请求头,request.getQueryParams()
获取请求参数,
params.getFirst("authorization")
获取第一个匹配key=authorization的value,
chain.filter(exchange)
是放行到下一个过滤器链,如果拦截到了,先设置状态码401HttpStatus.UNAUTHORIZED
,exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
。再进行拦截exchange.getResponse().setComplete()
Ordered也可以通过注解来设置过滤器顺序@Order(-1)
也可以通过重写方法来实现。
重启spring
地址中‘?’之后的部分就是通过GET发送的请求数据,各个数据之间用‘&’符号隔开。
没有authorization则拒绝访问401
7.5 过滤器顺序
7.6 跨域问题处理
跨域:域名不一致就是跨域,主要包括:
域名不同:www.taobao.com和www.taobao.org和www.jd.com和miaosha.jd.com
域名相同,端口不同:localhost:8080和localhost:8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS
网关处理跨域问题也是采用CORS方案
7.6.1 跨域问题测试
安装live-server npm install live-server -g
将index.html启动起来,live-server --port=8090
,显示CORS禁止跨域访问
将配置导入gateway的application.yml中
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
# default-filters: # 这个是全局过滤器,所有的路由都会经过这个过滤器
# - AddRequestHeader=Truth,Itcast is freaking awesome! # 这个是添加请求头,可以添加多个
globalcors: # =================》全局的跨域处理《==========================
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
重启
注意浏览器的url为http://127.0.0.1:8090,需要浏览器的url和配置中allowedOrigins的一致!