irpas技术客

【学习笔记】SpringCloud微服务架构_BlackBox_

网络投稿 5821

文章目录 @[toc]SpringCloud微服务架构一、认识微服务1. 服务架构的演变1.1 单体架构1.2 分布式架构1.3 服务治理1.4 微服务1.5 总结 2. 微服务技术对比2.1 微服务架构2.2 微服务技术对比2.3 企业需求 3. SpringCloud 二、微服务拆分案例1. 服务拆分1.1 服务拆分注意事项 2. 服务间调用2.1 步骤2.2 提供者和消费者 三、eureka注册中心1. 远程调用问题2. eureka原理2.1 Eureka作用2.2 总结 3. 搭建EurekaServer3.1 步骤 4. 服务注册4.1 注册user-service步骤4.2 启动多实例时的问题 5. 服务发现5.1 在order-service完成服务拉取 6. 总结 四、Ribbon负载均衡原理1. 负载均衡原理1.1 负载均衡流程图 2. 负载均衡策略2.1 IRule的实现图2.2 内置负载均衡规则类2.3 调整负载均衡的规则 3. 饥饿加载4. 总结 五、nacos注册中心1. 认识和安装Nacos2. Nacos快速入门2.1 服务注册到Nacos2.2 总结 3. Nacos服务分级存储模型3.1 Nacos服务分级存储模型3.2 服务跨集群调用问题3.3 服务集群属性3.4 根据集群负载均衡3.5 Nacos集群访问特点3.6 实例的权重控制 4. Nacos环境隔离——namespace4.1 介绍4.2 设置namespace4.3 nacos临时实例和非临时实例4.4 Nacos和Eureka共同点4.5 Nacos和Eureka区别 六、Nacos配置七、Feign远程调用八、Gateway服务网管 SpringCloud微服务架构 一、认识微服务 1. 服务架构的演变 1.1 单体架构

将业务的所有功能集中在一个项目中开发,打成一个包部署。

优点:架构简单;部署成本低缺点:耦合度高 1.2 分布式架构

根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。

优点:降低耦合度;有利于服务升级拓展 1.3 服务治理

分布式架构要考虑的问题:

服务拆分粒度如何?服务集群地址如何维护?服务之间如何实现远程调用?服务健康状态如何感知? 1.4 微服务

微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:

单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发面向服务:微服务对外暴露业务接口自治:团队独立、技术独立、数据独立、部署独立隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题 1.5 总结

单体架构特点?

简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统

分布式架构特点?

松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东、淘宝

微服务:一种良好的分布式架构方案

优点:拆分粒度更小、服务更独立、耦合度更低

缺点:架构非常复杂,运维、监控、部署难度提高

2. 微服务技术对比 2.1 微服务架构

微服务这种方案需要技术框架来落地,全球的互联网公司都在积极尝试自己的微服务落地技术。在国内最知名的就是SpringCloud和阿里巴巴的Dubbo。

2.2 微服务技术对比

2.3 企业需求 SpringCloud + Feign 采用SpringCloud技术栈服务接口采用Restful风格服务调用采用Feign方式 SpringCloudAlibaba + Feign 采用SpringCloudAlibaba技术栈服务接口采用Restful风格服务调用采用Feign方式 SpringCloudAlibaba + Dubbo 使用SpringCloudAlibaba技术栈服务接口采用Dubbo协议标准服务调用采用Dubbo方式 Dubbo原始模式 基于Dubbo老旧技术体系服务接口采用Dubbo协议标准服务调用采用Dubbo方式 3. SpringCloud

SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验:

服务注册发现 Eureka,Nacos,Consul 服务远程调用 OpenFeign,Dubbo 统一配置管理 SpringCloudConfig,Nacos 统一网管路由 SpringCloudGateway,Zuul 服务链路监控 Zipkin,Sleuth 流控、降级、保护 Hystix,Sentinel 二、微服务拆分案例 1. 服务拆分 1.1 服务拆分注意事项 不同微服务,不要重复开发相同业务微服务数据独立,不要访问其他微服务的数据库微服务可以将自己的业务暴露为接口,供其他微服务使用 2. 服务间调用 2.1 步骤

注册RestTemplate,将RestTemplate注入到Spring容器中

@MapperScan("cn.itcast.order.mapper") @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } /** * 创建RestTemplate并注入spring容器 */ @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }

