bootstrap.yml文件在application.yml之前被项目读入
<!--nacos的配置管理依赖-->
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml:
spring:
application:
name: userservice
profiles:
active: dev # 环境
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
discovery:
cluster-name: SH #集群名称,这里HZ代指杭州
config:
file-extension: yaml # 文件后缀名
在user-service中将pattern.dateformat这个属性注入到UserController中做测试
@Slf4j
@RestController
@RequestMapping("/user")
// @RefreshScope
public class UserController {
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat, Locale.CHINA));
}
}
}
链接:https://pan.baidu.com/s/1vokjKM49nJUrbzUT3MZGRA?pwd=ch93
提取码:ch93
RestTemplate方式调用存在问题
String url = "http://userservice/user/" + order.getUserId();User user = restTemplate.getForObject(url, User.class);
Feign的介绍
Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
使用Feign的步骤:
引入依赖:
<!--feign客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在order-service的启动类添加注解开启Feign的功能:
@EnableFeignClients()
编写Feign客户端:
在clients包下面新建一个UserClients接口
@FeignClient("userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
配置日志的级别
全局生效
feign:
client:
config:
default: #这里使用default就是全局配置,如果改成服务名称,则是针对某个服务
loggerLevel: FULL #日志级别
局部生效,将default改成服务名称,例如userservice
public class DefaultFeignConfiguration {
@Bean
public Logger.Level logLevel(){
return Logger.Level.BASIC;
}
}
全局配置:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
局部配置:
@EnableFeignClients(value="userservice",defaultConfiguration = DefaultFeignConfiguration.class)
Feign底层的客户端实现:
因此优化Feign的性能主要包括:
Feign添加HttpClient的支持
引入依赖:
<!--引入HttpClient依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置连接池:
feign:
httpclient:
enabled: true # 支持HttpClient的开关
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 单个路径的最大连接数
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。有两种方式解决:
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
@EnableFeignClients(clients = UserClient.class)
网关功能:
<!--nacos服务注册发现依赖-->
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
<!--网关gateway依赖-->
org.springframework.cloud
spring-cloud-starter-gateway
2.编写路由配置及nacos地址
server:
port: 10010 # 网关端口
spring:
application:
name: gateway #服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
routes: #网关路由配置
- id: user-service #路由id ,自定义,只要唯一即可
uri: lb://userservice # uri:http://127.0.0.1:8083 路由的目标地址 https就是固定地址
predicates: #路由断言 。也是判断请求是否符合路由古i则的条件
- Path=/user/** #这个是按照路径匹配,只要是以/user/开头就符合条件
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
路由配置包括:
路由断言工厂Route Predicate Factory
Gateway断言工厂官网讲述地址:详细
路由过滤器 GatewayFilter
给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!
实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器
spring:
application:
name: gateway #服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
routes: #网关路由配置
- id: user-service #路由id ,自定义,只要唯一即可
uri: lb://userservice # uri:http://127.0.0.1:8083 路由的目标地址 https就是固定地址
predicates: #路由断言 。也是判断请求是否符合路由古i则的条件
- Path=/user/** #这个是按照路径匹配,只要是以/user/开头就符合条件
filters: # 过滤器
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
spring:
application:
name: gateway #服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
routes: #网关路由配置
- id: user-service #路由id ,自定义,只要唯一即可
uri: lb://userservice # uri:http://127.0.0.1:8083 路由的目标地址 https就是固定地址
predicates: #路由断言 。也是判断请求是否符合路由古i则的条件
- Path=/user/** #这个是按照路径匹配,只要是以/user/开头就符合条件
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: # 默认过滤器,会对所有的路由请求都生效
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
自定义类,实现GlobalFilter接口,添加@Order注解:
@Order注解和Ordered接口的作用是解决过滤器执行顺序问题
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
//@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@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.FORBIDDEN);
// 4.2结束处理
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return 0;
}
}
网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:
spring:
cloud:
gateway:
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 # 这次跨域检测的有效期