SpringCloud-Alibaba

一 注册中心原理

在微服务架构中,注册中心是最核心的基础服务之一

注册中心主要涉及到三大角色:

  1. 服务提供者  ---生产者 被调用

  2. 服务消费者  --- 消费者 调用者

  3. 服务发现与注册

它们之间的关系大致如下:

  1. 各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。

  2. 服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。

  3. 各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。

  4. 微服务网络地址发送变化(例如实例增加或IP变动等)时,会重新注册到注册中心。这样,服务消费者就无需人工修改提供者的网络地址了。

注册中心应具备功能:

  1. 服务注册表
    服务注册表是注册中心的核心,它用来记录各个微服务的信息,例如微服务的名称、IP、端口等。服务注册表提供查询API和管理API,查询API用于查询可用的微服务实例,管理API用于服务的注册与注销。

  2.  服务注册与发现
    服务注册是指微服务在启动时,将自己的信息注册到注册中心的过程。服务发现是指查询可用的微服务列表及网络地址的机制

  3. 服务检查
    注册中心使用一定的机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册表移除该实例。

客户端启动的时候,会开启一个线程,这个线程每过五秒钟调用自己发起心跳服务端也会有一个定时心跳检查任务,会周期性的隔一段时间检查一下,每一个实例有没有与自己保持心跳,如果没有直接删掉。心跳两边都有,客户端有,服务端也有

二 常见的注册中心

Zookeeper

zookeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式

应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用

配置项的管理等。

Eureka

Eureka是Springcloud Netflix中的重要组件,主要作用就是做服务注册和发现。但是现在已经闭

Consul

Consul是基于GO语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现

和配置管理的功能。Consul的功能都很实用,其中包括:服务注册/发现、健康检查、Key/Value

存储、多数据中心和分布式一致性保证等特性。Consul本身只是一个二进制的可执行文件,所以

安装和部署都非常简单,只需要从官网下载后,在执行对应的启动脚本即可。

Nacos

Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它是 Spring

Cloud Alibaba 组件之一,负责服务注册发现和服务配置,可以这样认为nacos=eureka+config。

nacos简介

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速

实现动态服务发现、服务配置、服务元数据及流量管理。

从上面的介绍就可以看出,nacos的作用就是一个注册中心,用来管理注册上来的各个微服务

三 nacos实战入门

1.安装nacos

接下来,我们就在现有的环境中加入nacos,并将我们的两个微服务注册上去

第1步: 安装nacos

第2步: 启动nacos

windows启动:

startup.cmd -m standalone

linux启动的时候使用的命令是:

sh startup.sh -m standalone

如果微服务的IP地址显示的是以1 为最后一位的话 直接将对应的虚拟机的网卡禁用即可

第3步: 访问nacos

打开浏览器输入http://localhost:8848/nacos/index.html,即可访问服务, 默认密码是nacos/nacos

1.product微服务注册到nacos

a.在pom.xml中添加nacos的依赖

<dependency>

    <groupId>com.alibaba.cloud</groupId>

    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>

</dependency>

b. 在主启动类上添加nacos的开启注解

@EnableDiscoveryClient

当前微服务可以被nacos发现

c. 在application.properties添加nacos的配置

a.设置微服务的名字

b.设置端口号

c.添加到注册中心,将该服务交给注册中心去管理

application.properties相关内容如下:

spring.application.name=product

server.port=8082

#设置注册中心的地址

spring.cloud.nacos.discovery.server-addr=localhost:8848

开启注解,能够让注册中心扫描到该服务

@EnableDiscoveryClient

d.观察注册中心的服务列表

出现如上即为配置成功

2.订单微服务注册到nacos中

过程跟product一样

配置文件主要代码:

spring.application.name=order

spring.cloud.nacos.discovery.server-addr=localhost:8848

server.port=8081

3.一个服务创建多个实例

创建一个和product微服务一样的微服务并修改端口号,启动之后如下

2.服务调用的负载均衡

什么是负载均衡

