一、微服务?是什么?

相信我们大家前面所学的知识都是服务于单体架构的项目。什么是单体架构项目?

单体架构:就是把所有功能模块都写在一块,最后项目启动时所有功能一并启动。

随着用户量的增长,为了应对高并发场景,便出现了微服务的架构理念!

那么什么是微服务呢?


微服务从名字上看可以理解为即是微小的服务,通过解耦项目中各个功能作为一个单独的功能模块,每个功能作为一个单独的应用程序,即称为"服务",每次启动项目都可以单独启动某个功能的服务。每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP API。这些服务围绕业务能力来构建, 并通过完全自动化部署机制来独立部署。


思考一下!在开发过程中,我们在实现某个功能的时候会发现使用另一种语言会更好,比如说"直播"功能,可能使用C++语言会更适合,但是在单体项目中,我使用的语言只能是一种,比如说Java。而在微服务中即可以实现每一个"服务"使用不同的语言,因为他们启动的服务都是单独的进程。

简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行。

二、集群?分布式?

我们一定都听说过集群吧!我作为一个大数据专业的学生跟集群打交道算是较多了。那么什么是集群呢?

集群简单来说就是:一堆机器集中在一起!不管他们工作方式是否协助,都可以叫做集群。集群是一种物理形态,而分布式是一种工作方式!

分布式就是把应用拆分为多个模块服务,分布部署在不同的服务器上。这种分布式架构可以实现模块化升级和多语言团队协助,形成一种类似于"自治"的形态,实现独立部署、数据隔离以及多语言团队合作。

那么想要在Java项目中实现这种分布式架构怎么实现呢?即需要用到Nacos!


三、Nacos?

1.Nacos注册中心与服务发现

Nacos的全称是:Dynamic Naming and Configuration Service 是由阿里巴巴开发的开源项目,用于动态服务发现、配置管理和服务管理。

在微服务中,我们为了应对高并发的服务场景,需要把每一个服务创建多个"副本"放在不同的服务器上,比如说商城系统:"订单服务"调用"商品服务",但是我们是分布式的架构,并且每个"服务"可能存在着多个"副本",到底要调用哪一个服务器上的"服务"呢?这个时候就需要我们的Nacos注册中心了!

在"服务"启动时,会将"服务副本"的信息按照(一般是按照模块名)作为"服务Id"注册到Nacos注册中心,当某一个"服务"调用另一个"服务"时,需要先去Nacos注册中心获取被调用"服务"的"ip"和"端口号",然后根据Nacos返回的"ip"和"端口号"拼接传入的参数组成url。这就使用到了远程调用

如何配置Nacos?

  1. 首先要先启动Nacos后台:找到Nacos的bin目录,打开cmd或powershell,输入.\startup.cmd -m standalone



     
  2. 引入依赖以及在application.properties配置好Nacos的信息:


     
  3. 启动微服务即可!

2.远程调用基本流程

在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的需要互相调用,我们称为
远程调用。SpringCloud 中使用 HTTP+JSON 的⽅式完成远程调用。

我们举商品订单的例子来说明:
"用户"向"订单服务"发送下单请求,"订单服务"需要远程调用"商品服务"获取商品数据,然后生成订单,最后向用户返回订单数据。

但是我们会发现一个问题,这么多"服务副本",被远程调用时到底调用的时哪一个服务器上的"服务"呢?于是我们就涉及到了分布式的"负载均衡"。

3.负载均衡

分布式系统中,A 服务需要调⽤ B 服务,B 服务在多台机器中都存在,A 调⽤任意⼀个服务器均
可完成功能。 为了使每⼀个服务器都不要太忙或者太闲,我们可以负载均衡的调⽤每⼀个服务
器,提升⽹站的健壮性。

代码如何实现负载均衡呢?

1.使用 LoadBalancerClient 对象的 choose方法。

//使用LoadBalancerClient
    private Product getProductFormRemoteWithLoadBalancer(Long productId){
        //1.获取到商品服务所在的所有机器IP+Port
        ServiceInstance choose = loadBalancerClient.choose("service-product");


//        远程Url
        String url="http://"+choose.getHost()+":"+choose.getPort()+"/product/"+productId;
        log.info("远程请求:{}"+url);
//        //2.给远程发送请求
        Product product=restTemplate.getForObject(url, Product.class);
        return product;

2.使用@LoadBalanced注解

//使用注解
    private Product getProductFormRemoteWithAnnotation(Long productId){

        String url="http://service-product/product/"+productId;
        Product product=restTemplate.getForObject(url, Product.class);
        return product;

    }

4.思考:注册中心宕机,是否能够继续远程调用?

答案是:需要分情况!

首先我们要弄清楚实现"负载均衡"后"远程调用"具体是怎么执行的?

我们以使用@LoadBalanced注解作为演示:通过RestTemplate对象向Nacos注册中心获取对应"微服务名字"的访问地址列表,接着通过利用负载均衡算法选择到 ip和端口号 ,接着向被调用的服务发起请求访问。实际上,当RestTemplate对象向Nacos注册中心获取对应"微服务名字"的访问地址列表时,地址列表会被存储到实例缓存中。所以可以分为两种情况!

第一种情况:被调用过:当注册中心宕机后,远程调用不再依赖注册中心,可以通过实例缓存获取访问地址列表。

第二种情况:没有调用过:无法从注册中心获取访问地址列表,所以不可以通过!

更多推荐