微服务-配置中心、feign框架、gw网关
Day.02- 配置中心、Feign声明http框架、GW网关
本章小结:
- Nacos 单机、windows集群、linux集群安装
- Nacos配置中心的配置和使用,优先级对比
- Feign简单使用、日志优化、连接池优化
- Feign、boot、api最佳实践
- GW网关安装配置、路由断言、三种过滤器实践
未解之谜:
- ==多环境的分配需要好好琢磨下==
- 频繁更新的规范?
- 多环境分区存储
[TOC]
No.01-Nacos配置中心、多集群
1、配置中心
1.1、服务端配置
服务端主要存放频繁热更新的关键配置
- Data ID采用【服务名-环境.yaml】
- 配置格式采用YAML
- 配置内容:以==频繁修改需热更新==的为主
1.2、客户端配置
pom依赖
<!-- nacos配置依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
boostrap.yml 启动配置
spring: application: name: userservice #必要元素:服务名称,调取远程配置用 profiles: active: dev #必要元素:环境配置 cloud: nacos: server-addr: localhost:8848 # nacos settings config: file-extension: yaml # 配置类型
application配置清理(去除重复项,==分区存储后续再琢磨如何实现==)
```yaml
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://192.168.20.164:3306/cloud_user?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
cloud: # nacos settings
nacos:
discovery:
cluster-name: HZ
mybatis:
type-aliases-package: com.iyyxx.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.iyyxx: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
- 配置拉取:webController测试
```java
package com.iyyxx.user.web;
import com.iyyxx.user.config.PatternProperties;
import com.iyyxx.user.pojo.User;
import com.iyyxx.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
}
1.3、配置热更新
- 方案一,@Value和@RefreshScope搭配使用,不推荐
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope //热更新,配合@Value注解使用
public class UserController {
@Autowired
private UserService userService;
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
}
方案二,采用@ConfigurationProperties, 推荐
@ConfigurationProperties
package com.iyyxx.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; }
package com.iyyxx.user.web; import com.iyyxx.user.config.PatternProperties; import com.iyyxx.user.pojo.User; import com.iyyxx.user.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Slf4j @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Autowired private PatternProperties properties; @GetMapping("now") public String now() { return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat())); //从properties热同步 } }
1.4、多环境部署
配置可重叠,环境优先级: 服务名-profile.yaml > 服务名.yaml > application.yml(local)
测试准备
nacos:userservice.yaml
envSharedValue: 服务端共享配置 #仅一份,无重叠覆盖,均可用 name1: name@服务端共享 #优先级2,如果有更高级配置则被覆盖 name2: name@服务端共享 #优先级2,覆盖本地
nacos:userservice-dev.yaml
name1: name1@测试环境专用 #优先级1,覆盖全部
本地:application.yml
name1: name@local #优先级3,可被服务端2份覆盖 name2: name2@local #优先级3,如仅存这份,则显示 name3: name3@local #优先级3,如仅存这份,则显示
程序配置
- 补充idea多环境在启动器上的配置,==可不修改yaml文件调整环境配置!==
package com.iyyxx.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; private String envSharedValue; private String name1; private String name2; private String name3; }
package com.iyyxx.user.web; import com.iyyxx.user.config.PatternProperties; import com.iyyxx.user.pojo.User; import com.iyyxx.user.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Slf4j @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Autowired private PatternProperties properties; @GetMapping("prop") public PatternProperties properties() { return properties; } }
启动dev和test环境并测试
2、集群搭建
2.1、环境准备
服务 | IP | 端口 | 说明 |
---|---|---|---|
nacos1 | 127.0.0.1 | 8841 | 实际服务端口,未来建议放linux、不同机器保障安全 |
nacos2 | 127.0.0.1 | 8842 | 实际服务端口,未来建议放linux、不同机器保障安全 |
nacos3 | 127.0.0.1 | 8843 | 实际服务端口,未来建议放linux、不同机器保障安全 |
nginx | 127.0.0.1 | 80 | 反向代理端口,未来建议放linux |
2.2、nacos#application.properties 配置(服务端口、db)
### Default web server port:
server.port=8841
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.20.164:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
2.3、nacos#cluster.conf 集群清单(IP、端口)
127.0.0.1:8841
127.0.0.1.8842
127.0.0.1.8843
2.4、nginx#nginx.conf配置(反向代理)
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
# nacos集群、反向代理配置
upstream nacos-cluster {
server 127.0.0.1:8841;
server 127.0.0.1:8842;
server 127.0.0.1:8843;
}
server {
listen 80;
#server_name 采用hosts文件nacos自动生成的? 省的用localhost老报错,生产建议用稳定的域名为后迁移做平滑准备
server_name windows10.microdone.cn;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
}
2.5、 windows terminal安装及nginx 操作命令
github 下载安装【Windows terminal here】
建议设置多窗口、cmd shell
# nacos启动, 进入nagos/bin目录
startup.cmd
# nginx 启动, 进入nginx目录
start nginx
# nginx 关闭
nginx -s stop
# nginx 刷新配置
nginx -s reload
# windows shelle 根据执行文件名查进程
tasklist | findstr nginx
# windows shell 根据文件名杀进程, 支持通配符
taskkill /f /t /im nginx.exe
# windows shell 查询端口占用
netstat -ano|findstr ":80"
2.6、bootstrap.yml 配置修改
spring:
application:
name: userservice
profiles:
active: dev
cloud:
nacos:
server-addr: windows10.microdone.cn:80 # 端口必须显性的设置,不然默认8848端口
config:
file-extension: yaml
No.02-Feign 声明式调用框架
1、Feign优雅替换RestTemplate
restTemplate的问题
Feign的使用步骤
代码实现
POM依赖修改
<!-- Feign依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
入口程序开启@ConfigurationFeignClients
package com.iyyxx.order; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RoundRobinRule; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @MapperScan("com.iyyxx.order.mapper") @SpringBootApplication @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
添加@FeignClient
package com.iyyxx.order.clients; import com.iyyxx.user.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient("userservice") public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
修改服务层调用
package com.iyyxx.order.service; import com.iyyxx.order.clients.UserClient; import com.iyyxx.order.mapper.OrderMapper; import com.iyyxx.order.pojo.Order; import com.iyyxx.user.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private UserClient userClient; public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2.利用userClient查询用户,远程调用且负载均衡 User user = userClient.findById(order.getUserId()); // 3.封装user到Order order.setUser(user); // 4.返回 return order; } }
2、Feign日志开关
yml配置方式-全局
feign:
client:
config:
default: #default代表全部,可以用具体被调用的服务名称如userservice
loggerLevel: full #none,basic,full 空、简要、完整,生产环境不能使用full
yml配置方式-单个
feign:
client:
config:
userservice: #default代表全部,可以用具体被调用的服务名称如userservice
loggerLevel: full
bean配置方式-全局
创建DefaultFeignConfiguration
package com.iyyxx.order.config; import feign.Logger; import org.springframework.context.annotation.Bean; public class DefaultFeignConfiguration { @Bean public Logger.Level logLevel(){ return Logger.Level.FULL; //同样有多种日志级别 } }
应用到全局(boot入口程序的@EnableFeignClients的defaultConfiguration配置)
package com.iyyxx.order; import com.iyyxx.order.config.DefaultFeignConfiguration; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RoundRobinRule; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @MapperScan("com.iyyxx.order.mapper") @SpringBootApplication @EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class) //入口程序即全局! public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
bean配置方式-单个
- 配置feignClient的@FeignClient的Configuration属性
package com.iyyxx.order.clients;
import com.iyyxx.order.config.DefaultFeignConfiguration;
import com.iyyxx.user.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "userservice",configuration = DefaultFeignConfiguration.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
3、连接池优化(实际有效参数用jmeter压测)
HttpClient
POM依赖
<!-- Feign HttpClient依赖 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
yml配置
feign: httpclient: enabled: true # 开启feign对httpClient的支持 max-connections: 200 # 最大连接数 max-connections-per-route: 50 # 每个路径最大连接数
OKClient
POM依赖
<!-- Feign OKClient依赖 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
yml配置
feign: okhttp: enabled: true
4、Feign最佳实践(继承接口-不推荐,统一feignApi可以考虑,如果重叠服务较多的时候)
思路:
- SpringBootApplication之间不互相引用
- 另外存放Feign的连接池配置
- 远程调用都放到Feign-API里面
- Feign的依赖也放在这个包里
- 其他Boot都引用他
- 并且API里面也不去引用具体Boot
- api项目里主要是client的实现、pojo的冗余和Feign的公共配置
- api项目可以考虑作为boot之间交互测试的程序==后续在这里做test程序?==
具体实现如下:
Feign Model创建,略
api project加入feign依赖,order引用api、并去除userservice、feign依赖
api/pom依赖
<dependencies> <!-- Feign依赖 --> <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> <!-- Feign OKClient依赖,可选 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency> </dependencies>
移植orderservice/clients、orderservice/config、orderservice/pojo,如图
orderservice project删除orderservice的client、config,清理修正pom、
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>com.iyyxx</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- nacos客户端依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- 引入自身的feign-api --> <dependency> <groupId>com.iyyxx</groupId> <artifactId>feign-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
修正order的user引用为api project
package com.iyyxx.order.pojo; import com.iyyxx.feign.pojo.User; import lombok.Data; @Data public class Order { private Long id; private Long price; private String name; private Integer num; private Long userId; private User user; }
修正service的user
package com.iyyxx.order.service; import com.iyyxx.feign.clients.UserClient; import com.iyyxx.feign.pojo.User; import com.iyyxx.order.mapper.OrderMapper; import com.iyyxx.order.pojo.Order; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private UserClient userClient; public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2.利用userClient查询用户,远程调用且负载均衡 User user = userClient.findById(order.getUserId()); // 3.封装user到Order order.setUser(user); // 4.返回 return order; } }
调整入口程序,单独扫描clients, 如果要扫描目录可以考虑把
clients换成basePackages
package com.iyyxx.order; import com.iyyxx.feign.clients.UserClient; import com.iyyxx.feign.config.DefaultFeignConfiguration; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RoundRobinRule; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @MapperScan("com.iyyxx.order.mapper") @SpringBootApplication @EnableFeignClients(clients = UserClient.class, defaultConfiguration = DefaultFeignConfiguration.class) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
application.yml 仅保留feign的连接池配置,==未来如果遇到需要统一连接池可以考虑抽取到api project中==
```yaml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://192.168.20.164:3306/cloud_order?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
cloud: # nacos settings
nacos:
discovery:
cluster-name: FJ
namespace: c8f73bfe-ffbd-493b-a9fa-8885c947ca40 # dev测试环境
mybatis:
type-aliases-package: com.iyyxx.order.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.iyyxx: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
#com.alibaba.cloud.nacos.ribbon.NacosRule
#com.netflix.loadbalancer.RandomRule
ribbon:
eager-load:
enabled: true
clients:
- userservice
feign:
httpclient:
enabled: true # 开启feign对httpClient的支持
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 每个路径最大连接数
```
No.03-Gateway网关
1、GateWay实现
实现过程:
- 新增model
- 引入依赖(nacos注册发现、gateway)
- 编写入口程序(普通springboot)
- 编写yml文件(服务端口号、nacos注册信息、基本路由规则)
引入依赖
<!-- gateway依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- nacos服务注册和发现依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
入口程序
package com.iyyxx.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class,args); } }
配置信息
server: port: 10010 spring: application: name: gateway cloud: nacos: discovery: server-addr: windows10.microdone.cn:80 # nacos settings gateway: routes: - id: user-service # 路由标识,必须为宜 uri: lb://userservice predicates: # 路由断言 - Path=/user/** - id: order-service # 路由标识,必须为宜 uri: lb://orderservice predicates: # 路由断言 - Path=/order/**
测试
2、Route Predicate Factories
官方文档参考
可以做的功能:
- 根据时间范围做活动,比如秒杀 between
- ip地址范围限定,remoteaddr
案例:添加时间限定,2025年后才可访问,不过没有日志,只有服务404
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: windows10.microdone.cn:80 # nacos settings
gateway:
routes:
- id: user-service # 路由标识,必须为宜
uri: lb://userservice
predicates: # 路由断言
- Path=/user/**
- id: order-service # 路由标识,必须为宜
uri: lb://orderservice
predicates: # 路由断言
- Path=/order/**
- After=2025-01-20T17:42:47.789-07:00[America/Denver]
3、GatewayFilter Factory配置
案例:网关过滤器,
- 过滤器对request添加参数,springboot调用并日志输出
- 再修改为全局配置
gateway/application.yml
server: port: 10010 spring: application: name: gateway cloud: nacos: discovery: server-addr: windows10.microdone.cn:80 gateway: routes: - id: user-service uri: lb://userservice predicates: - Path=/user/** filters: #添加请求头过滤器,添加请求头 - AddRequestHeader=Truth,Mike is handsome! - id: order-service # uri: lb://orderservice predicates: - Path=/order/** - After=2025-01-20T17:42:47.789-07:00[America/Denver]
userservice/webController
package com.iyyxx.user.web; import com.iyyxx.user.config.PatternProperties; import com.iyyxx.user.pojo.User; import com.iyyxx.user.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Slf4j @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; /** * 路径: /user/110 * * @param id 用户id * @return 用户 */ @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); } }
调整为全局设置
server: port: 10010 spring: application: name: gateway cloud: nacos: discovery: server-addr: windows10.microdone.cn:80 # nacos settings gateway: routes: - id: user-service uri: lb://userservice predicates: - Path=/user/** - id: order-service uri: lb://orderservice predicates: - Path=/order/** - After=2025-01-20T17:42:47.789-07:00[America/Denver] default-filters: - AddRequestHeader=Truth,Lin is handsome!
4、Global Filters
说明:这个过滤器是可以编码的!
==优先级==:GWFilter Default Filter > GWFilter Routes Filter > GlobalFilters
GWFilter默认从1算起!
实现
package com.iyyxx.gateway; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; 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; @Component public class AuthorizeFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取请求参数 MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams(); // 2.获取参数中的authorization 参数 String authorization = queryParams.getFirst("authorization"); // 3。判断参数是否等于admin if(authorization!=null && authorization.equals("admin")){ // 4.是,放行 return chain.filter(exchange); }else{ // 5.否,拦截, 禁止访问 exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN); return exchange.getResponse().setComplete(); } } @Override public int getOrder() { return -1; //默认优先级21亿,最高-21亿,相比其他过滤器默认排序从1算起,设置-1优先级就很高了 } }
5、网关跨域问题
什么是跨域:从浏览器出发,用ajax访问不同的1,2,3级域名,或不同端口,都是跨域!都会被拦截
解决办法:采用CORS方案,在网关程序中集中处理就行, 默认已经处理好,只需要开启配置!
vscode添加【live server】插件 ==回头到前端部分,再细研究npm 安装这个并从命令行启动的相关玩法!==
vscode打开文件目录,模拟调用 ctrl+shift+p
- html测试程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<pre>
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 # 这次跨域检测的有效期
</pre>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.get("http://localhost:10010/user/1?authorization=admin")
.then(resp => console.log(resp.data))
.catch(err => console.log(err))
</script>
</html>
- 调试程序
spring:
cloud:
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://127.0.0.1:5500"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
- 查看效果
No.04、企业级服务端nacos、nginx配置
4.1、环境准备
服务 | IP | 端口 | 说明 |
---|---|---|---|
nacos1 | 192.168.20.162 | 8848 | 实际服务端口 |
nacos2 | 192.168.20.163 | 8848 | 实际服务端口 |
nacos3 | 192.168.20.164 | 8848 | 实际服务端口 |
nginx | 192.168.20.164 | 80 | 反向代理端口 |
4.2、jdk安装
tar zxvf jdk-8u241-linux-x64.tar.gz
mv jdk1.8.0_241/ /opt/software
ln -s /opt/software/jdk1.8.0_241 /opt/java
echo 'JAVA_HOME=/opt/java'>>~/.bash_profile
echo 'JRE_HOME=/opt/java/jre'>>~/.bash_profile
echo 'PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin'>>~/.bash_profile
echo 'CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib'>>~/.bash_profile
echo 'export JAVA_HOME JRE_HOME PATH CLASSPATH'>>~/.bash_profile
#验证!
java -version
4.3、nacos安装
- 解压、单机启动、可web访问!
tar xvf nacos-server-1.4.2.tar.gz
mv nacos/ /opt/software/
ln -s /opt/software/nacos/ /opt/nacos
/opt/nacos/bin/startup.sh -m standalone
/opt/nacos/bin/shutdown.sh
tail -f /opt/nacos/logs/start.out
4.4、nacos#application.properties 配置(服务端口、db)
### Default web server port:
server.port=8848
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.20.164:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
4.5、nacos#cluster.conf 集群清单(IP、端口)
192.168.20.162:8848
192.168.20.163
192.168.20.164
4.6、nacos#服务设置、自启动
vim /lib/systemd/system/nacos.service
# 添加以下内容
[Unit]
Description=nacos
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/opt/java"
ExecStart=/opt/nacos/bin/startup.sh
ExecReload=/opt/nacos/bin/shutdown.sh
ExecStop=//opt/nacos/bin/shutdown.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- 自启动、重启服务
systemctl enable nacos.service && systemctl restart nacos.service
4.7、nginx#nginx.conf配置(反向代理)
- 安装pcre、nginx
# 基本环境安装
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
# 下载pcre
cd /usr/local/src/
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
# 安装pcre
tar zxvf pcre-8.35.tar.gz
cd pcre-8.35
./configure
make && make install
pcre-config --version
# 下载安装nginx
cd ~
wget https://nginx.org/download/nginx-1.21.3.tar.gz
tar xvf nginx-1.21.3.tar.gz
cd nginx-1.21.3
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/src/pcre-8.35
make && make install
# 检查nginx是否安装成功,获取版本号
/usr/local/webserver/nginx/sbin/nginx -v
# 添加web用户
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
- 配置conf文件
vim /usr/local/webserver/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
upstream nacos-cluster {
server 192.168.20.162:8848;
server 192.168.20.163:8848;
server 192.168.20.164:8848;
}
server {
listen 80;
server_name 192.168.20.162;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
}
- 配置文件正确性检测
/usr/local/webserver/nginx/sbin/nginx -t
- nginx配置服务和自启动
vi /usr/lib/systemd/system/nginx.service
# 添加以下内容
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/webserver/nginx/sbin/nginx
ExecReload=/usr/local/webserver/nginx/sbin/nginx -s reload
ExecStop=/usr/local/webserver/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
设置nginx自启动
systemctl enable nginx.service systemctl status nginx.service reboot
4.8、 nginx 操作命令
systemctl stop/restart/start nacos/nginx
评论系统未开启,无法评论!