微服务复习

什么是微服务

就是把大系统拆分为很多小系统,几个人负责一个服务这样 ,每个服务独立的开发、测试和上线, 代码冲突少 ,每次上线就回归测试自己的一个服务即可 ,只要向后兼容接口就行了,不需要跟别人等待和协调 。

SpringCloud Alibaba微服务解决方案

Spring Cloud Alibaba 是Spring Cloud的一个子项目

核心组件分析

服务注册与发现: 基于Spring Cloud 服务注册与发现标准,借助Nacos进行实现

分布式配置管理: 基于Nacos支持分布式系统中的外部化配置,配置更改时自动刷新。

解决方案架构设计

基于Spring Cloud Alibaba实现的微服务,解决方案设计架构如图所示:

 项目

 

 

 创建父工程模块

 

 修改项目pom.xml文件内容,例如:

 

<!--统一依赖版本(spring boot,spring cloud,spring cloud alibaba)
    注意,这里只做版本管理-->
    <dependencyManagement>
        <dependencies>
            <!--Spring Boot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.2.RELEASE</version>
                <type>pom</type><!--允许scope的值为import时,type的值必须pom-->
                <scope>import</scope> <!--这里的import类似java中的import-->
            </dependency>
            <!--Spring Cloud (Spring Cloud 工程依赖于spring boot),
            spring cloud中定义的是一些微服务规范。-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--Spring Cloud Alibaba (这套依赖是基于Spring Cloud规范,做了具体的落地实现)-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--定义公共依赖(lombok,test)-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <!--springboot 2.2以后版本默认单元测试使用的是junit5,
                所以junit4以前的测试引擎不在需要-->
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <!--定义统一编译运行环境(jdk)-->
    <build>
        <plugins>
            <!--定义maven的编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

服务关系以及调用关系设计

 

 nacos

 不仅可以做注册中心,还可以作为配置中心

构建Nacos服务

初始化配置

打开表

source E:\app\nacos-server-1.4.2\nacos\conf\nacos-mysql.sql

打开/conf/application.properties里打开默认配置,并基于你当前环境配置要连接的数据库,连接数据库时使用的用户名和密码(假如前面有"#"要将其去掉):

 

 

 

服务注册与调用入门(重点)

 两个共有的pom文件

<dependencies>
        <!--Web服务-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--服务的注册和发现(我们要讲服务注册到nacos)-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

 创建并修改配置文件application.yml(或者application.properties),实现服务注册

server:
   port: 8081
spring:
  application:
    name: sca-provider #进行服务注册必须配置服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

 服务方

@RestController
public class ProviderController {

    @Value("${server.port:8080}")
    private String server;

    //访问方式:
    //1)浏览器中直接输入http://localhost:8081/provider/echo/tedu
    //2)在sca-consumer服务中对这个服务进行访问
    @GetMapping("/provider/echo/{msg}")
    public String doRestEcho1(@PathVariable String msg) throws InterruptedException {
        //Thread.sleep(5000);
        return server+" say hello "+msg;
    }
}

sca-consumer服务中的配置文件application.yml

server:
  port: 8090
spring:
  application:
    name: sca-consumer #服务注册时,服务名必须配置
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #从哪里去查找服务

服务之间进行服务调用时,使用了什么API?(RestTemplate,用此对象之前要先创建这个对象并交给spring管理)

在sca-consumer启动类中添加如下方法,用于创建RestTemplate对象.

@Bean
public RestTemplate restTemplate(){//基于此对象实现远端服务调用
    return new RestTemplate();
}

定义sca-consumer服务的消费端Controller,在此对象方法内部实现远端服务调用


/**
 * 定义服务消费端Controller,在这个Controller对象
 * 的方法中实现对远端服务sca-provider的调用
 */
@RestController
public class ConsumerController {
    /**
     * 从spring容器获取一个RestTemplate对象,
     * 基于此对象实现远端服务调用
     */
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 在此方法中通过一个RestTemplate对象调用远端sca-provider中的服务
     * @return
     * 访问此方法的url: http://localhost:8090/consumer/doRestEcho1
     */
    @GetMapping("/consumer/doRestEcho1")
    public String doRestEcho01(){
        //1.定义要调用的远端服务的url
        String url="http://localhost:8081/provider/echo/8090";
        //2.基于restTemplate对象中的相关方法进行服务调用
        return restTemplate.getForObject(url, String.class);
    }

}

 测试:

 问题:

 为什么要将服务注册到nacos?(为了更好的查找这些服务,一个是改变配置,不需要重新编译打包应用程序; 第二配置可以做到动态变更。)