服务远程调用RestTemplate,发送url

@Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private RestTemplate restTemplate; public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2. 利用RestTemplate发送http请求 // 2.1 url路径 String url = "http://localhost:8081/user/" + order.getUserId(); // 2.2 发送http请求,实现远程调用 User user = restTemplate.getForObject(url, User.class); // 3.封装user到order中去 order.setUser(user); // 4.返回 return order; } } 2.2 提供者和消费者 服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)服务A调用服务B,服务B调用服务C,那么服务B是什么角色? 要相对来言。A对B说,B是提供者;B对C而言,B是消费者 一个服务可以是同时是服务者和消费者 三、eureka注册中心 1. 远程调用问题 服务消费者该如何获取服务提供者的地址信息?拉取服务如果有多个服务提供者,消费者该如何选择?负载均衡算法消费者如何得知服务提供者的健康状态?心跳续约 2. eureka原理 2.1 Eureka作用

消费者该如何获取服务提供者具体信息? 服务提供者启动时向eureka注册自己的信息eureka保存这些信息消费者根据服务名称向eureka拉取提供者信息 如果有多个服务提供者,消费者该如何选择? 服务消费者利用负载均衡算法,从服务列表中挑选一个 消费者如何感知服务提供者健康状态? 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态eureka会更新记录服务列表信息,心跳不正常会被剔除消费者就可以拉取到最新的信息 2.2 总结

在Eureka架构中,微服务角色有两类:

EurekaServer:服务端,注册中心 记录服务信息心跳监控 EurekaClient:客户端 Provider:服务提供者,例如案例中的 user-service 注册自己的信息到EurekaServer每隔30秒向EurekaServer发送心跳 consumer:服务消费者,例如案例中的 order-service 根据服务名称从EurekaServer拉取服务列表基于服务列表做负载均衡,选中一个微服务后发起远程调用 3. 搭建EurekaServer 3.1 步骤

创建项目,引入spring-cloud-starter-netflix-eureka-server的依赖

<!--eureka服务器--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>

编写启动类,添加@EnableEurekaServer注解

@EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }

添加application.yml文件,编写下面的配置

server: port: 10086 # 服务端口 spring: application: name: eureka-server # eureka的服务名称 eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka/ # eureka的地址信息 4. 服务注册 4.1 注册user-service步骤

在user-service项目引入spring-cloud-starter-netflix-eureka-client的依赖

<!--eureka客服端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>

在application.yml文件,编写下面的配置

spring: application: name: userservice eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka/ # eureka的地址信息 4.2 启动多实例时的问题

5. 服务发现 5.1 在order-service完成服务拉取

服务拉取是基于服务名称获取服务列表,然后在对服务列表做负载均衡

修改OrderService的代码,修改访问的url路径,用服务名代替ip、端口:

// 2.1 url路径 String url = "http://userservice/user/" + order.getUserId();

在order-service项目的启动类OrderApplication中的RestTemplate添加负载均衡注解:

/** * 创建RestTemplate并注入spring容器 */ @Bean @LoadBalanced // 负载均衡注解 public RestTemplate restTemplate() { return new RestTemplate(); } 6. 总结 搭建EurekaServer 引入eureka-server依赖添加@EnableEurekaServer注解在application.yml中配置eureka地址 服务注册 引入eureka-client依赖在application.yml中配置eureka地址 服务发现 引入eureka-client依赖在application.yml中配置eureka地址给RestTemplate添加@LoadBalanced注解用服务提供者的服务名称远程调用 四、Ribbon负载均衡原理 1. 负载均衡原理 1.1 负载均衡流程图

2. 负载均衡策略 2.1 IRule的实现图

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则:

2.2 内置负载均衡规则类 内置负载均衡规则类规则描述RoundRobinRule简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。AvailabilityFilteringRule对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。WeightedResponseTimeRule为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。BestAvailableRule忽略那些短路的服务器,并选择并发数较低的服务器。RandomRule随机选择一个可用的服务器。RetryRule重试机制的选择逻辑
2.3 调整负载均衡的规则

通过定义IRule实现可以修改负载均衡,有两种方式:

代码方式:在order-service中OrderApplication类中,定义一个新的IRule 【作用于全局的,不管orderservice调用哪一个服务,都是按照新的IRule执行】

