第一篇:SpringCloudAlibaba入门与实践

目录

1 SpringCloudAlibaba介绍

2 服务注册与发现中心

2.1 注册中心的原理

2.2 服务拆分

2.3 服务间调用

2.3.1 RestTemplate调用远程服务

2.3.2 通过Nginx维护服务列表

2.3.3 通过Nacos实现注册中心

2.4 总结

3 Netflix Eureka注册和发现中心

3.1 创建父工程

3.2 搭建Eureka服务注册中心

3.3 创建子项目和接口开发

3.4 服务注册与发现

3.4.1 服务注册

3.4.2 服务发现

3.5 测试

3.6 总结

4 Ribbon的负载均衡

4.1 负载均衡原理

4.2 负载均衡策略配置

4.3 懒加载和饥饿加载

4.4 总结

5 Nacos服务管理平台

5.1 Nacos介绍和安装

5.1.1 Nacos介绍

5.1.2 Nacos安装

5.1.3 Nacos启动

5.2 Nacos快速入门

5.2.1 服务注册

5.2.2 服务发现

5.2.3 测试

5.3 总结


码字不易,喜欢就点个关注❤,持续更新技术内容。相关资料请私信。

相关内容:

第二篇:SpringCloudAlibaba入门与实践-CSDN博客

1 SpringCloudAlibaba介绍

目前,Spring Cloud Alibaba 包含如下组件:

开源部分

  1. Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

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

  3. RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

  4. Dubbo:Apache Dubbo 是一款高性能 Java RPC 框架,用于实现服务通信。

  5. Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

平台服务部分

  1. Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

  2. Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

  3. Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

2 服务注册与发现中心

注册与发现中心是以"服务"为中心构建现代应用架构的基础服务设施,能够更快速、简便地构建、管理和交付微服务平台。相当于微服务架构中的通讯中心,每个微服务提供者会将服务地址、端口等注册到注册中心,服务消费者再通过注册中心查找服务地址,然后进行调用。

特点说明
服务的自动注册微服务应用在启动时,通过注册中心客户端组件,将服务的相关信息自动注册给注册中心服务端。
服务的自动发现服务消费者需要能实时监听到注册中心中服务信息的变更,以能在真正调用服务时不会出现错误。
服务的健康检查当注册到注册中心的微服务实例宕机后,注册中心服务端发现实例已经宕机,并把相关信息从注册中心删除掉。

常见注册中心组件:Netflix Eureka、Alibaba Nacos、谷歌Consul、雅虎ZooKeeper。管理所有微服务、解决微服务之间调用关系错综复杂难以维护的问题。

2.1 注册中心的原理

注册中心分为服务端与客户端,服务端主要功能是记录服务信息和心跳监控,也就是为客户端提供配置服务和健康检查。客户端与微服务嵌套在一起,微服务相对地可以分为服务提供者和服务消费者,可以用多语言实现。提供者通过客户端将自己信息注册到注册中心,每隔几秒带上了服务名、服务ip、服务端口等信息向注册中心服务端发送心跳请求。消费者根据调用地微服务名称从注册中心拉取多个服务实例列表,基于此服务列表做负载均衡,挑选一个微服务发起远程调用。

同时注册中心也会通过http/tcp向微服务客户端主动发起健康检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。

2.2 服务拆分

  1. 微服务相互独立开发,不需要重复开发相同的业务。

  2. 微服务数据独立,不要访问其他微服务的数据库。

  3. 微服务可以将自己的业务暴露为接口供其他为微服务调用。

2.3 服务间调用

2.3.1 RestTemplate调用远程服务

RestTemplate是Spring封装的HTTP接口调用模板类,可以通过restTemplate发起的http请求调用微服务接口地址(微服务的ip、端口、接口路径的请求参数),但微服务接口地址是硬编码的方式写死的。如果一个微服务创建多个实例,形成微服务集群,怎么处理多个实例的调用。还有如果微服务接口名、参数或者请求方式更改了,那么也得同步修改restTemplate的调用。所以通过调用写死的服务地调用是很麻烦的。

2.3.2 通过Nginx维护服务列表

解决这个问题就需要负载均衡机制,如在中间加一个Nginx,为该服务分配一个二级域名,通过二级域名代理到不同的服务机器上,这样的问题是如当一个大型网站有大量的访问时,上百个服务系统都要启动很多机器,当访问量少时又要减机器,那么就涉及到大量的Nginx配置文件要修改。已经淘汰了。

2.3.3 通过Nacos实现注册中心

