springcloudalibaba-2

一 注册中心原理

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

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

  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实战入门

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

第1步: 安装nacos

下载地址: https://github.com/alibaba/nacos/releases

下载zip格式的安装包,然后进行解压缩操作

1.4.1的下载地址是:

https://github.com/alibaba/nacos/releases/tag/1.4.1

第2步: 启动nacos

startup.cmd -m standalone

bin

sh startup.sh -m standalone

linux启动的时候使用的命令是:sh startup.sh -m standalone

第3步: 访问nacos

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

将product微服务注册到nacos

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

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

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

@EnableDiscoveryClient

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

a.设置微服务的名字

b.设置端口号

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

application.properties相关内容如下:

spring.application.name=product
server.port=8074
#设置注册中心的地址
spring.cloud.nacos.discovery.server-addr=localhost:8848

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

@EnableDiscoveryClient

观察注册中心的服务列表

出现如上即为配置成功

订单微服务注册到nacos中

过程跟product一样

配置文件主要代码:

spring.application.name=order
spring.cloud.nacos.discovery.server-addr=localhost:8848
server.port=8075

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

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

6.服务调用的负载均衡

什么是负载均衡

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

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

服务端负载均衡指的是发生在服务提供者一方,比如常见的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 , 具体的负载策略如下所示

策略名

策略描述

实现说明

BestAvailableRule

选择一个最小的并发请求的server

逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server

AvailabilityFilteringRule

过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)

使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态

WeightedResponseTimeRule

根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。

一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。

RetryRule

对选定的负载均衡策略机上重试机制。

在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server

RoundRobinRule

roundRobin方式轮询选择server

轮询index,选择index对应位置的server

RandomRule

随机选择一个server

在index上随机,选择index对应位置的server

ZoneAvoidanceRule

复合判断server所在区域的性能和server的可用性选择server

使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

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

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

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

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

yml文件:

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.example.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;

public class LoadBalancerConfig {
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); //loadbalancer.client.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写死

第二种写法:

拼接url的方式

@Resource
private LoadBalancerClient loadBalancerClient;
@Override
public boolean addOrder(Integer pid) {
    ServiceInstance choose = loadBalancerClient.choose("product");
    String requestMsg = "方式二 GET 请求 RibbonServer";
    String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/pro/t-product/findById/"+pid);
    TProduct forObject = restTemplate.getForObject(url, TProduct.class);
    System.out.println(forObject);
    //添加订单
    if(forObject.getKucun()>0){
        //添加订单
        TOrder oreder=new TOrder();
        oreder.setNum(1);
        oreder.setPid(pid);
        oreder.setUid(1);
        boolean save = this.save(oreder);
        return save;
        //oreder.se
    }
    return false;
}

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

使用DiscoveryClient拼接url

@Resource
private DiscoveryClient discoveryClient;
@GetMapping("addOrder/{pid}")
public Result addOrder(@PathVariable("pid") Integer pid){
    List<ServiceInstance> serviceId = discoveryClient.getInstances("product");
    //如果有俩相同的微服务  不能定死是第一个  不然就没有任何的意义
    //随机产生数字
    int i = new Random().nextInt(serviceId.size());
    System.out.println("服务******"+i);
    ServiceInstance instance = serviceId.get(i);
    // id username productname
    Order order=new Order();
    order.setId(1);
    order.setUsername("于永利");
    System.out.println("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid);
    //商品的名字
   Result result= restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid,Result.class);
    ObjectMapper objectMapper=new ObjectMapper();
    Product pro = objectMapper.convertValue(result.getT(), Product.class);
    //jackson
    //HashMap<String,String> product=(HashMap) result.getT();
    order.setProductname(pro.getName());
    return new Result(order);


}

第三种写法:

使用OpenFeign

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

修改pom文件
<!--使用openFeign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
启动类上开启注解

@EnableFeignClients

调用

@FeignClient

service接口:

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

@FeignClient(value="product",fallback = TOrderServiceImpl.class)
public interface ITOrderService{
}
feign接口的实现类

service的实现类

@Service
public class TOrderServiceImpl  implements ITOrderService {


    @Override
    public TProduct addOrder(Integer pid) {
        System.out.println("你调用我了吗");
        if(pid==0){
            System.out.println("出错啦!!!!");
        }
        return null;
    }
}

使实现类生效

加jar

  <!-- -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

开启openfeign对sentinel的支持

(在application.properties中编写)

feign.sentinel.enabled=true

搭建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

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值