通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上 进行执行。

根据负载均衡发生位置的不同,一般分为服务端负载均衡和客户端负载均衡。

服务端负载均衡指的是发生在服务提供者一方,比如常见的nginx负载均衡

而客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求

我们在微服务调用关系中一般会选择客户端负载均衡,也就是在服务调用的一方来决定服务由哪个提供者执行。

基于Ribbon实现负载均衡 (废弃)

Ribbon是Spring Cloud的一个组件, 它可以让我们使用一个注解就能轻松的搞定负载均衡 第1步:在RestTemplate 的生成方法上添加@LoadBalanced注解

代码:

@SpringBootApplication

@EnableDiscoveryClient

public class OrderApplication {

    public static void main(String[] args) {

        SpringApplication.run(OrderApplication.class,args);

    }


    //实现负载均衡需要是用restTemplate

    @Bean

    @LoadBalanced

    public RestTemplate getRestTemplate(){

        return new RestTemplate();

    }

}

Ribbon支持的负载均衡策略 Ribbon内置了多种负载均衡策略,内部负载均衡的顶级接口为 com.netflix.loadbalancer.IRule ,

 

我们可以通过修改配置来调整Ribbon的负载均衡策略

1.注入负载均衡策略的bean

@Bean

public IRule getRule(){

    return new RandomRule();

}

2.修改消费端的配置文件

yml文件:消费者是调用者order

product: # 调用的提供者的名称

   ribbon:

      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

properties文件:

product.ribbon.NFLoadBalancerRuleClassName= com.netflix.loadbalancer.RandomRule    

 

负载均衡

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-loadbalancer</artifactId>

</dependency>

轮询算法 /随机算法

配置策略:

package com.ymm.config;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;

import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;

import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;

import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.core.env.Environment;

/**

* @auther: 余明明

*/

public class LoadBalancerConfig {

    @Bean

    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,

                                                            LoadBalancerClientFactory loadBalancerClientFactory) {

        // 获取需要进行负载均衡的名字  loadbalancer.client.name

        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

        // 对应的需要进行负载均衡的名字是什么

        System.out.println("======"+name);

        // product

        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);

    }

}

使用策略:

package com.order;



import com.order.config.LoadBalancerConfig;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;



import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;

import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;



@SpringBootApplication

@LoadBalancerClients(

        defaultConfiguration = LoadBalancerConfig.class

        // product 会使用这个策略

       // @LoadBalancerClient(value = "product",configuration= LoadBalancerConfig.class)

)

public class OrderAppliaction {

    public static void main(String[] args) {

        SpringApplication.run(OrderAppliaction.class);

    }



    @Bean



   // @LoadBalanced

    public RestTemplate getRestTemplate(){

        return new RestTemplate();

    }

}

四 基于Feign实现服务调用

FeignClient和RestTemplate

SpirngCloud 中,默认是使用HTTP进行微服务间通信,其中最常用的有两种实现形式

  • RestTemplate

  • Feign

RestTempale

  • 其实在SpringWeb里面,已经原生支持了 RestTemplate,只不过我们一般使用的是把请求URL直接写死,而不是通过服务名的形式来调用,但是在微服务架构中,因为有了注册中心的存在,我们的负载均衡可以不需要使用第三方软件或者硬件实现了,所有,我们最佳的方式是经过服务名访问,请求到那个实例,由 负载均衡策略来替我们决定。

  • ribbion中的负载均衡策略了解

Spring Cloud 中 7 种负载均衡策略!

自定义策略(了解)

第一种写法:

直接使用 RestTemplate , Url写死

第二种写法:

LoadBalancerClient 拼接url的方式

@Autowired

public RestTemplate restTemplate;



@Resource

private LoadBalancerClient loadBalancerClient;



@GetMapping("/add2/{pid}")