通过SpringBoot在每个微服务上自动装配Nacos客户端,因为在Nacos中默认集成了Ribbon的支持,只需要在服务启动类注入的RestTemplate方法上添加Ribbon的@LoadBalanced注解,赋予restTemplate能够解析微服务的能力。这样在控制器方法中通过restTemplate调用的微服务接口地址就不用写死,只需将机器的地址改为服务名称作为服务域名,就能自动对该微服务地多个实例实现负载均衡。

如定义了一个分布式架构的远程服务接口调用,当向该服务接口地址发送请求时,在底层会被Ribbon中的LoadBalancerInterceptor拦截器拦截,然后进行服务接口地址的域名解析为注册中心服务的地址,拉取服务下所有的机器地址列表,然后在每次对该服务接口调用时在客户端通过Ribbon基于缓存的服务实例列表实现负载均衡。

通过以上分析就可以回答以下两个问题了:

  1. 每次都要到注册中心拉取信息吗?注册中心宕机了怎么办?

  2. 拉取微服务的信息对应的机器宕机了怎么办?

2.4 总结

总结,Nacos注册中心会自动对每个微服务下启动的机器的IP和端口进行注册维护,当A服务要访问B服务的功能接口时,通过RestTemplate请求B服务下功能接口的服务域名和端口,会由Ribbon解析域名地址,然后根据Ribbon自动间断地向注册中心拉取的机器服务接口地址,当然还有Nacos主动推送注册维护的机器,最后Ribbon在客户端本地实现负载均衡。

3 Netflix Eureka注册和发现中心

Eureka停更后,比较新的技术都不支持了,一般都将Eureka换成了Nacos,不再推荐使用。不过我们可以通过学习Eureka来了解注册中心的功能。不过还在维护。

3.1 创建父工程