在Nacos中服务提供者是如何向Nacos注册中心(Registry)续约的?(5秒心跳)

对于Nacos服务来讲它是如何判定服务实例的状态?(检测心跳包,15,30)

服务消费方是如何调用服务提供方的服务的?(RestTemplate)

Nacos如何检查服务状态?(通过心跳包实现,服务启动时会定时向nacos发送心跳包-BeatInfo)

服务之间进行服务调用时,使用了什么API?(RestTemplate,用此对象之前要先创建这个对象并交给spring管理)

实现Nacos服务注册需要添加什么依赖?(两个:web,discovery)  服务的注册和发现

Nacos如何检查服务状态?(通过心跳包实现,服务启动时会定时向nacos发送心跳包-BeatInfo)  

服务负载均衡设计及实现(重点)

消费者访问多个服务实例

LoadBalancerClient应用

 这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。

 /**
     * 负载均衡客户端对象,基于此对象可以获取nacos中的服务实例,
     * 并且通过负载均衡算法从所有实例中取一个实例。
Ribbon 是什么?
Netflix公司提供的负载均衡客户端,一般应用于服务的消费方法
LoadBalancerClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于特点算法实现负载均衡方式的调用
     */

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Value("${spring.application.name:sca-consumer}")
    private String appName;

    @GetMapping("/consumer/doRestEcho2")
    public String doRestEcho2(){
        //从nacos获取服务实例(这里的choose方法内置了负载均衡算法)
        ServiceInstance instance = //"sca-provider"为nacos服务列表中的一个服务名
                loadBalancerClient.choose("sca-provider");
        String ip=instance.getHost();
        int port=instance.getPort();
        //String url="http://"+ip+":"+port+"/provider/echo/"+appName;
        String url=String.format("http://%s:%s/provider/echo/%s",ip,port,appName);
        //执行远端服务调用
        return restTemplate.getForObject(url,
                String.class//远端url对应的方法的返回值类型(响应数据类型)
        );
    }

@LoadBalanced

@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。

当使用RestTemplate进行远程服务调用时,假如需要负载均衡,还可以在RestTemplate对象构建时,使用@LoadBalanced对构建RestTemplate的方法进行修饰,例如在ConsumerApplication中构建名字为loadBalancedRestTemplate的RestTemplate对象:

@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){
    return new RestTemplate();
}
  @Autowired
    private RestTemplate loadBalancedRestTemplate;

    @GetMapping("/consumer/doRestEcho3")
    public String doRestEcho3(){
        //定义远程调用的url
        String url=String.format("http://%s/provider/echo/%s","sca-provider",appName);
        //执行远端服务调用
        return loadBalancedRestTemplate.getForObject(url,
                String.class//远端url对应的方法的返回值类型(响应数据类型)
        );
    }

 小节面试:

  • @Bean注解的作用?(一般用于配置类内部,描述相关方法,用于告诉spring此方法的返回值要交给spring管理,bean的名字默认为方法名,假如需要指定名字可以@Bean(“bean的名字”),最多的应用场景是整合第三方的资源-对象)

  • @Autowired注解的作用?(此注解用于描述属性,构造方法,set方法等,用于告诉spring框架,按找一定的规则为属性进行DI操作,默认按属性,方法参数类型查找对应的对象,假如只找到一个,则直接注入,类型多个时还会按照属性名或方法参数名进行值的注入,假如名字也不同,就出报错.)

  • Nacos中的负责均衡底层是如何实现的?(通过Ribbon实现,Ribbon中定义了一些负载均衡算法,然后基于这些算法从服务实例中获取一个实例为消费方法提供服务)

  • Ribbon 是什么?(Netflix公司提供的负载均衡客户端,一般应用于服务的消费方法)

  • Ribbon 可以解决什么问题? (基于负载均衡策略进行服务调用, 所有策略都会实现IRule接口)

  • Ribbon 内置的负载策略都有哪些?(8种,可以通过查看IRule接口的实现类进行分析)

  • @LoadBalanced的作用是什么?(描述RestTemplate对象,用于告诉Spring框架,在使用RestTempalte进行服务调用时,这个调用过程会被一个拦截器进行拦截,然后在拦截器内部,启动负载均衡策略。)

  • 我们可以自己定义负载均衡策略吗?(可以,基于IRule接口进行策略定义,也可以参考NacosRule进行实现)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睡不醒的小小秦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值