Nacos配置管理
Nacos除了做注册中心,还能做配置管理来使用。
统一配置管理
在nacos中添加配置文件的操作
在nacos配置列表中添加配置信息 配置格式支持yaml和properties格式
从微服务中拉取配置
1.引入nacos-config依赖
2.添加bootstrap.yaml 会在application.yml之前加载 
3.将读取到的数据配置到自定义属性中
配置热更新有两种方式
1) @Value注入读取到数据 需要在此类上添加@RefreshScope注解
2)使用@ConfigurationProperties注解代替@Value注解
新建一个类 加上@ConfigurationProperties 类中定义要读取的属性变量, 使用@Autowired主动装配此类的对象 并用此对象调用成员属性 获取配置属性值。
配置共享
在添加配置信息是不指定环境,注册中心的微服务都可访问到此配置信息
获取配置信息的优先级 显示当前环境的 比如 userservice-dev 开发环境的微服务 首先会读取dev环境的配置文件 然后没有指定环境的共享配置文件 最后才是本地配置
Nacos集群
搭建数据库,初始化数据库表结构
安装nacos并配置
启动nacos集群(多个nacos启动器)
nginx反向代理 (对nacos集群进行统一管理)
Feign远程调用
代替之前restTeplate进行远程调用
原因 : 代码可读性差 参数复杂URL难以维护 不够优雅
Feign代替TestTemplate
1. 引入feign依赖
2. 在微服务启动类上添加@EnableFeignClients注解开启Feign的功能
3.编写Feign的客户端 FeignClient接口 接空中的抽象方法与要进行远程调用的微服务web层的功能保持一致,路径包含窄路径 在微服务业务层使用接口对象调用指定的方法 即可达到远程调用的效果
Feign的自定义配置
1.配置文件方式
feign.Logger.Level 修改日志级别
一般开发中使用FULL全注释
NONE:不记录任何日志信息,这是默认值。
BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据
2.Java代码方式
声明一个配置类: 声明指定的日志等级

@EnableFeignClients 配置在全局生效
@FeignClient 配置在指定微服务生效 (value=” “)
Feign使用优化
Feign底层发起http请求,依赖于其他的框架。
URLConnection:默认实现,不支持连接池
Apache HttpClient:支持连接池
OKHttp:支持连接池
提高性能主要手段是使用连接池 因此要替换默认的URLConnection
1.引入依赖 httpclient
2. 配置连接池 application.yml

Feign最佳实践
微服务进行远程调用会有许多重复的代码 可以进行抽取
1.继承方式
不够优雅
2.抽取方式
1)将feign当作一个单独的微服务 创建单独项目 引入feign依赖
声明UserClient接口 pojo类 和配置类
2) 在需要远程调用的微服务中引入feign项目依赖
3)修改开启Feign功能的注解扫描的包
@EnableFeignClients(basePackages = “cn.itcast.feign.clients”)
Gateway服务网关
对微服务访问入口进行统一管理
核心功能特性:
请求路由 对访问微服务的用户进行权限校验
权限控制 设置请求转发到哪个微服务中 存在多个微服务时 还需要做负载均衡
限流 请求流量太大时,控制放行
快速入门
创建gateway项目
引入geteway网管依赖 和naacos注册中心依赖
编写启动类 和配置文件

lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。
路由配置 routes
1. id : 唯一标识
2. uri:路由目标地址,http代表固定的 lb是负载均衡
3.断言 predicates :判断路由的规则
4.路由过滤器 filters: 请求或相应做处理 TODO
过滤器工厂
GatewayFileter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的相应做处理:
Spring提供了31种不同的路由过滤器工厂
| 名称 | 说明 |
|---|---|
| AddRequestHeader | 给当前请求添加一个请求头 |
| RemoveRequestHeader | 移除请求中的一个请求头 |
| AddResponseHeader | 给响应结果中添加一个响应头 |
| RemoveResponseHeader | 从响应结果中移除有一个响应头 |
| RequestRateLimiter | 限制请求的流量 |
请求头过滤器 AddRequestHeader
当前过滤器只在userservice微服务生效
spring:cloud:gateway:routes:- id: user-serviceuri: lb://userservicepredicates:- Path=/user/**filters: # 过滤器- AddRequestHeader=name, value # 添加请求头// 测试代码@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id,@RequestHeader(value = "Truth",required = false) String name) {System.out.println("请求头中携带的name = " + name);return userService.queryById(id);}
默认过滤器: dafault-filters: 对配置的所有路由生效
全局过滤器
与GatewayFilter不同的是,GlobalFilter的逻辑需要自己写代码实现:
登陆状态判断<br /> 权限校验<br /> 请求限流等
自定义全局过滤器
实现GlobalFilter接口 重写方法 进行逻辑功能实现
public interface GlobalFilter {
/**
* 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
*
* @param exchange 请求上下文,里面可以获取Request、Response等信息
* @param chain 用来把请求委托给下一个过滤器
* @return {@code Mono<Void>} 返回标示当前过滤器业务结束
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求参数
MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
// 2.获取authorization参数
String auth = params.getFirst("authorization");
// 3.校验
if ("admin".equals(auth)) {
// 放行
return chain.filter(exchange);
}
// 4.拦截
// 4.1.禁止访问,设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //401
// 4.2.结束处理
return exchange.getResponse().setComplete();
}
}
过滤器执行顺序
请求进入网关会碰到三类过滤器:当前路由的过滤器,DefaultFilter,GlobalFilter;请求路由后,会将所有过滤器合并成一个过滤器链,排序后一次执行每个过滤器
每个过滤器指定一个int类型的order值,值越小 优先级越高 越先执行
GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增
当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行
响应的过滤器执行顺序与请求过滤器的执行顺序相反
跨域问题
跨域: 域名不同 、 域名相同,端头不同
浏览器禁止请求的发起者与服务端发生跨域ajax请求 可以通过CORS来解决
解决跨域问题:
在gateway服务的application.yml文件中,添加下面的配置:
spring:
cloud:
gateway:
# 。。。
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
# - "允许跨域请求的网站"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