首先创建一个空百的Maven项目父工程springcloud-demo,因为父工程是用来统一管理依赖的,不需要写逻辑业务,所以可以把src目录删除,留下一个pom.xml文件就行。(注意自己Maven的配置,详细可以看http://t.csdn.cn/TSAgL

在父工程pom文件引入相关依赖坐标。

<!-- springCloud -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

只要子项目的pom文件中写了某依赖项,不指定具体版本,子项目会从父项目中继承该依赖,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

3.2 搭建Eureka服务注册中心

接下来就可以在父工程之下创建一个Maven子项目来搭建Eureka,与其他服务模块不同的是,pom文件中引入的是spring-cloud-starter-netflix-eureka-server的依赖坐标,通过SpringBoot在Eureka服务上自动装配Eureka服务端:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    <version>2.1.2.RELEASE</version>
</dependency>

编写启动类,添加@EnableEurekaServer注解:

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

添加application.yml文件,配置以下信息,包括项目的服务端口和服务名称以及Eureka的配置,引入Eureka服务端依赖之后就可以配置Eureka服务端的地址信息了,因为Eureka也需要将自己注册到注册中心:

server:
  port: 10100 # 服务端口
spring:
  application:
    name: eurekaserver #服务名称
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://localhost:10100/eureka/

3.3 创建子项目和接口开发

接着创建订单和用户子项目模块:

以订单服务项目为例,在java源文件下创建订单相关的目录,以及启动类。

首先在在pojo中创建用户类和订单类。注意属性名要与数据库表中的字段对应。我就是因为订单类中定义定义的user_id属性"i"大写了,而数据库是小写的,所以开始在mapper层返回的order对象user_id就为null了,最后在使用restTemplate远程调用,根据user_id查询用户接口的地方就报错了,所以一直摸不着头。可以看到注释掉远程调用后user_Id为null。

在mapper中定义OrderMapper,然后定义一个通过id查询订单的方法。

@Mapper
public interface OrderMapper {
    @Select("select * from tb_order where id = #{id}")
    Order findById(Long id);
}

然后在service中调用注入OrderMapper使用查询方法返回订单对象。然后进行业务处理,返回订单列表。远程调用可以先不看,看完服务注册和服务发现后再回来梳理。我们通过restTemplate发起的http请求远程调用userservice微服务用户查询的接口地址。最后返回完整的订单列表。

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

最后在web中创建订单控制器OrderController,定义查询订单的接口。接收前端发送的请求和传递的订单id,调用业务层方法进行处理。

@RestController
@RequestMapping("/order")
public class OrderController {
​
   @Autowired
   private OrderService orderService;
​
    @GetMapping("/{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }
}

用户服务的用户查询接口开发与订单查询一样,只是订单查询多了用户查询接口的远程调用(多表联查)。

3.4 服务注册与发现

3.4.1 服务注册

和Eureka服务一样,订单服务和用户服务也需要引入Eureka的依赖,只不过订单和用户服务引入的是Eureka的客户端eureka-client。之前说过,只要父工程引入了依赖信息,子项目引入相关依赖时可以不指定坐标版本,自动从父工程中继承依赖。如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

<!--eureka客户端依赖坐标-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

同样的,引入依赖之后要进行配置,和Eureka服务一样需要配置项目启动端口、服务名称以及配置Eureka的注册中心地址,这样就能把该服务注册到Eureka中。

server:
  port: 8081 #客户端端口
spring:
  application:
    name: orderservice # 配置服务名称和eureka地址,方便注册
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://localhost:10100/eureka/ # 配置服务名称和eureka地址,方便注册

最后先启动Eureka服务,然后启动订单和用户服务,在Eureka提供的页面可以看到已经将三个服务实例注册到了Eureka注册中心:

这样服务注册就完成了。

启动多个实例进行注册,右键需要需要模拟多实例部署的服务:

修改Name,为了避免端口冲突,需要修改端口设置:

最后可以看到复制出来的服务实例。

3.4.2 服务发现

服务发现其实就服务拉取,服务拉取是基于服务名称获取服务实例列表,然后再对服务列表做负载均衡。

1.首先在在服务启动类注入的RestTemplate方法上添加Ribbon的负载均衡注解@LoadBalanced,赋予restTemplate能够解析微服务和实现复杂均衡的能力。

@Bean
// ribbon的负载均衡注解
@LoadBalanced
// 当通过restTemplate调用微服务接口地址时,在底层会被LoadBalancerInterceptor拦截器拦截,
// 拦截后通过执行RibbonLoadBalancerClient的execute方法对服务名称进行解析,在execute中调用getLoadBalancer方法得到DynamicServerListBalancer动态服务列表均衡器对象,该对象在注册中心拉取到对应的服务实例地址列表。然后再在execute中调用getServer找IRule接口基于规则挑出某个服务实例地址返回给RibbonLoadBalancerClient,execute将服务返回。将服务名称替换为地址最终成功发送请求。
public RestTemplate restTemplate() {
    return new RestTemplate();
}

2.然后修改OrderService代码,修改url路径,用服务名代替ip、端口:(这部分就是OrderService中远程调用业务)

// url
String url = "http://userservice/user/" + order.getUserId();
// 利用RestTemplate发起http请求实现远程调用,查询用户。
User user = restTemplate.getForObject(url, User.class);

启动全部微服务,可以看到注册中心的服务列表,其中userservice服务启动了两个实例,分别在8080端口和8082端口:

3.5 测试

测试请求用户服务中查询用户的接口:

测试请求订单服务中查询订单的接口:

这样基于Eureka注册中心的微服务基础搭建就完成了。

3.6 总结

  1. 搭建EurekaServer

  1. 引入eureka-server依赖。

  2. 添加@EnableEurekaServer注解。

  3. 在application.yml中配置eureka地址。

  1. 搭建业务服务模块

  1. 创建服务项目

  2. 开发服务接口

  1. 服务注册

  1. 引入eureka-client依赖

  2. 在application.yml中配置eureka地址

  1. 服务发现

  1. 引入eureka-client依赖

  2. 在application.yml中配置eureka地址

  3. 给RestTemplate添加@LoadBalanced注解

  4. 用服务提供者的服务名称作为远程调用的域名

当然,因为Eureka集成了Ribbon,现在只是基于Spring的RestTemplate远程调用和Ribbon的域名解析,简单使用了一下Eureka的服务注册和服务发现的功能。后续还有Ribbon的负载均衡等等内容。

4 Ribbon的负载均衡

4.1 负载均衡原理

通过restTemplate调用微服务接口地址时,在底层会被LoadBalancerInterceptor拦截器拦截,拦截后通过执行RibbonLoadBalancerClient的execute方法对服务名称进行解析。

在execute中调用getLoadBalancer方法得到DynamicServerListBalancer动态服务列表均衡器对象,该对象在注册中心拉取到对应的服务实例地址列表。然后再在execute中调用getServer找IRule接口基于规则挑出某个服务实例地址返回给RibbonLoadBalancerClient,execute将服务返回。将服务名称替换为地址最终成功发送请求。

整个过程就是解析服务域名和实现负载均衡。

4.2 负载均衡策略配置

Ribbon内置策略规则说明
RoundRobinRule简单轮询服务列表来选择服务器。是Ribbon默认的负载均衡规则。
AvailabilityFilteringRule按照规则忽略服务器
WeightedResponseTimeRule为每一个服务器赋予权重值。服务器响应时间越长,权重越小。这个规则会随机选择服务器,权重会影响服务器的选择。
ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个个机房。而后对Zone内的多个服务器进行轮询。
BestAvailableRule忽视一些短路的服务器,并选择并发数较低的服务器。
RandomRule随机选择一个可用的服务器。
RetryRule重试机制的选择逻辑。

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

1.代码方式:在服务启动类中定义一个新的Rule:

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

2.配置文件方式:在服务配置文件中,添加新的配置也可以修改规则,如下是对userservice服务访问的负载均衡规则:

userservice: 
    ribbon: 
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

两种方式的区别:

  1. 在进行远程调用的服务的启动类中定义,面对的是所有服务访问使用的负载均衡规则。

  2. 而在服务配置文件中进行单一服务的配置,当然对应的也是单个的服务使用的负载均衡规则。

4.3 懒加载和饥饿加载

Ribbon对服务列表实现负载均衡访问时,默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会比较长。而采用饥饿加载则会在项目启动时创建,降低第一次访问的耗时。

第一次访问时,如下分别是懒加载和饥饿加载所用的时间:

第一次加载后再次访问:

通过下面配置开启饥饿加载:

ribbon: 
    eager-load:
        enabled: true # 开启饥饿加载
        clients: 
            -userservice # 指定userservice这个服务饥饿加载
            -xxxservice

4.4 总结

  1. Ribbon负载均衡规则

规则接口是IRule

默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询。

  1. 负载均衡自定义方式

代码方式:配置灵活,但修改时需要重新打包发布

配置方式:直观,方便,无需重新打包发布,但是无法做到全局配置。

  1. 饥饿加载

开启饥饿加载

指定饥饿加载的服务名称

5 Nacos服务管理平台

首先我们先来看一下SpringCloud通用模块中的两个接口,一个是服务发现和服务注册的接口,无论是Eureka还是Nacos的注册和发现,都是基于这两个接口实现的。当我们要替换注册和发现中心时只需要引入新的依赖,配置新的服务注册地址,SpringBoot会进行自动装配,服务提供者和服务消费代码不需要修改。

5.1 Nacos介绍和安装

5.1.1 Nacos介绍

官方:一个更易于创建云原生应用的动态服务发现(Nacos Discovery)、服务配置(Nacos Config)和服务管理平台。一句话nacos就是集注册中心、配置中心和服务管理平台的组件。

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

Nacos的关键特性包括:

  1. 流量控制和服务退化降级

  2. 服务注册和发现

  3. 分布式配置

  4. 事件驱动

  5. 消息总线

  6. 分布式事务

  7. Dubbo RPC

5.1.2 Nacos安装

这里只展示Windows系统的安装过程。

搜索Nacos官方网站,进入Nacos的Github仓库,在右侧点击进入。

在下面有很多的版本标签,点击进入。

然后选择nacos服务进行下载。

如下是nacos解压后的目录结构:

5.1.3 Nacos启动

进入bin目录,如果直接双击startup.cmd执行文件,nacos默认是集群启动方式。

可以通过指令修改为单机启动模式:

startup.cmd -m standalone

可以看到nacos服务已经在8848端口运行了:

5.2 Nacos快速入门

5.2.1 服务注册

  1. 从SpringCloudAlibaba官网复制spring-cloud-alibaba的依赖坐标,然后在cloud-demo父工程中添加:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

1.注释掉eureka客户端依赖,添加nacos的客户端依赖坐标:

<!-- nacos客户端依赖,父工程已经引入了springcloudalibaba,这里就不用写版本号了 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2.修改微服务中的配置文件,在spring下添加nacos服务端口,注释掉eureka地址。

spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848 # nacos服务地址
​
#eureka:
#  client:
#    service-url: # eureka的地址信息
#      defaultZone: http://localhost:10100/eureka/ # 配置服务名称和eureka地址,方便注册

注意注释掉服务中原有的eureka依赖。

5.2.2 服务发现

因为Nacos也集成了Ribbon,所以同样会进行域名解析然后拉取服务列表,并实现负载均衡。

5.2.3 测试

首先启动Nacos服务:

打开nacos提供的页面,账号和密码默认都是nacos,提交后进入nacos控制台页面:

打开服务列表,暂时还没有服务注册到nacos:

我们之前已经配置在每个服务配置好了nacos注册中心的地址,现在启动服务,刷新nacos控制页面。可以看到nacos注册中心的服务列表,其中userservice服务启动了两个服务实例,分别在8080端口和8082端口:

访订单服务的订单查询接口,同时远程调用用户服务的查询接口,成功返回结果:

5.3 总结

  1. Nacos服务搭建

  1. 下载安装包

  2. 解压

  3. 在bin目录下运行指令:

startup.cmd -m standalone
  1. Nacos服务注册和发现

  1. 在父工程引入SpringCloudAlibaba依赖

  2. 在所有子工程的服务中引入nacos-discovery客户端依赖

  3. 在所有服务中配置nacos服务地址,spring.cloud.nacos.server.addr

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Maxlec

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

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

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

打赏作者

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

抵扣说明:

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

余额充值