@Bean public IRule randomRule() { return new RandomRule(); }

配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则**【针对某个微服务而言】**

userservice: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 3. 饥饿加载

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。

而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon: eager-load: clients: userservice # 制定对userservice这个服务饥饿加载 enabled: true # 开启饥饿加载 4. 总结 Ribbon负载均衡规则 规则接口是IRule默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询 负载均衡自定义方式 代码方式:配置灵活,但修改时需要重新打包发布配置方式:直观,方便,无需重新打包发布,但是无法做全局配置 饥饿加载 开启饥饿加载指定饥饿加载的微服务名称 五、nacos注册中心 1. 认识和安装Nacos

在nacos的bin目录下启动cmd,输入指令 startup.cmd -m standalone开始单击模式

2. Nacos快速入门 2.1 服务注册到Nacos

在cloud-demo01父工程中添加spring-cloud-alibaba的管理依赖

<!--Nacos的管理依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.5.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>

注释掉order-service和user-service中原有的eureka依赖。

添加nacos的客户端依赖:

<!-- nacos客户端依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>

修改user-service&order-service中的application.yml文件,注释eureka地址,添加nacos地址:

cloud: nacos: server-addr: localhost:8848

启动并测试:

2.2 总结 Nacos服务搭建 下载安装包解压在bin目录下运行指令:startup.cmd -m standalone Nacos服务注册或发现 引入nacos.discovery依赖配置nacos地址spring.cloud.nacos.server-addr 3. Nacos服务分级存储模型 3.1 Nacos服务分级存储模型

3.2 服务跨集群调用问题

服务调用尽可能选择本地集群的服务,跨集群调用延迟较高

本地集群不可访问时,再去访问其它集群

3.3 服务集群属性

修改application.yml,添加如下属性

cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: BJ # 配置集群名称,也就是机房位置,例如:BJ代表北京

在Nacos控制台中可以看到集群的变化

总结

Nacos服务分级存储模型

一级是服务,例如userservice二级是集群,例如杭州或上海三级是实例,例如杭州机房的某台部署了userservice的服务器

如何设置实例的集群属性

修改application.yml文件,添加spring.cloud.nacos.discovery.cluster-name属性即可 3.4 根据集群负载均衡

修改order-service中的application.yml,设置集群为HZ:

cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 配置集群名称,也就是机房位置

然后在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务:

userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 3.5 Nacos集群访问特点 优先访问同集群在同集群内采用随机方式访问实例总结 NacosRule负载均衡策略 优先选择同集群服务实例列表本地集群找不到提供者,才去其它集群寻找,并且会报警告确定了可用实例列表后,再采用随机负载均衡挑选实例 3.6 实例的权重控制

Nacos控制台可以设置实例的权重值,0~1之间

同集群内的多个实例,权重越高被访问的频率越高

权重设置为0则完全不会被访问

4. Nacos环境隔离——namespace 4.1 介绍

Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离

4.2 设置namespace

创建好后记住命名空间ID,这个用于写入到服务的yaml文件中

![在这里插入图片描述](https://img-blog.csdnimg.cn/da7b4aca17aa45379ab6ac36bea318ec.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQmxhY2tCb3hf,size_20,color_FFFFFF,t_70,g_se,x_16)

配置yaml文件,添加namespace:

cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 配置集群名称,也就是机房位置 namespace: cac40efa-e6d8-424e-bcd3-1100a94539c4

重启order-service后,再来查看控制台

【注意】不同namespace下的服务是不可见的

4.3 nacos临时实例和非临时实例 cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 配置集群名称,也就是机房位置 namespace: cac40efa-e6d8-424e-bcd3-1100a94539c4 ephemeral: false # 是否是临时实例 4.4 Nacos和Eureka共同点 都支持服务注册和服务拉取都支持服务提供者心跳方式做健康检测 4.5 Nacos和Eureka区别 Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式**(主动检测对服务器压力大)**临时实例心跳不正常会被剔除,非临时实例则不会被剔除Nacos支持服务列表变更的消息推送模式,服务列表更新更及时Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式 六、Nacos配置 七、Feign远程调用 八、Gateway服务网管


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #服务架构的演变11 #单体架构12 #分布式架构13 #服务治理14 #微服务15 #总结2