微服务架构-Day1

学习目标

  • 学会微服务架构
  • 对应项目cloud-demo

学习笔记

1.认识微服务

1.1.单体架构

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

单体架构的优缺点如下:

优点:

  • 架构简单
  • 部署成本低

缺点:

  • 耦合度高(维护困难、升级困难)

1.2.分布式架构

分布式架构:根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务。

分布式架构的优缺点:

优点:

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

缺点:

  • 服务调用关系错综复杂

1.3.微服务

微服务的架构特征:

  • 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责
  • 自治:团队独立、技术独立、数据独立,独立部署和交付
  • 面向服务:服务提供统一标准的接口,与语言和技术无关
  • 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题

1.4.SpringCloud

SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。

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

其中常见的组件包括:

微服务架构-Day1_第1张图片

2.服务拆分和远程调用

2.1.服务拆分原则

  • 不同微服务,不要重复开发相同业务
  • 微服务数据独立,不要访问其它微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其它微服务调用

2.2.实现远程调用案例

大概的步骤是这样的:

  • 注册一个RestTemplate的实例到Spring容器
  • 修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User
  • 将查询的User填充到Order对象,一起返回

2.2.1 注册RestTemplate

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

OrderApplication.java

2.2.2.实现远程调用

@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;
    }
}

OrderService.java

2.3.提供者与消费者

在服务调用关系中,会有两个不同的角色:

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

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

一个服务既可以是服务提供者,也可以是服务消费者。提供者与消费者角色是相对的

3.Eureka注册中心

3.1.Eureka的结构和作用

微服务架构-Day1_第2张图片

3.2.搭建eureka-server

3.2.1.引入eureka依赖


<dependencies>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
    dependency>
dependencies>

pom.xml

3.2.2.编写启动类

给eureka-server服务编写一个启动类,一定要添加一个@EnableEurekaServer注解,开启eureka的注册中心功能:

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

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

}

EurekaApplication.java

3.2.3.编写配置文件

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

application.yml

3.3.服务注册

1)引入依赖

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

pom.xml

2)配置文件

在user-service中,修改application.yml文件,添加服务名称、eureka地址:

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

application.yml

3)启动多个user-service实例

首先,复制原来的user-service启动配置:

微服务架构-Day1_第3张图片

然后,在弹出的窗口中,填写信息:

微服务架构-Day1_第4张图片

现在,SpringBoot窗口会出现两个user-service启动配置,启动该配置即可:

微服务架构-Day1_第5张图片

3.4.服务发现

1)在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解:

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    //开启负载均衡
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

OrderApplication.java

2)修改order-service服务中的cn.itcast.order.service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名代替ip、端口:

@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://userservice/user/" + order.getUserId();
        // 2.2.发送http请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);
        // 3.封装User带Order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

OrderService.java

4.Ribbon负载均衡

4.1.负载均衡原理

SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。

微服务架构-Day1_第6张图片

4.2.负载均衡策略

4.2.1.负载均衡策略

微服务架构-Day1_第7张图片
微服务架构-Day1_第8张图片

4.2.2.自定义负载均衡策略

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

  1. 代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:(此种方案为全局配置方案)
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    //开启负载均衡
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    
    @Bean
    public IRule randomRule(){
        return new RandomRule();
    }
}

OrderApplication.java

  1. 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:(针对某个微服务)
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

application.yml

4.3.饥饿加载

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

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

ribbon:
  eager-load:
    enabled: true
    clients: userservice

application.yml

5.Nacos注册中心

国内公司一般都推崇阿里巴巴的技术,比如注册中心,SpringCloudAlibaba也推出了一个名为Nacos的注册中心。

5.1.认识Nacos

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

5.2. 启动和访问nacos

进入nacos安装目录下的bin目录,然后执行命令即可

  • windows命令:startup.cmd -m standalone

在浏览器输入地址:http://127.0.0.1:8848/nacos即可:默认的账号和密码都是nacos,进入

5.3.服务注册到nacos

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。

主要差异在于:

  • 依赖不同
  • 服务地址不同

1)引入依赖
在cloud-demo父工程的pom文件中的中引入SpringCloudAlibaba的依赖:

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    <version>2.2.6.RELEASEversion>
    <type>pomtype>
    <scope>importscope>
dependency>

pom.xml

然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>

pom.xml

  • 注意:不要忘了注释掉eureka的依赖。

2)配置nacos地址
在user-service和order-service的application.yml中添加nacos地址:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848

application.ym

  • 注意:不要忘了注释掉eureka的地址

3)刷新nacos

5.4.服务分级存储模型

微服务架构-Day1_第9张图片

微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。

5.4.1.给user-service配置集群

修改user-service的application.yml文件,添加集群配置:

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

application.yml

此时启动的user-service就属于HZ这个集群

再次修改user-service的application.yml文件,添加集群配置:

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

application.yml

此时启动的user-service就属于SH这个集群

5.4.2.同集群优先的负载均衡

1)给order-service配置集群信息

修改order-service的application.yml文件,添加集群配置:

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

application.yml

2)修改负载均衡规则

修改order-service的application.yml文件,修改负载均衡规则:

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

application.yml

5.5.权重配置

默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。

但是Nacos提供了权重配置(值在0~1之间)来控制访问频率,权重越大则访问频率越高。

在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:

微服务架构-Day1_第10张图片

在弹出的编辑窗口,修改权重:

微服务架构-Day1_第11张图片

  • 注意:如果权重修改为0,则该实例永远不会被访问

5.6.环境隔离

Nacos提供了namespace来实现环境隔离功能。

  • nacos中可以有多个namespace
  • namespace下可以有group、service等
  • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见

5.6.1.创建namespace

默认情况下,所有service、data、group都在同一个namespace,名为public:

微服务架构-Day1_第12张图片

我们可以点击页面新增按钮,添加一个namespace:

微服务架构-Day1_第13张图片

然后,填写表单:

微服务架构-Day1_第14张图片

就能在页面看到一个新的namespace:

微服务架构-Day1_第15张图片

5.6.2.给微服务配置namespace

给微服务配置namespace只能通过修改配置来实现。

修改order-service的application.yml文件:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ
        namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID

application.yml

5.7.Nacos与Eureka的区别

Nacos的服务实例分为两种l类型:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。

  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

Nacos和Eureka整体结构类似,服务注册、服务拉取、心跳等待,但是也存在一些差异:

微服务架构-Day1_第16张图片

配置一个服务实例为永久实例:

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

application.yml

  • Nacos与eureka的共同点

    • 都支持服务注册和服务拉取
    • 都支持服务提供者心跳方式做健康检测
  • Nacos与Eureka的区别

    • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
    • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
    • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

你可能感兴趣的:(微服务框架,spring,boot,spring,cloud,spring,cloud,alibaba,eureka,nacos)