public Object add2(@PathVariable Integer pid) {

    ServiceInstance choose = loadBalancerClient.choose("product");

    String requestMsg = "方式二 GET 请求 RibbonServer";

    String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/product/getById/" + pid);

    System.out.println(url);

    // 1. 根据pid 得到商品的信息

    Product forObject = restTemplate.getForObject(url, Product.class);

    //  实现远程的调用

    //  product : 分布式部署 

    // 思考82 和83 之前进行轮询调用

    return forObject;

}

利用 LoadBalancerClient 通过应用名获取 url,然后再使用 RestTemplate 请求

使用DiscoveryClient拼接url

@Autowired

public RestTemplate restTemplate;



@Resource

private DiscoveryClient  discoveryClient;



@GetMapping("add3/{pid}")

public Object add3(@PathVariable Integer pid){

    List<ServiceInstance> pro = discoveryClient.getInstances("product");

    //

    int size = pro.size();

    //

    int i = new Random().nextInt(size);// =size-1

    ServiceInstance choose = pro.get(i);

    String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/product/getById/"+pid);

    System.out.println("*****"+url);

    // 1. 根据pid 得到商品的信息

    Product forObject = restTemplate.getForObject(url, Product.class);

    //  实现远程的调用

    return forObject;

}

第三种写法:

使用OpenFeign

OpenFeign默认的负载均衡规则是轮循

修改pom文件

<!--使用openFeign-->

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

启动类上开启注解

@EnableFeignClients

调用

@FeignClient

service接口:

   如果有异常 回滚到哪一个类里面

// fallback代表微服务有问题 走fallback的类

@FeignClient(value = "product",fallback =ProFeignImpl.class )

public interface ProFeign {

    // 根据id 查询 商品的信息  需要访问的微服务是哪一个

    // "product/getById/{id}"

    // 1. nacos 里面找到product 服务  ip port

    // 2. 发出一个get请求 路径是 ip:port/product/getById/{id}

    @GetMapping("product/getById/{id}")

    Product getProById(@PathVariable Integer id);

}

feign接口的实现类

service的实现类

// fallback代表微服务有问题 走fallback的类

@FeignClient(value = "product",fallback =ProFeignImpl.class )

public interface ProFeign {

    // 根据id 查询 商品的信息  需要访问的微服务是哪一个

    // "product/getById/{id}"

    // 1. nacos 里面找到product 服务  ip port

    // 2. 发出一个get请求 路径是 ip:port/product/getById/{id}

    @GetMapping("product/getById/{id}")

    Product getProById(@PathVariable Integer id);

}

使实现类生效

加jar

  <!-- -->

        <dependency>

            <groupId>com.alibaba.cloud</groupId>

            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>

        </dependency>

开启openfeign对sentinel的支持

(在application.properties中编写)

feign.sentinel.enabled=true

Controller调用

@Resource

private ProFeign proFeign;



@GetMapping("feignOrder/{id}")

public Product getProById(@PathVariable Integer id) {

    Product proById = proFeign.getProById(id);

    return proById;

}

product的Controller

@RestController

@RequestMapping("/product")

public class ProductController {

    @GetMapping("/getById/{id}")

    public Product getProductById(@PathVariable("id") Integer id){

        System.out.println("商品的id是"+id);

        Product product=new Product();

        product.setName("测试商品");

        product.setId(id);

        return product;//返回商品

    }

}

五搭建nacos的集群(选修)

集群部署说明

linux版

简易版步骤:

1.上压缩包

2.解压

3.配置 conf/cluster.conf

4.在mysql中创建数据库nacos_config

并导入 /conf/nacos-mysql.sql

5.修改application.properties

在最后加上

db.num=1

db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true

db.user.0=root

db.password.0=root

修改端口号 8848

6.启动

参考教程:

https://www.cnblogs.com/Arthemis-z/p/14505008.html

nginx配置负载均衡

upstream nacoscluster{

    server 192.168.58.33:8849;

    server 192.168.58.33:8850;

    server 192.168.58.33:8851;

  

}

server {

    listen 8847;

    server_name localhost;

    location /nacos/ {

        proxy_pass http://nacoscluster/nacos/;

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值