# 认识微服务

# 服务框架演变

# 单体架构

# 概念

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

# 优点

  • 架构简单
  • 部署成本低

# 缺点

  • 耦合度高

# 图解

image-20221227120000100

# 分布式架构

# 概念

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

# 优点

  • 降低服务耦合
  • 有利于服务升级拓展

# 图解

image-20221227120255948

# 微服务

# 概念

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

# 微服务架构特征

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

# 图解

image-20221227120725992

# 微服务技术对比

# 微服务结构

# 概念

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

# 图解

image-20221227121030726

# 企业四种需求

image-20221227121129930

# SpringCloud

# 概述及图解

  • SpringCloud 是目前国内使用最广泛的微服务框架,官网地址:https://spring.io/project/spring-cloud
  • SpringCloud 集成了各种微服务功能组件,并基于 SpringBoot 实现了这些组件的自动装配,从而提供了良好的开箱体验

image-20221227121553296

# SpringCloud 与 SpringBoot 的版本兼容关系图解

image-20221227121716149

# 服务拆分及远程调用

# 服务拆分

# 注意事项及图解

  • 单一职责:不同的微服务,不要重复开发相同业务
  • 数据独立:不要访问其他微服务的数据库
  • 面向服务:将自己的业务暴露为接口,供其他微服务调用

image-20221227122026696

# 远程调用

# 远程调用方式分析

image-20221227122518487

# 提供者和消费者及图解

  • 服务提供者:一次业务中,被其他服务调用的服务。(提供接口给其他微服务)
  • 服务消费者:一次业务中,调用其它服务的服务。(调用其它服务提供的接口)

image-20221227123838619

# 案例 Demo

# 导入课前提供的工程:cloud-demo

image-20221227122319014

# 根据订单 id 查询订单功能

image-20221227122413301

# 注册 RestTemplate

在 order-service 的 OrderApplication 中注册 RestTemplate

@MapperScan("com.bjh.order.mapper")
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate;
    }
}

# 远程服务调用 RestTemplate

修改 order-service 的 OrderService 的 queryOrderById 方法

@Service
public class OrderService() {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    privvate RestTemplate restTemplate;
    public Order queryOrderById(Long orderId) {
        //1. 查询订单
        Order order = orderMapping.findById(orderId);
        //2. 查询用户
        String sql = "http://localhost:8081/user/" + order.getUserId();
        User user = restTemplate.getForObject(url,User.class);
        //3. 封装 user 对象
        order.setUser(user);
        //4. 返回查询订单结果 order
        return order;
    }
}

# Eureka 注册中心

# 远程调用的问题

# 服务调用出现的问题

  • 服务者该如何获取服务提供者的地址信息
  • 如果有多个服务提供者,消费者如何选择
  • 消费者如何得知服务提供者的健康状态

image-20221227124149027

# eureka 原理

# Eureka 注册中心

# Eureka 作用

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

# Eureka 的作用图解

image-20221227124334662

# 搭建 EurekaServer

# 步骤

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

<dependency>
	<groupId>org.springframework.cloud</groupId>
    <artifactld>apring-cloud-starter-netflix-eureka-server</artifactld>
</dependency>

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

# 添加 aplication.yml 文件,编写配置

server:
	port: 10086
spring:
	application:
		name: eurekaserver
eureka:
	client:
		service-url:
			defaultZone: http://127.0.0.1:10086/eureka/

# 服务注册

# 注册 user-service

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

<dependency>
	<groupId>org.springframework.cloud</groupId>
    <artifactld>apring-cloud-starter-netflix-eureka-client</artifactld>
</dependency>

# 在 application.yml 文件,编写配置

spring:
	application:
		name: userservice
eureka:
	client:
		service-url:
			defaultZone: http://127.0.0.1:10086/eureka/

# 我们可以将 user-service 多次启动,模拟多实例部署,但是避免端口冲突,需要配置端口

image-20221227125909545

# 将 order-service 同商完成注册

