当前位置: 首页 > news >正文

成都 网站建设培训班白帽seo公司

成都 网站建设培训班,白帽seo公司,梵克雅宝四叶草项链回收多少钱,青岛关键词优化报价上一篇:SpringCloud 入门(3)—— Nacos配置中心-CSDN博客 Spring Cloud Gateway 作为 Spring Cloud 生态系统的一部分,主要在微服务架构中充当 API 网关的角色。它提供了统一的入口点来处理所有的 HTTP 请求,并将这些请…

上一篇:SpringCloud 入门(3)—— Nacos配置中心-CSDN博客


Spring Cloud Gateway 作为 Spring Cloud 生态系统的一部分,主要在微服务架构中充当 API 网关的角色。它提供了统一的入口点来处理所有的 HTTP 请求,并将这些请求路由到不同的后端微服务。

Spring Cloud Gateway 是一个强大的工具,它不仅简化了微服务间的通信,还增强了系统的安全性、稳定性和可扩展性。对于任何采用微服务架构的应用程序来说,它都是不可或缺的一部分。

1.快速入门

1.1创建网关

单独创建一个模块,配置网关

首先导入网关所需依赖

         <!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--服务发现中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>

本地服务中配置,指定nacos地址

#微服务配置
spring:application:name: gatewaycloud:nacos:server-addr: 124.70.208.223:8848discovery:namespace: devgroup: xuecheng-plus-project  # Nacos 服务发现的组名,用于进一步隔离服务config:namespace: devgroup: xuecheng-plus-project  file-extension: yamlrefresh-enabled: true #动态刷新shared-configs:- data-id: logging-${spring.profiles.active}.yamlrefresh: trueprofiles:active: dev

1.2nacos配置中心

在nacos配置中心中进行远程配置;所有的网关相关配置全部配置到nacos中,创建gateway-dev.yaml 

34f8812d20cd41f292101253b70075b5.png

server:port: 63010 # 网关端口
spring:cloud:gateway:routes: # 网关路由配置- id: content-api # 路由id,自定义,只要唯一即可uri: lb://content-api # 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/content/** # 这个是按照路径匹配,只要以/content/开头就符合要求- id: system-apiuri: lb://system-apipredicates:- Path=/system/**- id: media-apiuri: lb://media-apipredicates:- Path=/media/**

四个属性含义如下:

  • id:路由的唯一标识

  • uri:路由目标地址,lb://代表负载均衡,从注册中心获取目标微服务的实例列表,并且负载均衡选择一个访问。

  • predicates:路由断言,其实就是匹配条件

  • filters:路由过滤条件,

1.3路由匹配条件

SpringCloudGateway中支持的断言类型有很多:

名称

说明

示例

After

是某个时间点后的请求

- After=2037-01-20T17:42:47.789-07:00[America/Denver]

Before

是某个时间点之前的请求

- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

Between

是某两个时间点之前的请求

- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]

Cookie

请求必须包含某些cookie

- Cookie=chocolate, ch.p

Header

请求必须包含某些header

- Header=X-Request-Id, \d+

Host

请求必须是访问某个host(域名)

- Host=**.somehost.org,**.anotherhost.org

Method

请求方式必须是指定方式

- Method=GET,POST

Path

请求路径必须符合指定规则

