1. Nacos配置管理
配置的热更新
DataID 命名格式: 实例名-环境名.后缀名(yaml)
尽量用 yaml,不用 yml
2. Nacos配置管理 - 微服务配置拉取
把所有nacos地址和配置信息都放在 bootstrap.yml
- 引入 Nacos配置管理依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 新建 bootstrap.yml (bootstrap.yml为引导文件,它的优先级比application.yml要高)
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
file-extension: yaml # 配置文件后缀
namespace: c3b1bbc3-0ebd-4298-92c2-1e54858acf02 # 命名空间
group: DEFAULT_GROUP # 配置组
prefix: user-service # 配置文件前缀
server-addr: localhost:8848 # nacos地址
discovery:
namespace: c3b1bbc3-0ebd-4298-92c2-1e54858acf02 # 命名空间
group: DEFAULT_GROUP # 配置组
- 读取配置
在Nacos的配置为:
pattern-dateformat=yyyy-MM-dd HH:mm:ss
在usercontroller.java里:
@NacosValue("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
此处遇到坑:
- 要使用@NacosValue注解
- 要确保namespace一致
- boot, cloud, alibaba版本匹配
- 有时候需要重启一下nacos
3. Nacos配置管理 - 配置热更新
配置自动刷新
方式一:在@Value注入的变量所在类上面添加注解 @RefreshScope
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
方法二:使用@ConfigurationProperties注解
package cn.itcast.user.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}
然后直接访问 PatternProperties的bean的dateformat就行。
4. Nacos配置管理 - 微服务配置共享
5. Nacos配置环境 - Nacos集群管理
6. 基于Feign的远程调用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在启动类上加注解@EnableFeignClients
@EnableFeignClients
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
编写 Feign 客户端
@FeignClient(value = "userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
调用:
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.用Feign远程调用
User user = userClient.findById(order.getUserId());
// 3.封装user到Order
order.setUser(user);
// 4.返回
return order;
}
7. Feign - 自定义配置
覆盖配置方式:
配置文件:
全局:
feign:
client:
config:
default:
loggerLevel: FULL
局部:
feign:
client:
config:
userservice:
loggerLevel: FULL
java代码形式:
// FeignClientConfiguration.java
public class DefaultFeignConfiguration {
@Bean
public Logger.Level logLevel(){
return Logger.Level.BASIC;
}
}
全局:
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
局部
@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class)
8. Feign - 性能优化
- 引入 HttpClient依赖
<dependency>
<!-- httpClient -->
<groupId>io.github.openfeign</groupId>
<artifactId>fegin-httpclient</artifactId>
</dependency>
配置连接池:
feign:
client:
config:
default:
loggerLevel: BASIC
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 #最大连接数
max-connections-per-route: 50 #每个路径的最大连接数
9. Feign - 最佳实践
方式一(继承):给消费者的FeignClient和提供者controller定义统一的父接口作为标准。
方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的pojo,默认的Feign配置都放到这个模块中,提供给所有消费者使用。
10. Feign - 实现抽取
- 新建module,命名为feign-api,引入 feign的starter依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
-
将所有client、pojo和配置类都放到feign-api里面
-
改变import的路径
-
重启重试即可。
11. Gateway - 网关介绍
12. Gateway - 快速入门
- 新建module,命名为 gateway2,引入依赖
<!--nacos服务注册发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 创建GatewayApplication,编写路由配置及nacos地址
server:
port: 10010
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
spring:
application:
name: gateway
cloud:
nacos:
server-addr: nacos:8848 # nacos地址
gateway:
routes:
- id: user-service # 路由标示,必须唯一
uri: lb://userservice # 路由的目标地址
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
13. Gateway - 路由断言工厂
14. Gateway - 路由过滤器GatewayFilter
全局过滤器:
spring:
application:
name: gateway
cloud:
nacos:
server-addr: nacos:8848 # nacos地址
gateway:
...
default-filters:
- AddRequestHeader=Truth,Itcast is freaking awesome!
...
15. Gateway - 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.判断参数值是否等于 admin
if ("admin".equals(auth)) {
// 4.是,放行
return chain.filter(exchange);
}
// 5.否,拦截
// 5.1.设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2.拦截请求
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
16. Gateway - 过滤器链执行顺序
17. Gateway - Cors跨域问题处理
spring:
application:
name: gateway
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
cors-configurations:
'[/**]':
allowedOrigins: #允许哪些网站的跨域请求
- 'http://localhost:10000'
allowedMethods: #允许跨域请求的方法
- 'GET'
- 'POST'
- 'PUT'
- 'DELETE'
- 'OPTIONS'
allowedHeaders: '*' # 允许跨域请求的头
allowCredentials: true # 是否允许携带cookie
maxAge: 3600 # 跨域请求的有效时间