谷粒商城项目|微服务架构的一些与思考&&解决跨域问题
1.微服务架构的组成每部分的作用
2.还有其他的微服务架构模式吗
3.微服务服务交互的方式
1)grpc
2)rest api
4.微服务网关与API网关?
5.注册中心比较(Nacos与Eureka)
Nacos
Nacos 是阿里巴巴开源的项目,Nacos 支持基于 DNS 和基于 RPC 的服务发现
Eureka
Eureka 是 Spring Cloud 体系中的一部分,已经停止维护且功能相对单一,主要提供服务注册与发现
//具体场景-将某一个服务注册到注册中心
服务在application.properties配置配置中心服务器地址和服务的名字。
@EnableDiscoveryClient开启服务注册与发现功能
如果用Eureka该怎么实现
5.Nacos实现注册中心的流程
大致流程相同 使用@EnableEurekaServer注释
6.Nacos与Eureka底层实现的不同?
CAP原理:
二者对CAP原理的侧重性不同
一致性(Consistency): 所有节点在同一时间具有相同的数据。
可用性(Availability): 每个请求都能收到一个响应,无论它是成功或失败的响应
分区容忍性(Partition tolerance): 系统应该能够持续提供服务,即使出现了网络分区,也就是说,某些节点之间的通信可能失败或延迟,但系统仍需继续运行。
Nacos侧重:Nacos遵循AP和CP原则
AP(可用性):读多写少
CP(一致性):秒杀服务
Eureka侧重:遵循AP原则,在网络分区发生时优先保证可用性。
7.Nacos集群
配置中心比较(Nacos与Config)
1.配置中心存储哪些数据
配置中心创建application.properties存储配置
数据源信息
微服务名称
日志和监控配置
密钥
2.使用流程
coupons模块创建bootstrap.yml
在coupons模块中创建/src/main/resources/bootstrap.yml,优先级别application.properties高
问题:nacos配置要先于yml,但如果尚未读取yml,又如何得知nacos地址并获取nacos配置呢?
答案:因此spring引入了一种新的配置文件:bootstrap.yml文件,优先级高于application.yml,会在application.yml之前被读取。
使用@Value获取配置文件中的值
使用@RefershScope获取配置中心最新的值
3.配置中心的基本概念
命名空间:微服务之间配置隔离 每个微服务抽取一个配置
支持加载多配置 比如每个业务的数据源分离开,mybatis分离开等等
/具体场景
如果用Config该怎么实现,有什么缺点
创建Config Server 将配置文件放在git上,Config Server 一个git地址
客户端开通服务
通过暴露的/actuator/refresh端点来刷新配置
4.Nacos与Config区别?
有自己的配置管理界面,配置存储在Nacos服务器
5.为什么要选Nacos?
有自己的配置管理界面,配置存储在Nacos服务器,可以进行配置的版本历史、回滚、监听
6.Nacos有可能在什么场景下出现什么问题
在大规模服务和配置的场景下,Nacos需要处理大量的请求。
问题:响应变慢,处理能力达到瓶颈。
在生产环境中,Nacos通常部署为集群以确保高可用。
问题:集群节点之间的数据不一致,或者当一个节点失败时,服务不可用。
解决办法:
监控和故障恢复:
实时监控:对Nacos集群的健康状态、性能指标和日志进行实时监控。
故障转移和恢复:确保有故障转移机制,在节点或服务失败时可以快速恢复。
负载均衡和扩容:
负载均衡:确保请求合理分配到各个节点,避免单点过载。
集群扩容:在高并发场景下,适时对集群进行扩容,增加节点以分散负载。
网关比较(GateWay与Zuul)
1.网关的作用
1)将前端的请求动态的路由到每一个服务
2)网关动态地管理,他能从注册中心中实时地感知某个服务上线还是下线。
3)请求也要加上询问权限,看用户有没有权限访问这个请求
2.网关的核心概念 工作流程
Route路由: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true.发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,
Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.就是java里的断言函数,匹配请求里的任何信息,包括请求头等。根据请求头路由哪个服务
Filter过滤: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.过滤器请求和响应都可以被修改。
客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。
1).具体场景
gateway 配置路由:
前端将请求发送至网关服务器
gateway:
routes:
- id: baidu_route # 每一个路由的名字,唯一即可
uri: https://www.baidu.com # 匹配后提供服务的路由地址
predicates: # 断言规则
- Query=url,baidu #如果url参数等于baidu 符合断言,转到uri
如果用Zuul该怎么实现
如果是Zuul进行相似的配置即可
GateWay的好处是什么
什么是I/O操作 网关什么时候需要发起I/O操作
磁盘I/O:涉及到数据在内存和磁盘(或其他永久存储设备)之间的传输。例如,从硬盘读取文件数据到内存,或将数据从内存写入硬盘。
网络I/O:涉及到数据在内存和网络之间的传输。例如,从互联网上下载数据到本地系统,或将数据从本地系统上传到互联网。
网关在以下情况下需要发起I/O操作:
路由请求:当接收到外部的网络请求时(比如HTTP请求),网关需要读取请求数据(网络I/O操作),然后根据路由规则将请求转发到适当的服务或应用。
路由模式:
Zuul:使用同步阻塞模型,可能在高并发场景下成为性能瓶颈。
当一个线程执行I/O操作(如读取文件、网络通信等)时,它会一直等待操作完成才继续执行后续代码。
GateWay:支持异步非阻塞模式,更适合处理大量并发请求。
长连接支持:
当线程发起I/O操作时,不需要等待操作完成即可继续执行后续代码。I/O操作与线程的其他工作是并行进行的,一旦I/O操作完成,线程会通过回调或事件通知机制得到通知。
GateWay:由于基于WebFlux,它更好地支持长连接,如WebSocket。
Zuul 1.x:不支持长连接,尽管Zuul 2.x计划改进这一点。
8.为什么使用SpringCloud Alibaba 而不是SpringCloud
熔断降级 Hystirx Sentinel
一些项目难点
某项服务访问网关时有跨域问题?
什么是跨域
跨域:指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域问题
跨域的流程
非简单请求的需要发送预检请求
解决方式1:
使用Nginx反向代理,不同地址、端口都被同一个域名反向代理了,这就是统一域了。这种方法在开发时没法用,所以不采用。
依赖反向代理来处理所有跨域请求可能限制了架构的可扩展性和灵活性,特别是在动态扩展和微服务自动化部署方面。每次有新的服务都要更改配置
反向代理是一种服务器代理模式,它位于客户端和服务器之间,接收来自客户端的请求,并将这些请求转发到内部服务器。与传统的前向代理(主要用于客户端)不同,反向代理对于客户端是透明的,客户端通常不知道实际上是与一个代理而不是真实的服务器直接通信。
解决方式2:
配置当前请求允许跨域,在请求头中配置允许跨域的信息
但是很多请求都需要配置,过于麻烦
最终解决方式:
新建配置类 实现一个CrosWebFilter的过滤器,解决跨域问题
这个过滤器将用于处理所有的跨域请求,根据上述配置进行相应的CORS检查和头部设置。
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class GulimallCorsConfiguration{
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration= new CorsConfiguration();
//1、配置跨域
// 允许跨域的请求头
corsConfiguration.addAllowedHeader("*");
// 允许跨域的请求方式
corsConfiguration.addAllowedMethod("*");
// 允许跨域的请求来源
corsConfiguration.addAllowedOriginPattern("*");
//注释的这句会报错。因为当allowCredentials为真时,allowedorigin不能包含特殊值"*",因为不能在"访问-控制-起源“响应头中设置该值。
//corsConfiguration.addAllowedOrigin("*");//这句会报错
// 是否允许携带cookie跨域
corsConfiguration.setAllowCredentials(true);
// 任意url都要进行跨域配置,两个*号就是可以匹配包含0到多个/的路径
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
什么是响应式编程:
异步非阻塞:响应式编程模型基于异步非阻塞I/O操作,这意味着在等待I/O操作(如网络请求或数据库调用)完成时,程序可以继续执行其他任务。
数据流和变化的传播:响应式编程关注于数据流的创建、组合、过滤和转换。当数据流发生变化时,这些变化会自动传播到程序的其他部分。
背压(Backpressure):这是响应式编程的一个关键概念,指的是消费者(接收方)控制生产者(发送方)数据发送速率的能力,防止消费者被过快的数据流淹没。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!