怎样创造自己的网站,html静态网站作品,网站以前在百度能搜索不到了,东莞制作网站公司哪家好目录 Nacos 简介
Nacos 的特点
Nacos 的使用步骤可以查看黑马教程文档#xff1a;#xfeff;#xfeff;#xfeff;#xfeff;#xfeff;#xfeff;#xfeff;day03-微…目录 Nacos 简介
Nacos 的特点
Nacos 的使用步骤可以查看黑马教程文档day03-微服务01 - 飞书云文档 (feishu.cn)
OpenFeign 的使用步骤
Feign Logger.Level 的选项
网关
自定义过滤器拦截器
网关到微服务的用户传递
META-INF是什么
微服务之间的用户传递
配置管理 如何进行配置管理
如果进行热部署更新
更新路由
微服务保护和分布式管理
雪崩问题
sentinel是什么
如何使用sentinel
熔断的具体实现步骤
主要逻辑
如何解决雪崩问题
分布式事务多个服务或数据库之间数据一致性的问题
编辑
什么事seata
XA模式
AT模式 Nacos 简介
Nacos 是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台。它在微服务架构中常被用作服务注册中心和配置中心。 Nacos 的特点
服务发现与注册支持 DNS 和 HTTP 协议的服务发现。动态配置管理支持实时动态配置刷新。
Nacos 的使用步骤可以查看黑马教程文档day03-微服务01 - 飞书云文档 (feishu.cn)
通常Nacos会和OpenFeign结合使用 更加方便
OpenFeign的产生就是为了让远程调用像本地方法调用一样简单。
使用步骤
1.引入服务注册和服务发现的依赖
!--nacos 服务注册发现--
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId
/dependency
!--nacos 服务注册发现--
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId
/dependency
2. 配置Nacos地址
spring:cloud:nacos:server-addr: 自己的虚拟机Ip:8848 OpenFeign 的使用步骤 引入依赖 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency开启 Feign 功能 在主类上添加 EnableFeignClients 注解。 SpringBootApplication
EnableFeignClients
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}定义 Feign 客户端 使用 FeignClient 注解标注接口指定调用的服务名称。 FeignClient(name service-name)
public interface MyFeignClient {GetMapping(/api/endpoint)String getEndpoint();
}调用 Feign 接口 注入定义的 Feign 接口并调用方法。 RestController
public class MyController {Autowiredprivate MyFeignClient myFeignClient;GetMapping(/call)public String callService() {return myFeignClient.getEndpoint();}
}如果将这个代理的专门使用一个包提取出来那么我们需要在启动类上面添加扫描包的注解 package com.hmall.pay;import com.hmall.api.config.DefaultFeignConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;MapperScan(com.hmall.pay.mapper)
SpringBootApplication
EnableFeignClients(basePackages com.hmall.api.client ,defaultConfiguration DefaultFeignConfig.class)
public class PayApplication
{public static void main(String[] args) {SpringApplication.run(PayApplication.class, args);}
}在 Spring Boot 的微服务项目中上述代码配置了 defaultConfiguration 属性来指定一个默认的配置类 DefaultFeignConfig它用于 Feign 客户端的默认行为设置。具体来说这是为了增强日志打印功能方便开发者在调用微服务时追踪和调试。
以下是DefaultFeignConfig的内容
package com.hmall.api.config;import feign.Logger;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfig
{Beanpublic Logger.Level feignLoggerLevel(){return Logger.Level.FULL;}
}Feign Logger.Level 的选项
NONE不记录任何日志默认值。BASIC记录请求方法、URL、响应状态码以及执行时间。HEADERS在 BASIC 的基础上记录请求和响应的头信息。FULL记录请求和响应的所有信息包括头、体、元数据。
网关
服务拆分之后面临两大问题
1.服务地址过多前端不知道如何请求谁
2. 每个服务都可以需要登录信息 自定义过滤器拦截器 NettyRoutingFilter 是 Spring Cloud Gateway 中的一个核心过滤器它负责将请求真正路由到目标服务并处理响应的回传。简单来说这是网关在处理请求时实际完成路由和转发的核心组件
网关到微服务的用户传递 网关层的请求拦截 在微服务架构中为了提高安全性和请求处理的一致性需要在网关层对所有请求进行统一拦截。具体要求如下
放行无需登录的请求对于公共接口或资源不进行Token校验直接放行。拦截需要登录的请求对于需要登录的请求检查Request中是否包含有效的Token。 如果Token不存在或无效返回HTTP状态码401 (UNAUTHORIZED)表示用户未登录并终止请求的后续处理调用response.setComplete()。如果Token有效解析Token获取用户的唯一标识如用户ID将该用户ID通过ServerWebExchange注入到请求头中然后继续放行请求。 String id userId.toString();ServerWebExchange swe exchange.mutate().request(build - build.header(user-info, id)).build(); 微服务中如何获取用户ID 通常情况下微服务可以通过读取请求头中的user-info字段获取用户ID。然而如果每个微服务都单独实现一个拦截器会导致代码重复、不便于维护。
为了解决这个问题可以将通用的拦截器逻辑抽取到common模块。所有微服务都引入common模块直接复用其中的拦截器。这种方式可以避免重复开发提高代码的复用性和一致性。但是这个时候springBoot无法扫描到这个拦截器的包因此拦截器不会失效。所以要配置spring.factories 文件
基于Spring Boot的拦截器配置 微服务通常基于Spring Boot而不是传统的Spring MVC。如果直接使用Spring MVC的拦截器在Spring Boot环境下可能会报错。
总结为了解决上述问题可以通过在common模块中为拦截器配置META-INF文件同时在拦截器类上添加ConditionalOnClass(DispatcherServlet.class)注解。这样可以确保拦截器仅在支持Spring MVC的环境中加载从而避免不兼容问题。 META-INF是什么
META-INF 是Java程序的一个特殊目录用于存放配置文件和元数据信息。它通常位于JAR文件的根目录下主要包含以下类型的内容 MANIFEST.MF 文件 Java的清单文件用于描述JAR包的信息。包括主类、版本号、依赖项等。 Spring Boot相关配置 例如spring.factories 文件用于注册自动配置类。格式为键值对可以定义拦截器、过滤器等组件的自动加载逻辑。 服务注册文件 用于SPI服务提供接口机制例如META-INF/services目录下的文件定义了特定接口的实现类。
示例在common模块中的spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration\com.hmall.common.config.MyBatisConfig,\com.hmall.common.config.JsonConfig,\com.hmall.common.config.MvcConfig
微服务之间的用户传递
如果是微服务之间的用户Id传递的话其实获取到的用户id的值是null因为微服务之间的网络请求不是通过网关的所以网关无法在请求头中设置userId其他服务也不可以获取到userId的值了
微服务之间是通过openFeign进行网络请求转发的在转发之前我们是可以获得用户Id的所以我们可以在请求发送之前设置拦截器如果我们在每一个微服务都加一个拦截器太麻烦了。所以我们选择加在专门写FeignClient的模块中hm-api
那么我们应该如何改造转发的请求呢在转发之前我们是可以获取到用户id的所以我们可以借助Feign中提供的一个拦截器接口feign.RequestInterceptor
public interface RequestInterceptor {/*** Called for every request. * Add data using methods on the supplied {link RequestTemplate}.*/void apply(RequestTemplate template);
}我们只需要实现这个接口然后实现apply方法利用RequestTemplate类来添加请求头将用户信息保存到请求头中。这样以来每次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 feignLoggerLevel(){return Logger.Level.FULL;}Beanpublic RequestInterceptor userInfoRequestInterceptor(){return new RequestInterceptor() {Overridepublic void apply(RequestTemplate requestTemplate) {// 获取用户IdLong user UserContext.getUser();if(user null) {// 如果为空则直接跳过return;}// 存入请求头当中requestTemplate.header(user-info,user.toString());}};}}网关部分用户身份校验并将用户信息存入请求头。微服务部分使用拦截器提取用户信息存入 ThreadLocal微服务间通过 OpenFeign 的 RequestInterceptor 传递用户信息。
配置管理
在微服务架构中服务数量众多且配置管理复杂常常导致重复代码和维护成本增加。通过 Nacos 的配置管理功能我们能够实现配置的统一管理和动态更新提升开发效率并减少运维压力。
在微服务架构中每个服务都需要独立管理自己的配置文件例如数据库连接JDBC、日志配置、Swagger 接口文档配置等。这些配置中往往存在大量重复内容既增加了维护成本也容易引发配置不一致问题。 Nacos 是一款集服务注册与配置管理于一体的工具通过将公共配置提取到 Nacos 中并实现动态加载可以有效减少代码冗余、降低维护难度并支持配置实时更新。 如何进行配置管理
引入 Maven 依赖
在 Spring Boot 项目中添加以下依赖 !--nacos配置管理--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId/dependency!--读取bootstrap文件--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-bootstrap/artifactId/dependency
2. 在Nacos网址上面添加配置分别提取jdbc-mysql配置swagger配置日志的配置
jdbc共享配置
spring:datasource:url: jdbc:mysql://${hm.db.host:192.168.88.130}:${hm.db.port:3306}/${hm.db.database}?useUnicodetruecharacterEncodingutf8zeroDateTimeBehaviorconvertToNullserverTimezoneGMT%2B8useSSLfalseallowPublicKeyRetrievaltrueautoReconnecttruefailOverReadOnlyfalsedriver-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:- com.hmall.cart.controller- ${hm.swagger.package} 3. 创建bootstrap.yaml 公共配置是动态的所以我们需要在 bootstrap.yaml进行配置
必须配置其 spring: application: nameprofiles: active: cloud:nacos:config:extension
spring:application:name: cart-service # 服务名称profiles:active: devcloud:nacos:server-addr: 192.168.88.130 # nacos地址config:file-extension: yaml # 文件后缀名shared-configs: # 共享配置- dataId: shared-jdbc.yml # 共享mybatis配置- dataId: shared-log.yml # 共享日志配置- dataId: shared-swagger.yml # 共享日志配置
注意这里的shared-configs的dataId的配置名一定要和Nacos里面的一模一样 ,如果 dataId 与 Nacos 中的配置名称不一致服务将无法加载到对应的共享配置从而导致启动失败或无法正确读取配置
4. 剩余部分就需要在application.yaml里面配置
server:port: 8082
feign:okhttp:enabled: true # 开启OKHttp连接池支持
hm:swagger:title: 购物车服务接口文档package: com.hmall.cart.controllerdb:host: 192.168.88.130 # 修改为你自己的虚拟机IP地址database: hm-cart如果进行热部署更新 进入Nacos网站http://192.168.88.130:8848/nacos 开始添加配置 使用默认的 应用名称.yaml例如cart-service.yaml这样无需显式在 bootstrap.yaml 中指定 dataId
什么是默认的
应用名称作为默认 Data ID Spring Boot 项目的 spring.application.name 属性会作为 Nacos 配置的默认 Data ID。
例如 如果你的 bootstrap.yaml 配置如下
spring:application:name: cart-servicecloud:nacos:server-addr: 192.168.88.130:8848那么 Nacos 会自动尝试加载以下文件作为配置
Data ID: cart-service.yaml
Group: DEFAULT_GROUP优先加载的文件格式 默认情况下Nacos 会加载和 spring.cloud.nacos.config.file-extension 对应的文件格式默认为 yaml。 无需显式指定 Data ID 只要 Nacos 配置文件的 Data ID 与 spring.application.name 一致并以 .yaml 作为后缀就会被自动加载而无需手动在 bootstrap.yaml 中声明 shared-configs 或特定 dataId。 配置项前缀匹配prefix 指定的值必须在配置文件中明确存在。例如hm.cart 对应的配置项必须是以下形式之一
在对应的yml 中配置如下 hm:cart:maxAmount: 10此时对应的配置类的注解ConfigurationProperties(prefix hm.cart)的prefix必须是hm.cart
package com.hmall.cart.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;Data
Component
ConfigurationProperties(prefix hm.cart)
public class CartProperties {private Integer maxAmount;
}更新路由 微服务保护和分布式管理
雪崩问题 sentinel是什么
Sentinel 是阿里巴巴开源的一款用于分布式系统的流量控制和熔断降级的中间件。它主要用于保护微服务的稳定性帮助应对高并发场景下的流量突增或服务调用异常。
Sentinel 提供了灵活的流量控制规则和强大的监控能力是 Spring Cloud Alibaba 技术栈中的核心组件之一用于服务治理和高可用保障。
如何使用sentinel
1. 引入依赖
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactIdversion2021.0.3.0/version
/dependency2. 连接sentinel-dashboard控制台需要配置控制台修改application.yaml文件添加下面内容
spring:cloud: sentinel:transport:dashboard: localhost:8090
3. 由于我们的SpringMVC接口是按照Restful风格设计因此购物车的查询、删除、修改等接口全部都是/carts路径所以我们需要在application.yaml里面添加 http-method-specify: true # 开启请求方式前缀
spring:cloud:sentinel:transport:dashboard: 127.0.0.1:8090http-method-specify: true # 开启请求方式前缀
详细请点击黑马教程day05-服务保护和分布式事务 - 飞书云文档 (feishu.cn)
接下来详细介绍一下熔断的解决办法 熔断的具体实现步骤
步骤 1配置 Sentinel 的熔断规则
在 Sentinel 可视化控制台 中配置熔断规则基于
异常比例当调用失败率超过设定值时触发。异常数当调用失败总数超过设定值时触发。响应时间当接口响应时间超过设定值时触发。
示例
熔断条件某接口失败率 50% 且调用量 10在 1 分钟内触发熔断。熔断恢复在熔断 5 秒后恢复尝试。 步骤 2编写 FallbackFactory
当服务触发熔断时FallbackFactory 提供降级逻辑。正常会去调用ItemClient接口但是当ItemClinet接口对应的Controller的处理出现异常或者请求被限流了就会走这个fallback”备选方案“它也会创建一个ItemClient去返回一些提示信息。以 ItemClientFactoryFallback 为例
主要逻辑
实现 FallbackFactory 接口。在 create 方法中捕获异常信息 Throwable。定义服务降级逻辑 非关键业务返回默认值如返回空集合。关键业务抛出业务异常触发事务回滚确保数据一致性。
代码解读
package com.hmall.api.fallback;import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.exception.BizIllegalException;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;import java.util.Collection;
import java.util.List;Slf4j
public class ItemClientFactoryFallback implements FallbackFactoryItemClient {Overridepublic ItemClient create(Throwable cause) {return new ItemClient() {Overridepublic ListItemDTO queryItemByIds(CollectionLong ids) {log.error(远程调用ItemClient#queryItemByIds方法出现异常参数{}, ids, cause);// 查询购物车允许失败查询失败返回空集合return CollUtils.emptyList();}Overridepublic void deductStock(ListOrderDetailDTO items) {// 库存扣减业务需要触发事务回滚查询失败抛出异常throw new BizIllegalException(cause);}};}
}
步骤 3在配置类中注册为 Bean
原因
默认情况下Spring Boot 不会扫描非显式标注为 Component 的类。需要显式将 FallbackFactory 注册为 Bean才能生效。
代码解读
在 DefaultFeignConfig 配置类中 注册 ItemClientFactoryFallback
package com.hmall.api.config;import com.hmall.api.fallback.ItemClientFactoryFallback;
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 feignLoggerLevel(){return Logger.Level.FULL;}Beanpublic RequestInterceptor userInfoRequestInterceptor(){return new RequestInterceptor() {Overridepublic void apply(RequestTemplate requestTemplate) {// 获取用户IdLong user UserContext.getUser();if(user null) {// 如果为空则直接跳过return;}// 存入请求头当中requestTemplate.header(user-info,user.toString());}};}// 注册为BeanBeanpublic ItemClientFactoryFallback itemClientFallbackFactory(){return new ItemClientFactoryFallback();}}步骤 4在服务接口中绑定降级逻辑
使用 FeignClient 注解绑定服务并指定
value目标微服务名称。fallbackFactory对应的 FallbackFactory 类。configuration自定义的 Feign 配置类。
代码解读
FeignClient(value item-service,fallbackFactory ItemClientFactoryFallback.class,configuration DefaultFeignConfig.class
)
public interface ItemClient {GetMapping(/items)ListItemDTO queryItemByIds(RequestParam(ids) CollectionLong ids);PostMapping(/stock/deduct)void deductStock(RequestBody ListOrderDetailDTO items);
}如何解决雪崩问题 快速失败 熔断器在触发后立即返回降级结果避免资源被耗尽。 默认降级逻辑 通过 FallbackFactory 提供兜底逻辑为非关键业务返回默认值降低错误扩散的影响。 保护核心业务 关键业务如库存扣减触发异常并回滚确保数据一致性。 监控与恢复 Sentinel 自动监控系统恢复状态当异常比例降低时自动关闭熔断器恢复正常调用。
分布式事务多个服务或数据库之间数据一致性的问题
day05-服务保护和分布式事务 - 飞书云文档 (feishu.cn) 什么事seata
SeataSimple Extensible Autonomous Transaction Architecture是阿里巴巴开源的一款分布式事务解决方案。它为分布式系统中的事务一致性问题提供了简单、高效的解决方案支持多种事务模型帮助开发者轻松实现分布式事务。
在微服务架构中各服务通常独立部署拥有独立的数据库。这种设计虽然带来了高可用性和扩展性但也引入了分布式事务问题如跨服务的数据一致性。Seata 专注于保证事务的一致性。 XA模式 首先我们可以在Nacos中的共享shared-seata.yaml配置文件中设置
seata: data-source-proxy-mode: XA
然后我们要利用GlobalTransactional标记分布式事务的入口方法即可 AT模式 RabbitMQ
详细查看请查看RabbitMQ高级篇-CSDN博客