<!--nacos的管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高本地集群不可访问时,再去访问其他集群
修改application.yml添加以下内容
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
discovery:
cluster-name: HZ # 配置集群名称,也就是机房位置
将order-server中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务
userserver:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
实际部署中会出现这样的场景:
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离 修改order-server的application.yml,添加namespace:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
discovery:
cluster-name: HZ # 配置集群名称,也就是机房位置
namespace: # 填写命名空间: 填ID
不同namespace下的服务不可见
配置获取步骤
<!-- nacos的配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 若bootstrap配置不生效,加入以下依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.1</version>
</dependency>
spring:
application:
name: userserver
profiles:
active: dev # 环境
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties{
private String dateformat;
}
多种配置的优先级:
服务名-profile.yaml -> 服务名.yaml > 本地配置
当前环境配置 优先级高于 nacos中的配置 优先级高于 本地配置
<!-- feign客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@FeignClient("userserver")
public interface UserClients {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
public Order queryOrderById(Long orderId){
Order order = orderMapper.findById(orderId);
// 用feign远程调用
User user = userClients.findById(order.getUserId());
order.setUser(user);
return order;
}
方式一:配置文件方式
# Feign日志配置
feign:
client:
config:
default:
loggerLevel: FULL
方式二:代码方式先声明一个Bean
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
// 1. 而后如果是全局配置,则把他放到@EnableFeignClients注解中
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
// 2. 如果是局部配置,则把他放到@FeignClient注解中
@FeignClient(value = "userserver", configuration = FeignClientConfiguration.class)
Feign底层的客户端实现
引入依赖
<!-- 引入HttpClient依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置文件
# 开启httpClient配置
httpclient:
enabled: true #支持httpClient开关
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 单个路径的最大连接数
Feign的优化:
spring官方不推荐使用
实现最佳实践方式二的步骤如下:
1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖
2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
3.在order-service中引入feign-api的依赖
4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
5.重启测试
推荐第二种
网关功能:
<!-- 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>
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
# gateway配置
gateway:
routes: # 网关路由配置
- id: user-server # 路由id,自定义主要是唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 固定地址
uri: lb://userserver # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配, 只要以/user/开头就符合要求
- id: order-server
uri: lb://orderserver
predicates:
- Path=/order/**
predicates:
- After=2021-01-01T11:37:34.485+08:00[Asia/Shanghai]
predicates:
- Before=2021-01-01T11:37:34.485+08:00[Asia/Shanghai]
predicates:
- Between=2021-01-01T11:37:34.485+08:00[Asia/Shanghai], 2021-01-07T11:37:34.485+08:00[Asia/Shanghai]
predicates:
- Cookie=username, zhangsan
predicates:
- Header=X-Request-Id, \d+
predicates:
- Host=**.abc.org, **.xyz.org
predicates:
- Method=GET
predicates:
- Path=/foo/{segment}
predicates:
- Query=myParam, \d+
predicates:
- RemoteAddr=192.168.1.1/24
predicates:
- Weight=group1, 5
- Weight=group2, 10
给所有进入userserver的请求加一个请求头
// 实现方法
## 添加过滤
# filters:
# - AddRequestHeader=Truth, XYZ
- id: order-server
uri: lb://orderserver
predicates:
- Path=/order/**
# 全局过滤配置
default-filters:
- AddRequestHeader=Truth,ABC
过滤器的作用是什么?
对路由的请求或响应做加工处理,比如添加请求头配置在路由下的过滤器只对当前路由的请求生效
defaultFilters的作用是什么?
对所有路由生效的过滤器,比如添加请求头配置在defaultFilters下过滤器对所有路由的请求都生效
@Component
//@Order(-1) // 优先级
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);
}
exchange.getResponse().setRawStatusCode(401);
// 5. 否拦截
return exchange.getResponse().setComplete();
}
// 优先级
@Override
public int getOrder() {
return -1;
}
}
全局过滤器的作用是什么?对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器的步骤?
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
# - "http://localhost:8080"
- "*"
allowedMethods: # 允许的跨域的ajax的请求方式
- "GET"
- "POST"
- "PUT"
- "DELETE"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
exposedHeaders: true # 是否允许请求中携带cookie
maxAge: 36000 # 这次跨域检测的有效期
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。