# 在 order-service 完成服务拉取

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

String url = "http://userservcie/user/" + order.getUserId();

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

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

# 服务发现

# Ribbon 负载均衡

# 负载均衡原理

# 负载均衡流程

image-20221228132003650

# 负载均衡策略

# IRule 接口以及实现类

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

image-20221228132126584

# 修改负载均衡 —— 代码方式

在 order-service 中的 OrderApplication 类中,定义一个新的 IRule(全局定义)

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

# 修改负载均衡 —— 添加配置

在 order-service 中的 application.yml 文件中,添加新的配置可以修改规则

userservice:
	ribbon:
		NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  # 负载均衡策略

# 懒加载

在 Ribbon 默认采用懒加载,即第一次访问才会区创建 LoadBalanceClient,请求时间会很长,而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面的配置开启饥饿加载

ribbon:
	eager-load:
		enabled: true #开启解饿加载
		clients: userservice #指定对 userservice 这个服务进行饥饿加载

# Nacos 注册中心

# 认识和安装 Nacos

Nacos 是阿里巴巴的产品,现在是 SpringCloud 的一个组件,相比 Eureka 功能更加丰富,国内受欢迎程度更高

启动:在 bin 目录下运行指令: startup.cmd -m standalone

# Nacos 的快速入门

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

<dependency>
	<groupId>com.alibaba.cloud</groupId>
    <artifactld>spring-cloud-alibaba-dependencies</artifactld>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

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

# 添加 nacos 的客户端依赖

<dependency>
	<groupId>com.ailibaba.cloud</groupId>
    <artifactld>spring-cloud-starter-alibaba-nacos-discovery</artifactld>
</dependency>

# 修改 user-service 和 order-service 中的 application.yml 配置文件,注释 eureka 地址,添加 nacos 地址

spring:
	cloud:
		nacos:
			server-addr: localhost:8848  # 服务端地址

# 启动并测试

image-20221228133929007

# Nacos 服务分级存储模型

# 模型图解

image-20221228134109722

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

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

image-20221228134209746

# 服务集群属性

# 修改 application.yml

spring:
	cloud:
		nacos:
			server-addr: localhost:8848
			discovery: 
				cluster-name: HZ  #配置集群名

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

image-20221228134436986

# 修改 order-service 的 application.yml 文件,设置为 HZ

spring:
	cloud:
		nacos:
			server-addr: localhost:8848
			discovery:
				cluster-name: HZ #配置集群名称

# 然后在 order-service 中设置负载均衡的 IRule 为 NacosRule

userservice:
	ribbon:
		NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则

# 服务器型性能有差异,Nacos 提供了权重配置控制访问频率

image-20221228134958915

# Nacos 环境隔离

# 环境隔离 - namespace

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

# 环境隔离步骤

# 在 Nacos 控制可以创建 namespace,隔离不同的环境

image-20221228135218122

# 填写新的命名空间信息

image-20221228135244149

# 保存后控制台可以看到命名空间的 id

image-20221228135321197

# 修改 order-service 的 application.yml,添加 namespace

spring:
	datasource:
		url: jdbc:mysql://localhost:3306/baozi?useSSL=false
		username: root
		password: root
		driver-class-name: com.mysql.cj.jdbc.Driver
	cloud:
		nacos:
			server-addr: localhost:8848
			discovery:
				cluster-name: SH
				namespace: 命名空间id

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

image-20221228135704597

# 此时访问 order-serive,因为 namespace 不同,导致无法找到 userservice,控制台报错

image-20221228135753360

# nacos 注册中心细节分析

image-20221228135831289

服务注册到 Nacos 时,可以选择注册为临时和非临时实例,通过配置 application.yml

spring:
	cloud:
		nacos:
			discovery:
				ephemeral: false # 设置为非临时实例

临时实例宕机,会从 nacos 的服务列表中剔除,而临时实例不会

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Baozi 微信支付

微信支付

Baozi 支付宝

支付宝

Baozi 微信

微信