- Path=/red/{segment},/blue/**

Query

请求参数必须包含指定参数

- Query=name, Jack或者- Query=name

RemoteAddr

请求者的ip必须是指定范围

- RemoteAddr=192.168.1.1/24

weight

权重处理

2.网关全局过滤器

在网关处,在filter包中实现GlobalFilter接口配置全局过滤器,实现 Ordered接口定义过滤器的优先级。

在过滤器中,首先获取需要放行的路径(在配置文件中定义,AuthProperties 类中读取不进行拦截的路径),如果请求路径,不需要拦截,直接放行。

如果该路径在配置文件中没有定义,都需要拦截,首先获取请求头中的authorization,拿到token值,进行解析。拿到用户的id。将用户的id放到请求头中user-info,转发给其他的微服务

package com.hmall.gateway.filter;import com.hmall.common.exception.UnauthorizedException;
import com.hmall.common.utils.CollUtils;
import com.hmall.common.utils.UserContext;
import com.hmall.gateway.config.AuthProperties;
import com.hmall.gateway.util.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.List;@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(AuthProperties.class)
public class AuthGlobalFilter implements GlobalFilter, Ordered {private final JwtTool jwtTool;private final AuthProperties authProperties;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 (!CollUtils.isEmpty(headers)) {token = headers.get(0);}// 4.校验并解析tokenLong userId = null;try {userId = jwtTool.parseToken(token);} catch (UnauthorizedException e) {// 如果无效,拦截ServerHttpResponse response = exchange.getResponse();response.setRawStatusCode(401);return response.setComplete();}// 5.如果有效,传递用户信息String userInfo = userId.toString();System.out.println("userId"+userInfo);ServerWebExchange swe = exchange.mutate().request(builder -> builder.header("user-info", userInfo)).build();// 6.放行return chain.filter(exchange);}private boolean isExclude(String antPath) {for (String pathPattern : authProperties.getExcludePaths()) {if(antPathMatcher.match(pathPattern, antPath)){return true;}}return false;}@Overridepublic int getOrder() {return 0;//数字约小,优先级越高}
}

上面我们已经在网关过滤器中,获取请求头中的token,解析出用户id,放回请求头user-info中,传递给各个微服务。

但通过openFeign发起的请求中,并没有通过网关,请求中没有携带user-info。

所以我们需要配置openFeign拦截器,拿到用户id,并放到请求头中,转发给其他微服务

下面是针对openFeign的配置

package com.hmall.api.config;import com.hmall.common.utils.UserContext;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfig {@Beanpublic Logger.Level feignLogLevel(){//日志信息return Logger.Level.FULL;}@Beanpublic RequestInterceptor userInfoRequestInterceptor(){return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {// 获取登录用户Long userId = UserContext.getUser();if(userId == null) {// 如果为空则直接跳过return;}// 如果不为空则放入请求头中,传递给下游微服务template.header("user-info", userId.toString());}};}
}

 配置完成后需要在使用了openFeign微服务的启动类上加上@EnableFeignClients注解,激活拦截器

@EnableFeignClients(basePackages = "com.hmall.api.client", defaultConfiguration = DefaultFeignConfig.class)
@EnableFeignClients(basePackages = "com.hmall.api.client", defaultConfiguration = DefaultFeignConfig.class)
@MapperScan("com.hmall.pay.mapper")
@SpringBootApplication
public class PayApplication {public static void main(String[] args) {SpringApplication.run(PayApplication.class, args);}
}

3.配置全局id

3.1SpringMvc拦截器

在网关和OpenFeign中我们已经将用户id放到了请求头user-info中,而所有的微服务,都需要依赖常量模块common,故我们在common模块中,定义SpringMVC拦截器,获取userId,保存到TreadLocal中。

这里可能有人会问,为什么不在网关过滤器中直接将用户id保存在TreadLocal中呢?,而是放到请求头中,在common模块中,定义拦截器拿到用户id,在保存TreadLocal中。这就不得不提一下TreadLocal的特性了

ThreadLocal 是 Java 中的一个工具,它为每个线程提供独立的变量副本,使得同一个线程在不同地方访问 ThreadLocal 变量时都能得到相同的数据,而不同线程之间不会相互影响。然而,ThreadLocal 的作用范围仅限于当前 JVM(Java 虚拟机)中的线程,并且它的生命周期与线程的生命周期绑定

在微服务架构中,网关和各个微服务通常是独立部署的应用程序它们可能运行在不同的进程中,甚至是在不同的服务器上。因此,当你在一个微服务(如网关)中使用 ThreadLocal 来保存用户信息时,这些信息不会自动传递到其他微服务中

在common模块中定义拦截器

import cn.hutool.core.util.StrUtil;
import com.hmall.common.utils.UserContext;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class UserInfoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.获取请求头中的用户信息String userInfo = request.getHeader("user-info");// 2.判断是否为空if (StrUtil.isNotBlank(userInfo)) {// 不为空,保存到ThreadLocalUserContext.setUser(Long.valueOf(userInfo));}// 3.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 移除用户UserContext.removeUser();}
}

 添加拦截器

import com.hmall.common.interceptors.UserInfoInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());}
}

不过,需要注意的是,这个配置类默认是不会生效的,因为它所在的包是common模块,因为common模块中的扫描包路径与其它微服务的扫描包不一致,且常量模块中,没有单独的SpringBootApplication启动类,无法被扫描到,因此无法生效。


基于SpringBoot的自动装配原理,我们要将其添加到resources目录下的META-INF/spring.factories文件中:

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

注解: @ConditionalOnClass(DispatcherServlet.class)

DispatcherServlet 是 Spring MVC 的核心组件,负责接收和分发 HTTP 请求到相应的控制器。因此,当应用程序是基于 Spring MVC 构建时,类路径中必然包含 DispatcherServlet

@ConditionalOnClass 用于自动配置类中,以确保该拦截器只有在处理http请求时才生效,拦截。

3.2TreadLocal

package com.hmall.common.utils;public class UserContext {private static final ThreadLocal<Long> tl = new ThreadLocal<>();/*** 保存当前登录用户信息到ThreadLocal* @param userId 用户id*/public static void setUser(Long userId) {tl.set(userId);}/*** 获取当前登录用户信息* @return 用户id*/public static Long getUser() {return tl.get();}/*** 移除当前登录用户信息*/public static void removeUser(){tl.remove();}
}

http://www.dinnco.com/news/38760.html

相关文章:

  • 网站建设网络推广最低价格金城武重庆森林经典台词
  • 国家知识产权局招聘2023公告seo什么意思中文意思
  • 网站建设宀金手指花总十五seo关键词排名优化软件
  • php网站开发视频什么是网站外链
  • 杏坛网站制作短视频平台推广
  • 网站 数据库模板seo助手
  • 代办公司合法吗seo推广公司排名
  • 牛网站培训后的收获和感想
  • 泾川门户网厦门seo外包
  • 访问不到自己做的网站搜索关键词热度
  • 专门做设计的网站seo综合优化公司
  • 软件开发工程师和程序员的区别seo门户网站
  • iis 建设网站seo推广招聘
  • 出色的网站站长工具网址查询
  • 怎么做链接网站天津外贸seo推广
  • 织梦五彩婚纱源码网_婚庆策划网站php源码企业网站模板源码
  • 网站文章正文可以做内链吗谷歌官方网站登录入口
  • 专门做家具网站百度seo快速排名
  • 自己做的网站加入购物车价格怎么联系百度人工服务
  • 网站建设制作包括哪些网络营销外包推广定制公司
  • 做bc网站搜索引擎优化课程
  • 定制网站建设宝安西乡网站开发建设步骤
  • 公司做网站的优点seo综合检测
  • 深圳营销网站建设公司百度指数的搜索指数代表什么
  • 瑞安网站制作河北网站建设制作
  • 做网站怎么入账营销型网站建站
  • 高端营销网站下载百度免费版
  • 企业网站功能间联系营销背景包括哪些内容
  • 东营市住房和城乡建设管理局网站湖南网站营销seo方案
  • 做装饰网站公司今天新闻最新消息