网站推广费用ihanshi,寻找哈尔滨网站建设,国内优秀设计网站站长,中国机械设备采购网之前学习了Nacos#xff0c;用于发现并注册、管理项目里所有的微服务#xff0c;而OpenFeign简化微服务之间的通信#xff0c;而为了使得前端可以使用微服务项目里的每一个微服务的接口#xff0c;就应该将所有微服务的接口管理起来方便前端调用#xff0c;所以有了网关。…之前学习了Nacos用于发现并注册、管理项目里所有的微服务而OpenFeign简化微服务之间的通信而为了使得前端可以使用微服务项目里的每一个微服务的接口就应该将所有微服务的接口管理起来方便前端调用所以有了网关。
前端调用后端微服务项目的接口时不需要指定每一个接口具体的地址只需要将请求发送到后端的网关即可。
网关介绍
网关是网络的关口负责请求的路由、转发、身份校验 。 网关模块的配置
1、新建一个maven空模块配置一下依赖
dependencies
......!-- 其它依赖 --!--网关--
dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId
/dependency !--nocos discovery--
dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId
/dependency !--负载均衡--
dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-loadbalancer/artifactId
/dependency /dependencies
build finalName${project.artifactId}/finalName plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins
/build
2、创建com.XXX项目名称.gateway包报下名新建配置类
SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}
3、在静态资源目录下新建application.yaml文件配置网关相关属性
server:port: 8080 # 网关服务的端口号指定网关运行在 8080 端口
spring:application:name: gateway # 应用名称注册到 Nacos 的服务名称cloud:nacos:server-addr: 192.168.52.128:8848 # Nacos 服务器地址配置 Nacos 注册中心地址gateway:routes: # 路由配置- id: item-service # 路由 ID唯一标识可以随便命名uri: lb://item-service # 目标服务地址即从注册中心获取 item-service 的地址predicates: # 断言即路由转发的规则- Path/items/**,/search/** # 匹配 /items/ 开头的和 /search/ 开头的请求到 item-service 服务获取响应- id: user-service uri: lb://user-service predicates: - Path/items/**,/search/**
4、最后启动整个项目的时候也要把网关启动
由下图可见网关的效果有了 网关的登录校验 网关过滤器有两种分别是
GatewayFilter: 路由过滤器作用于任意指定的路由默认不生效要配置到路由后生效。GlobalFilter: 全局过滤器作用范围是所有路由声明后自动生效。
网关加公共依赖XXX-common实现请求的校验
1、网关过滤器过滤请求Filters文件夹
Component // 将该类标记为Spring组件使其成为Spring容器管理的Bean
RequiredArgsConstructor // Lombok注解自动生成一个包含所有final字段的构造函数
public class AuthGlobalFilter implements GlobalFilter, Ordered {// 依赖注入JwtTool用于JWT的解析和验证private final JwtTool jwtTool;// 依赖注入AuthProperties包含认证相关的配置信息如排除路径等private final AuthProperties authProperties;// AntPathMatcher用于路径匹配判断请求路径是否在排除路径中private final AntPathMatcher antPathMatcher new AntPathMatcher();Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 获取当前请求对象ServerHttpRequest request exchange.getRequest();// 2. 判断请求路径是否需要登录拦截if (isExclude(request.getPath().toString())) {// 如果路径在排除列表中直接放行不进行拦截return chain.filter(exchange);}// 3. 从请求头中获取tokenString token null;ListString headers request.getHeaders().get(authorization);if (headers ! null !headers.isEmpty()) {token headers.get(0); // 获取第一个authorization头通常为Bearer Token}// 4. 校验并解析tokenLong userId null;try {// 使用JwtTool解析token获取用户IDuserId jwtTool.parseToken(token);} catch (UnauthorizedException e) {// 如果token无效或解析失败拦截请求并返回401 Unauthorized状态码ServerHttpResponse response exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete(); // 结束请求处理}// 打印用户ID通常用于调试生产环境中不建议直接打印敏感信息System.out.println(userId userId);String userInfo userId.toString();// 将用户信息存入请求头ServerWebExchange swe exchange.mutate().request(builder - builder.header(user-info, userInfo)).build();// 5. 如果token有效继续执行后续的过滤器链return chain.filter(swe);}// 判断请求路径是否在排除路径列表中private boolean isExclude(String path) {for (String pathPattern : authProperties.getExcludePaths()) {// 使用AntPathMatcher进行路径匹配if (antPathMatcher.match(pathPattern, path)) {return true; // 如果匹配到排除路径返回true}}return false; // 否则返回false}Overridepublic int getOrder() {// 返回过滤器的执行顺序0表示最高优先级return 0;}
} 过滤器里涉及的一些依赖
// jwt校验工具
Component
public class JwtTool {private final JWTSigner jwtSigner;public JwtTool(KeyPair keyPair) {this.jwtSigner JWTSignerUtil.createSigner(rs256, keyPair);}public String createToken(Long userId, Duration ttl) {// 1.生成jwsreturn JWT.create().setPayload(user, userId).setExpiresAt(new Date(System.currentTimeMillis() ttl.toMillis())).setSigner(jwtSigner).sign();}/*** 解析token** param token token* return 解析刷新token得到的用户信息*/public Long parseToken(String token) {// 1.校验token是否为空if (token null) {throw new UnauthorizedException(未登录);}// 2.校验并解析jwtJWT jwt;try {jwt JWT.of(token).setSigner(jwtSigner);} catch (Exception e) {throw new UnauthorizedException(无效的token, e);}// 2.校验jwt是否有效if (!jwt.verify()) {// 验证失败throw new UnauthorizedException(无效的token);}// 3.校验是否过期try {JWTValidator.of(jwt).validateDate();} catch (ValidateException e) {throw new UnauthorizedException(token已经过期);}// 4.数据格式校验Object userPayload jwt.getPayload(user);if (userPayload null) {// 数据为空throw new UnauthorizedException(无效的token);}// 5.数据解析try {return Long.valueOf(userPayload.toString());} catch (RuntimeException e) {// 数据格式有误throw new UnauthorizedException(无效的token);}}
}// 拦截器拦截
Data
Component
ConfigurationProperties(prefix hm.auth)
public class AuthProperties {private ListString includePaths;private ListString excludePaths;
}
2、网关的yaml文件里配置不需要校验直接放行的请求
hm:jwt: #解析jwt密钥文件location: classpath:hmall.jksalias: hmallpassword: hmall123tokenTTL: 30mauth:excludePaths:- /search/**- /users/login- /items/**- /hi
3、由于每一个微服务都导入了XX-common模块的依赖所以在XX-common模块里配置并注册拦截器拦截所有发送到每个微服务里的请求用于将请求头里用户信息存入线程池。
public class UserInfoInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1. 获取登录用户信息String userInfo request.getHeader(user-info); // 从请求头里获取// 2. 判断是否获取了用户如果有存入ThreadLocalif (StrUtil.isNotBlank(userInfo)) {UserContext.setUser(Long.valueOf(userInfo));}// 3. 放行return true;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 清理用户UserContext.removeUser();}
} 4、注册XX-common模块里的拦截器
Configuration
ConditionalOnClass(DispatcherServlet.class) // 使得网关不去生效改拦截器
public class MvcConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());// 默认拦截所有的请求目的是为了将每一个请求里包含的用户信息存入线程池}
}
5、配置静态资源文件夹下的spring.factories文件取保每个微服务可以读取到XX-common模块里的拦截器
org.springframework.boot.autoconfigure.EnableAutoConfiguration\com.hmall.common.config.MyBatisConfig,\com.hmall.common.config.MvcConfig,\com.hmall.common.config.JsonConfig
OpenFeign传递用户信息
使用OpenFeign时一个微服务发送给另一个微服务的请求也要携带用户信息到请求头里要和网关发送给微服务的请求一样。所有要在公共api模块里加拦截器使得每一个请求的请求头里添加用户信息。
写到OpenFeign的配置类里且微服务的启动类加上EnableFeignClients(basePackages com.hmall.api.client, defaultConfiguration DefaultFeignConfig.class)的注解 // 写到OpenFeign的配置类里且微服务的启动类加上
// EnableFeignClients(basePackages com.hmall.api.client,
// defaultConfiguration DefaultFeignConfig.class)的注解
Bean // 声明为一个Bean可以被Spring容器管理public RequestInterceptor userInfoRequestInterceptor() {return new RequestInterceptor() {Overridepublic void apply(RequestTemplate template) {// 获取当前用户的IDLong userId UserContext.getUser(); // 导入XXX-common模块里的线程池// 如果用户ID不为空则添加到请求头中if (userId ! null) { // 确保每一个微服务之间发送的请求也携带user-info到请求头里// 将用户ID添加到请求头中key为user-infoSystem.out.println(将用户ID添加到请求头中key为user-info,id为 userId);template.header(user-info, userId.toString());}}};} nacos共享配置
由于每一个微服务的yaml文件里有多个共同的配置信息所有可以将其抽取出来的配置共同使用nacos注册中心配置。 每一个微服务里导入如下依赖即可实现。
!-- nacos配置管理 --
dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-config/artifactId
/dependency
!-- 读取bootstrap文件 --
dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-bootstrap/artifactId
/dependency
nacos里共同配置的信息${XXX:YY}表示如果读取不到XXX则默认为YY
# 数据库和mybatis
spring:datasource:url: jdbc:mysql://${hm.db.host:192.168.52.128}:${hm.db.port:3306}/${hm.db.database}?useUnicodetruecharacterEncodingUTF-8autoReconnecttrueserverTimezoneAsia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: ${hm.db.un:root}password: ${hm.db.pw:123}
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandlerglobal-config:db-config:update-strategy: not_nullid-type: auto# 日志记录
logging:level:com.hmall: debugpattern:dateformat: HH:mm:ss:SSSfile:path: logs/${spring.application.name}# swagger配置
knife4j:enable: trueopenapi:title: ${hm.swagger.title:黑马商城接口文档}description: ${hm.swagger.desc:黑马商城接口文档}email: zhanghuyiitcast.cnconcat: 虎哥url: https://www.itcast.cnversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- ${hm.swagger.package}
拉取nacos里的配置文件到本地微服务以下为bootstrap.yaml文件
spring: main: additional-properties: --add-opensjava.base/java.lang.invokeALL-UNNAMED application: # 应用程序名称用于标识该服务在Nacos或其他服务注册中心中可用到 name: cart-service cloud: nacos: # Nacos的服务地址用于连接到Nacos服务器 server-addr: localhost:8848 # nacos地址 config: # 配置文件的格式这里指定为YAML格式 file-extension: yaml # 定义共享配置文件列表这些配置将从Nacos服务器加载 shared-configs: # 一定对应好nacos里的Data ID- data-id: shared-jdbc.yaml # JDBC共享配置文件 - data-id: shared-log.yaml # 日志共享配置文件 - data-id: shared-swagger.yaml # Swagger共享配置文件
nacos配置里的变量在本地微服务里配置好以下为application.yaml文件
server:port: 8082
feign:okhttp:enabled: true
hm:db:database: hm-cartswagger:title: 黑马城市购物车服务接口文档package: com.hmall.cart.controller
配置热更新
配置热更新修改配置文件里的配置的时候不需要重新启动微服务项目配置就可以生效配置。
具体应用实例
需求购买车的限定数量目前是写死在业务中的将其改为读取配置文件属性并将配置置交给Nacos管理实现热更新。 首先在nocas配置要限定数量所在的微服务的yaml文件 之后在对应的微服务里添加config文件
Data
Component
ConfigurationProperties(prefix hm.cart) // 对应yaml文件里的配置
public class CartProperties {private Integer maxItems;
}
最后在业务文件里面就可以去使用了
private final CartProperties cartProperties; // 导入依赖
......private void checkCartsFull(Long userId) {int count lambdaQuery().eq(Cart::getUserId, userId).count();if (count cartProperties.getMaxItems()) {throw new BizIllegalException(StrUtil.format(用户购物车课程不能超过{}, cartProperties.getMaxItems()));}}
...... 文章转载自: http://www.morning.kxxld.cn.gov.cn.kxxld.cn http://www.morning.xwlmr.cn.gov.cn.xwlmr.cn http://www.morning.rzjfn.cn.gov.cn.rzjfn.cn http://www.morning.banzou2034.cn.gov.cn.banzou2034.cn http://www.morning.qrwdg.cn.gov.cn.qrwdg.cn http://www.morning.brhxd.cn.gov.cn.brhxd.cn http://www.morning.mtsgx.cn.gov.cn.mtsgx.cn http://www.morning.rntyn.cn.gov.cn.rntyn.cn http://www.morning.brxzt.cn.gov.cn.brxzt.cn http://www.morning.bqyb.cn.gov.cn.bqyb.cn http://www.morning.gqryh.cn.gov.cn.gqryh.cn http://www.morning.nywrm.cn.gov.cn.nywrm.cn http://www.morning.xmxbm.cn.gov.cn.xmxbm.cn http://www.morning.nhzps.cn.gov.cn.nhzps.cn http://www.morning.fyglg.cn.gov.cn.fyglg.cn http://www.morning.rtkgc.cn.gov.cn.rtkgc.cn http://www.morning.jgnjl.cn.gov.cn.jgnjl.cn http://www.morning.jlpdc.cn.gov.cn.jlpdc.cn http://www.morning.rwwdp.cn.gov.cn.rwwdp.cn http://www.morning.cyfsl.cn.gov.cn.cyfsl.cn http://www.morning.fkwp.cn.gov.cn.fkwp.cn http://www.morning.npfkw.cn.gov.cn.npfkw.cn http://www.morning.mhfbf.cn.gov.cn.mhfbf.cn http://www.morning.dmlsk.cn.gov.cn.dmlsk.cn http://www.morning.jjwt.cn.gov.cn.jjwt.cn http://www.morning.lsfrc.cn.gov.cn.lsfrc.cn http://www.morning.rfxg.cn.gov.cn.rfxg.cn http://www.morning.wwnb.cn.gov.cn.wwnb.cn http://www.morning.bxdlrcz.cn.gov.cn.bxdlrcz.cn http://www.morning.spkw.cn.gov.cn.spkw.cn http://www.morning.grnhb.cn.gov.cn.grnhb.cn http://www.morning.ltqtp.cn.gov.cn.ltqtp.cn http://www.morning.ejknty.cn.gov.cn.ejknty.cn http://www.morning.cgtfl.cn.gov.cn.cgtfl.cn http://www.morning.dyxzn.cn.gov.cn.dyxzn.cn http://www.morning.rscrj.cn.gov.cn.rscrj.cn http://www.morning.lpnpn.cn.gov.cn.lpnpn.cn http://www.morning.mxmzl.cn.gov.cn.mxmzl.cn http://www.morning.bangaw.cn.gov.cn.bangaw.cn http://www.morning.mhmsn.cn.gov.cn.mhmsn.cn http://www.morning.kxnnh.cn.gov.cn.kxnnh.cn http://www.morning.qrksj.cn.gov.cn.qrksj.cn http://www.morning.zsrdp.cn.gov.cn.zsrdp.cn http://www.morning.zwdrz.cn.gov.cn.zwdrz.cn http://www.morning.shnqh.cn.gov.cn.shnqh.cn http://www.morning.zcxjg.cn.gov.cn.zcxjg.cn http://www.morning.rjmb.cn.gov.cn.rjmb.cn http://www.morning.bcngs.cn.gov.cn.bcngs.cn http://www.morning.hlwzd.cn.gov.cn.hlwzd.cn http://www.morning.sdktr.com.gov.cn.sdktr.com http://www.morning.fhwfk.cn.gov.cn.fhwfk.cn http://www.morning.gnmhy.cn.gov.cn.gnmhy.cn http://www.morning.srcth.cn.gov.cn.srcth.cn http://www.morning.tlfzp.cn.gov.cn.tlfzp.cn http://www.morning.hytr.cn.gov.cn.hytr.cn http://www.morning.rhchr.cn.gov.cn.rhchr.cn http://www.morning.kxnnh.cn.gov.cn.kxnnh.cn http://www.morning.nmbbt.cn.gov.cn.nmbbt.cn http://www.morning.fbzyc.cn.gov.cn.fbzyc.cn http://www.morning.pgggs.cn.gov.cn.pgggs.cn http://www.morning.qxkcx.cn.gov.cn.qxkcx.cn http://www.morning.zxxys.cn.gov.cn.zxxys.cn http://www.morning.mzgq.cn.gov.cn.mzgq.cn http://www.morning.qkgwz.cn.gov.cn.qkgwz.cn http://www.morning.xsklp.cn.gov.cn.xsklp.cn http://www.morning.hdpcn.cn.gov.cn.hdpcn.cn http://www.morning.btmwd.cn.gov.cn.btmwd.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.thbnt.cn.gov.cn.thbnt.cn http://www.morning.xhklb.cn.gov.cn.xhklb.cn http://www.morning.yfddl.cn.gov.cn.yfddl.cn http://www.morning.lbbrw.cn.gov.cn.lbbrw.cn http://www.morning.rstrc.cn.gov.cn.rstrc.cn http://www.morning.mysmz.cn.gov.cn.mysmz.cn http://www.morning.gyjld.cn.gov.cn.gyjld.cn http://www.morning.pmptm.cn.gov.cn.pmptm.cn http://www.morning.hsflq.cn.gov.cn.hsflq.cn http://www.morning.byrlg.cn.gov.cn.byrlg.cn http://www.morning.kdldx.cn.gov.cn.kdldx.cn http://www.morning.qysnd.cn.gov.cn.qysnd.cn