当前位置: 首页> 健康> 母婴 > SpringCloud03

SpringCloud03

时间:2025/7/12 19:59:04来源:https://blog.csdn.net/2301_80098154/article/details/140766796 浏览次数:0次

一、网关

网关:就是网络的关口,负责请求的路由,转发,身份校验。

在SpringCloud中网关的实现:

SpringCloud Gateway

由SpringCloud官方出品

基于WebFlux响应式编程

无需调优即可获得优异性能

(1)网关路由

配置路由规则

spring:cloud:gateway:routes: - id: item # 路由规则id,自定义,唯一uri: lb://item-service # 路由目标微服务,lb代表负载均衡predicates: # 路由断言,判断请求是否符合规则,符合则路由到目标- Path=/items/** # 以请求路径做判断,以/items开头则符合- id: xxuri: lb://xx-servicepredicates:- Path=/xx/**

①快速入门:

创建一个新的模块,引入网关的依赖,编写启动类,配置路由规则。

②路由属性

网关路由对应的java类型是RouteDefinition,其中常见的属性有:

id:路由唯一标识

uri:路由目标地址

predicates:路由断言,判断请求是否符合当前路由

filters:路由过滤器,对请求或响应做特殊处理

路由断言: 

路由过滤器:

(2)网关登录校验

ctrl+H 查看该类的实现类

网关过滤器有两种,分别是:

GatewayFilter:路由过滤器作用于任意指定的路由,默认不生效,要配置到路由后生效。

GlobalFilter:全局过滤器,作用范围是所有路由,声明后自动生效。

①自定义全局过滤器

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        获取请求ServerHttpRequest request = exchange.getRequest();HttpHeaders headers = request.getHeaders();System.out.println("headers"+headers);
//        放行return chain.filter(exchange);}@Overridepublic int getOrder() {
//        过滤器执行顺序,值越小,优先级越高return 0;}
}

②自定义过滤器GatewayFilter

自定义GatewayFilter不是直接实现GatewayFilter,而是实现AbstractGatewayFilterFactory


@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {@Overridepublic GatewayFilter apply(Object config) {return new OrderedGatewayFilter(new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {System.out.println("print any filter running");return chain.filter(exchange);}},1);}}
}

③实现登录校验

@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {private final AuthProperties authProperties;private final JwtTool jwtTool;private final AntPathMatcher antPathMatcher=new AntPathMatcher();@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        1.获取requestServerHttpRequest request = exchange.getRequest();
//        2.判断是否需要做登录拦截if (isExclude(request.getPath().toString())){
//            放行return chain.filter(exchange);}
//        3.获取tokenString token =null;List<String> headers = request.getHeaders().get("authorization");if (headers!=null&&!headers.isEmpty()){token=headers.get(0);}
//        4.校验并解析tokenLong userId=null;try{userId = jwtTool.parseToken(token);}catch(UnauthorizedException e){ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}
//        TODO 5.传递用户信息System.out.println("userId"+userId);
//        6.放行return chain.filter(exchange);    }private boolean isExclude(String path) {for (String pathPattern :authProperties.getExcludePaths()){if (antPathMatcher.match(pathPattern,path)){return true;}}return false;}@Overridepublic int getOrder() {return 0;}
}

④网关传递用户信息

一、在网关的登录校验过滤器中,把获取到的用户写入请求头

需求:修改gateway模块中的登录校验拦截器,在校验成功后保存用户到下游请求的请求头中。 提示:要修改转发到微服务的请求,需要用到ServerWebExchange类提供的API,示例如下:

//        5.传递用户信息String userInfo = userId.toString();ServerWebExchange swe = exchange.mutate().request(builder -> builder.header("userinfo", userInfo)).build();

从网关那里获取用户信息,通过过滤器做拦截,获取修改请求头,定义一个通用的拦截器,

二、在hm-common中编写SpringMVC拦截器,获取登录用户

需求:由于每个微服务都可能有获取登录用户的需求,因此我们直接在hm-common模块定义拦截器,这样微服务只需要引入依赖即可生效,无需重复编写。

@Component
public class UserInfoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//      获取用户登陆信息String userinfo = request.getHeader("userinfo");
//      判断是否获取了用户,如果有,存入ThreadLocal
if (StrUtil.isNotBlank(userinfo)){UserContext.setUser(Long.valueOf(userinfo));}
//        放行
return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserContext.removeUser();}
}
@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());}
}

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.hmall.common.config.MyBatisConfig,\com.hmall.common.config.MvcConfig,\com.hmall.common.config.JsonConfig

⑤OpenFeign传递用户(微服务之间的相互调用)

微服务项目中的很多业务要多个微服务共同合作完成,而这个过程中也需要传递登录用户信息。

OpenFeign中提供了一个拦截器接口,所有由OpenFeign发起的请求都会先调用拦截器处理请求

    @Beanpublic RequestInterceptor userInfoRequestInterceptor(){return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {Long userId = UserContext.getUser();if (userId!=null){RequestTemplate userinfo = template.header("userinfo", userId.toString());}}};}

(3)配置管理

①配置共享

i.添加一些通用配置到Nacos中,包括:Jdbc、MybatisPlus、日志、Swagger、OpenFeign等配置

ii.拉取共享配置

基于NacosConfig拉取共享配置代替微服务的本地配置

引入依赖

<!--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></dependency>

新建bootstrap.yaml

spring:application:name: cart-service #微服务名称profiles:active: devcloud:nacos:server-addr: 1.12.232.19:8848 #nacos地址config:file-extension: yaml #文件后缀名shared-configs:- data-id: shared-jdbc.yaml- data-id: shared-log.yaml- data-id: shared-swagger.yaml

②配置热更新

配置热更新:当修改配置文件中的配置时,微服务无需重启即可使配置生效。

前提条件:nacos中要有一个与微服务名有关的配置文件。

微服务中要以特定方式读取需要热更新的配置属性

@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {private Integer maxItems;
}

③动态路由

如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。

  • 创建ConfigService,目的是连接到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>
</dependency>

然后在网关gatewayresources目录创建bootstrap.yaml文件,内容如下

spring:application:name: gatewaycloud:nacos:server-addr: 192.168.150.101config:file-extension: yamlshared-configs:- dataId: shared-log.yaml # 共享日志配置

接着,修改gatewayresources目录下的application.yml,把之前的路由移除

server:port: 8080
hm:jwt:location: classpath:hmall.jksalias: hmallpassword: hmall123tokenTTL: 30mauth:excludePaths:- /search/**- /users/login- /items/**- /hi

然后,在gateway中定义配置监听器

接下来,我们直接在Nacos控制台添加路由,路由文件名为gateway-routes.json,类型为json

[{"id": "item","predicates": [{"name": "Path","args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"}}],"filters": [],"uri": "lb://item-service"},{"id": "cart","predicates": [{"name": "Path","args": {"_genkey_0":"/carts/**"}}],"filters": [],"uri": "lb://cart-service"},{"id": "user","predicates": [{"name": "Path","args": {"_genkey_0":"/users/**", "_genkey_1":"/addresses/**"}}],"filters": [],"uri": "lb://user-service"},{"id": "trade","predicates": [{"name": "Path","args": {"_genkey_0":"/orders/**"}}],"filters": [],"uri": "lb://trade-service"},{"id": "pay","predicates": [{"name": "Path","args": {"_genkey_0":"/pay-orders/**"}}],"filters": [],"uri": "lb://pay-service"}
]

关键字:SpringCloud03

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: