当前位置:   article > 正文

Spring Cloud Alibaba 第一篇(Nacos组件)_springcloud alibaba组件

springcloud alibaba组件

一、Spring Cloud Alibaba

1.1.简介

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

Spring Cloud :是一种微服务开发规范,是一套标准接口。所有器实现的框架都 必须要符合 该标准

实现框架:

Spring Cloud Netflix 第一点版本 在去年已经停止更新

Spring Cloud Alibaba 第二代版本,非常的便于介入阿里云各种云服务

1.2. 主要功能

  • 服务限流降级:默认支持WebServlet、WebFlux、OpenFeign、RestTemplate、Spring Cloud Gateway、Zuul、Dubbo 和 RocketMQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics监控。
  • 服务注册与发现:适配Spring Cloud 服务注册与发现标准,默认集成了Ribbon的支持。 提供注册中心相关功能(nacos,eureka,zk)
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。                 我们可以让很多实例 去共享 同一个远程的 application.proerties
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。              消息推送功能,通知
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。。                                                                                                                   解决跨应用之间的 事务 一致性

  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。                                            可以将文件直接存储 阿里云对象存储

  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。                                                 Redis + Quartz或者Elastic-Job来解决。

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

1.3. 组件

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

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

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

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

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

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

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

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

1.4.为什么要用Spring Cloud Alibaba?

1.我们需要知道Spring Cloud Alibaba在Spring Cloud家族中的地位,它是一个套件,与Netflix OSS一样,涵盖了非常多的实用组件,其中也有不少内容存在重叠。

2.我们需要知道Netflix OSS下的诸多重要组件先后宣布停止新功能开发的大背景,而Spring Cloud Alibaba是一个新生项目,正处于高速迭代中。对于未来,相信谁都会选。

3.对于中国用户来说,Spring Cloud Alibaba还有一个非常特殊的意义:它将曾经红极一时的Dubbo,以及阿里巴巴的强力消息中间件RocketMQ融入Spring Cloud体系。还在纠结于如何让这些共存的团队,你们所面临过的各种困难与问题,马上就会迎刃而解。不用再烦恼是不是要扩展Dubbo的注册中心,还是自己为RocketMQ实现一套的Spring Cloud Stream的Binder等等问题。

4.对于Spring Cloud Alibaba的上手学习成本如何呢?

如果您已经是Spring Cloud的用户,那么恭喜您,在Spring Cloud Common的抽象和Spring Cloud Alibaba团队的努力下,你会非常容易、甚至不需要改变多少编码模式,就能适应它。如果您第一次接触Spring Cloud,那么也恭喜您,因为这是有史以来,中文文档最全的一个Spring Cloud组件了,相信机制的您一定也能很快的上手使用它

如何引入依赖

  1. <packaging>pom</packaging>
  2. <properties>
  3. <!-- Environment Settings -->
  4. <java.version>1.8</java.version>
  5. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  6. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  7. <!-- Spring Settings -->
  8. <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
  9. <spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
  10. </properties>
  11. <dependencyManagement>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.cloud</groupId>
  15. <artifactId>spring-cloud-dependencies</artifactId>
  16. <version>${spring-cloud.version}</version>
  17. <type>pom</type>
  18. <scope>import</scope>
  19. </dependency>
  20. <dependency>
  21. <groupId>com.alibaba.cloud</groupId>
  22. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  23. <version>${spring-cloud-alibaba.version}</version>
  24. <type>pom</type>
  25. <scope>import</scope>
  26. </dependency>
  27. </dependencies>
  28. </dependencyManagement>

二、Nacos组件

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

2.1 特性

  • 服务发现和服务健康监测

Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDKOpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODOHTTP&API查找和发现服务。

相当于dubbo的zookeeper和springcloud的eureka

 实现:nacos ,eureka,zookeeper

  • 动态配置服务

动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

相当于动态配置的zookeeper和springcloude-nacos-config

  • 动态 DNS 服务

动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。

  • 服务及其元数据管理

Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

我们可以通过 nacos 完成对注册到nacos 中的所有的实例进行健康检测,包保存其元数据

2.2 作用

  • 注册中心:帮助发现其他服务对应的实例

  • 配置中心:全局的配置文件

  • 健康监控管理中心:监控实例的健康状态

2.3 安装

环境要求

  1. 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。

  2. 64 bit JDK 1.8+;下载 & 配置

  3. Maven 3.2.x+;下载 & 配置

2.3.1.下载安装包

nacos-server-1.2.0-beta.0.zip

注意下载[nacos-server-1.2.0 以上版本会报错

2.3.2 解压

2.3.3 启动

 进入到bin目录

 

2.3.4.访问 路径

http://localhost:8848/nacos

三、springcloud alibaba 实例

1.创建一个服务的生产者 提供服务 springcloud-alibaba-provider

2.创建一个服务的消费者 消费提供的服务springcloud-alibaba-consume

3.1.创建父工程springcloudalibaba

在父工程的pom.xml文件引入以下依赖

  1. <!-- 标记该工程 为父工程-->
  2. <packaging>pom</packaging>
  3. <!--
  4. spring cloud 必须 基于spring boot 实现
  5. -->
  6. <parent>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-parent</artifactId>
  9. <version>2.2.4.RELEASE</version>
  10. </parent>
  11. <properties>
  12. <!-- Environment Settings -->
  13. <java.version>1.8</java.version>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  16. <!-- Spring Settings
  17. spirng cloud 版本是 以伦敦地铁站 命名 Hoxton.SR1
  18. -->
  19. <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
  20. <!--
  21. spring-cloud-alibaba 版本
  22. -->
  23. <spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
  24. </properties>
  25. <!-- 管理子工程 的依赖 ,保证子工程依赖的 jar 和 父工程 保持一致
  26. 在子工程中 不需要加版本号
  27. -->
  28. <dependencyManagement>
  29. <dependencies>
  30. <dependency>
  31. <groupId>org.springframework.cloud</groupId>
  32. <artifactId>spring-cloud-dependencies</artifactId>
  33. <version>${spring-cloud.version}</version>
  34. <type>pom</type>
  35. <scope>import</scope>
  36. </dependency>
  37. <dependency>
  38. <groupId>com.alibaba.cloud</groupId>
  39. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  40. <version>${spring-cloud-alibaba.version}</version>
  41. <type>pom</type>
  42. <scope>import</scope>
  43. </dependency>
  44. </dependencies>
  45. </dependencyManagement>

3.2 创建服务提供者springcloud-alibaba-provider

创建子工程springcloud-alibaba-providerr,引入以下依赖,下面是我的pom.xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springcloudalibaba</artifactId>
  7. <groupId>com.qf</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>springcloud-alibaba-provider</artifactId>
  12. <dependencies>
  13. <!--springBoot 相关 -->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-web</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-actuator</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. <!-- alibaba.cloud 相关-->
  28. <dependency>
  29. <groupId>com.alibaba.cloud</groupId>
  30. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>com.alibaba.cloud</groupId>
  34. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  35. </dependency>
  36. </dependencies>
  37. </project>

创建配置文件,application.properties

  1. # 应用名 模块名 注意应用名 不可以使用_
  2. spring.application.name=springcloud-alibaba-provider
  3. #配置nacos 服务器地址
  4. spring.cloud.nacos.server-addr=localhost:8848
  5. #配置tomcat端口号
  6. server.port=8083
  7. #暴露所有应用断点,便于监控
  8. management.endpoints.web.exposure.include=*

创建启动类

  1. package com.qf;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. @EnableDiscoveryClient //激活nacos相关功能
  6. @SpringBootApplication
  7. public class ProviderApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(ProviderApplication.class,args);
  10. }
  11. }

创建测试类

  1. package com.qf.controller;
  2. import com.qf.entity.Student;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.web.bind.annotation.*;
  5. @RestController //Controller + ResponseBody 该注解下面的方法返回的都是Json数据
  6. public class HelloController {
  7. @Value("${server.port}")
  8. private Integer port;
  9. @RequestMapping("/getMessage/{msg}") //restFul风格
  10. public String getMessage(@PathVariable("msg") String msg){
  11. return "msg:"+msg + "--from-port:" + port;
  12. }
  13. @RequestMapping("/say")
  14. public String say(@RequestParam("msg") String msg){
  15. return "msg:"+msg + "--from-port:" + port;
  16. }
  17. }

测试启动provider

访问nacos管理界面,可以看到

访问 http://localhost:8083/getMessage/hello 和 http://localhost:8083/say?msg=bye

 3.3 创建服务消费者 springcloud-alibaba-consumer

消费者通过nacos调用服务提供者的接口使用LoadBalanceClient 和 RestTemplate来完成

1.创建springcloud-alibaba-consumer

引入以下pom和provider 一致

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springcloudalibaba</artifactId>
  7. <groupId>com.qf</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>springcloud-alibaba-consumer</artifactId>
  12. <dependencies>
  13. <!--springBoot 相关 -->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-web</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-actuator</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. <!-- alibaba.cloud 相关-->
  28. <dependency>
  29. <groupId>com.alibaba.cloud</groupId>
  30. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>com.alibaba.cloud</groupId>
  34. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  35. </dependency>
  36. </dependencies>
  37. </project>

2.创建配置文件

  1. #应用名 模块名 注意应用名 不可以使用_
  2. spring.application.name=springcloud-alibaba-consumer
  3. #配置nacos 服务器地址
  4. spring.cloud.nacos.server-addr=localhost:8848
  5. #配置tomcat端口号
  6. server.port=8085
  7. #暴露所有应用断点,便于监控
  8. management.endpoints.web.exposure.include=*

3.创建启动类

  1. package com.qf;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. @EnableDiscoveryClient //激活nacos相关功能
  6. @SpringBootApplication
  7. public class ConsumerApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(ConsumerApplication.class,args);
  10. }
  11. }

5.创建配置类

  1. package com.qf.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.client.RestTemplate;
  5. @Configuration //标记当前类是配置类,相当于spring中的bean.xml
  6. public class NacosConfig {
  7. /**
  8. * RestTemplate 就是一个帮助我们发起远程http请求的客户端(类似于postman,浏览器)
  9. * */
  10. @Bean //向容器中加入一个RestTemplate
  11. public RestTemplate getRestTemplate(){
  12. return new RestTemplate();
  13. }
  14. }

6.创建测试类

  1. package com.qf.controller;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.cloud.client.ServiceInstance;
  4. import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import org.springframework.web.client.RestTemplate;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. /**
  11. * 主要用于consumer向provider发起远程请求
  12. * */
  13. @RestController
  14. public class NacosConsumerController {
  15. /**
  16. * loadBalancerClient负载均衡的客户端,用来根据服务名从nacos中获取对应的ip
  17. * */
  18. @Autowired
  19. private LoadBalancerClient loadBalancerClient;
  20. /**
  21. * RestTemplate 就是一个帮助我们发起远程http请求的客户端(类似于postman,浏览器)
  22. * */
  23. @Autowired
  24. private RestTemplate restTemplate;
  25. @RequestMapping("/test1")
  26. public String test1(){
  27. // 调用远程 provider 中的 @RequestMapping("/getMessage/{msg}")
  28. // 现在是 写死 地址,也可以使用 nacos 找到 springcloud-alibaba-provider 对应的ip 端口
  29. // String url = "http://localhost:8083/getMessage/hello";
  30. // serviceInstance 就是远程 provider 实例的 ip 和 端口 的封装
  31. ServiceInstance serviceInstance = loadBalancerClient.choose("springcloud-alibaba-provider");
  32. // 得到远程服务实例的ip
  33. //serviceInstance.getHost();
  34. // 得到端口
  35. // serviceInstance.getPort();
  36. //%s 就是需要替换的参数
  37. String url = String.format("http://%s:%s/getMessage/%s",serviceInstance.getHost(),serviceInstance.getPort(),"hello");
  38. // 使用restTemplate 发起网络请求
  39. return restTemplate.getForObject(url,String.class);
  40. }
  41. @RequestMapping("/test2")
  42. public String test2(){
  43. // 远程调用 @RequestMapping("/say")
  44. // public String say(@RequestParam("msg") String msg)
  45. ServiceInstance serviceInstance= loadBalancerClient.choose("springcloud-alibaba-provider");
  46. String url = String.format("http://%s:%s/say?msg={msg}",serviceInstance.getHost(),serviceInstance.getPort());
  47. //msg值的初始化
  48. Map map = new HashMap();
  49. map.put("msg","hello java2109");
  50. // 使用restTemplate 发起网络请求
  51. return restTemplate.getForObject(url,String.class,map);
  52. }
  53. }

启动服务提供者和服务消费者进行测试,

查看nacos管理界面可以看到:http://localhost:8848/nacos

 浏览器访问:http://localhost:8085/test1

RestTemplate:帮助我们发起远程请求的 客户端

使用的都是模板设计模式

LoadBalancerClient:loadBalancerClient 负载均衡的客户端 ,用来 根据服务名 从nacos 中获取对应的ip

 四、Ribbon

如果provider 提供的服务有多个,那么consumer 调用provider时,就需要更多不同的负载均衡算法 选择不同的实例发起请求

4.1 Ribbon概述

是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制
可以实现服务的远程调用和服务的负载均衡协调

4.2 Ribbon的负载均衡

 4.3 示例

1. 在springcloud-alibaba-consumer中引入负载均衡依赖

  1. <!-- 引入负载均衡-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-ribbon
  5. </artifactId>
  6. </dependency>

2.在配置文件中配置负载均衡器(将原来的myConfig类屏蔽)

  1. import com.netflix.loadbalancer.IRule;
  2. import com.netflix.loadbalancer.RandomRule;
  3. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.web.client.RestTemplate;
  7. @Configuration
  8. public class RibbonConfig {
  9. @LoadBalanced // 对RestTemplate 的发起网络请求 进行拦截,
  10. // 运用负载均衡策略(就是按照策略选择对应的ip)
  11. @Bean //向容器中加入一个 RestTemplate
  12. public RestTemplate restTemplate(){
  13. return new RestTemplate();
  14. }
  15. @Bean // 将随机的 策略加入到容器中
  16. public IRule iRule(){
  17. // 创建一个随机的负载均衡策略
  18. IRule rule = new RandomRule();
  19. //2.权重响应时间分配规则 代替ResponseTimeRule 响应时间加权策略
  20. // WeightedResponseTimeRule responseTimeRule=new WeightedResponseTimeRule();
  21. // //3.最低并发策略 分配的时候选择目前并发量最小的
  22. // BestAvailableRule bestAvailableRule=new BestAvailableRule();
  23. // //4.轮训策略
  24. // RoundRobinRule roundRobinRule=new RoundRobinRule();
  25. // //5.重试策略 如果在配置时间内,无法选择服务,尝试选择一个服务 重试机制
  26. // RetryRule retryRule=new RetryRule();
  27. // //6.区域感知策略 就近访问
  28. // ZoneAvoidanceRule zoneAvoidanceRule=new ZoneAvoidanceRule();
  29. 7.可用过滤策略 可用根据阈值进行服务过滤
  30. // AvailabilityFilteringRule filteringRule=new AvailabilityFilteringRule();
  31. return rule;
  32. }
  33. }

3.创建RibbonTestController 测试(屏蔽原来 TestController)

  1. package com.qf.controller;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. import org.springframework.web.client.RestTemplate;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. @RestController
  9. public class RibbonTestController {
  10. /**
  11. * RestTemplate 就是一个帮助我们发起远程http请求的客户端(类似于postman,浏览器)
  12. * */
  13. @Autowired
  14. private RestTemplate restTemplate;
  15. @RequestMapping("/test1")
  16. public String test1(){
  17. // 调用远程 provider 中的 @RequestMapping("/getMessage/{msg}")
  18. // http://springcloud-alibaba-provider/getMessage/%s
  19. //restTemplate 向 http://springcloud-alibaba-provider服务发起请求,但是会被ribbon 进行拦截,
  20. // 会根据负载均衡策略选择其中一台 provider实例,并替换 springcloud-alibaba-provider为 ip:端口
  21. // %s 就是需要替换的参数
  22. String url = String.format("http://springcloud-alibaba-provider/getMessage/%s","hello");
  23. // 使用restTemplate 发起网络请求
  24. return restTemplate.getForObject(url,String.class);
  25. }
  26. @RequestMapping("/test2")
  27. public String test2(){
  28. // 远程调用 @RequestMapping("/say")
  29. // public String say(@RequestParam("msg") String msg)
  30. String url = String.format("http://springcloud-alibaba-provider/say?msg={msg}");
  31. //msg值的初始化
  32. Map map = new HashMap();
  33. map.put("msg","hello java2109");
  34. // 使用restTemplate 发起网络请求
  35. return restTemplate.getForObject(url,String.class,map);
  36. }
  37. }

4.启动 两个provider (端口一定不同),在启动一个consumer进行测试

 然后修改端口号为8084,再次启动

 然后启动consumer

 然后访问:http://localhost:8848/nacos/ 

打开新的页面,输入:http://localhost:8085/test1

Ribbon:是一个负载均衡的客户端,他可以拦截RestTemplate 发起的请求,并且将请求路径中的服务名,根据负载均衡策略替换为ip:端口,并发起网络请求

底层原理:使用aop ,动态代理实现

五、Feign

Feign:就是伪装,feign 就是可以将远程的访问调用,伪装成本地的接口调用。

Feign = RestTemplate + Ribbon

5.1 什么是Feign?

Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。 Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。

5.2 实例1

1.创建一个springcloud-feign-cosumer工程,导入依赖

  1. <dependencies>
  2. <!--springBoot 相关 -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-actuator</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-test</artifactId>
  14. <scope>test</scope>
  15. </dependency>
  16. <!-- alibaba.cloud nacos 相关-->
  17. <dependency>
  18. <groupId>com.alibaba.cloud</groupId>
  19. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>com.alibaba.cloud</groupId>
  23. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  24. </dependency>
  25. <!-- opengin -->
  26. <dependency>
  27. <groupId>org.springframework.cloud</groupId>
  28. <artifactId>spring-cloud-starter-openfeign</artifactId>
  29. </dependency>
  30. </dependencies>

2.创建配置文件application.properties

  1. # 应用名 模块名 注意应用名 不可以使用_ springcloud-alibaba-feign-consumer
  2. spring.application.name=springcloud-alibaba-feign-consumer
  3. #配置nacos 服务地址
  4. spring.cloud.nacos.server-addr=localhost:8848
  5. server.port=8086
  6. #暴露所有应用断点,便于监控
  7. management.endpoints.web.exposure.include=*

3.创建启动类

  1. package com.qf;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. import org.springframework.cloud.openfeign.EnableFeignClients;
  6. @EnableFeignClients //激活feign 相关功能
  7. @EnableDiscoveryClient //激活nacos功能
  8. @SpringBootApplication
  9. public class FeignApplication {
  10. public static void main(String[] args) {
  11. SpringApplication.run(FeignApplication.class,args);
  12. }
  13. }

4.创建Feign伪装接口

  1. package com.qf.service;
  2. import com.qf.entity.Student;
  3. import org.springframework.cloud.openfeign.FeignClient;
  4. import org.springframework.web.bind.annotation.*;
  5. /**
  6. * 伪装 接口
  7. *
  8. * 我们需要向那个一个 服务发起远程调用,就需要将远程的处理器 方法拷贝过来,只剩方法名,没有方法体
  9. * 1.拷贝 provider 中的 处理器方法
  10. * 2.删除方法体
  11. *
  12. * @FeignClient(value = "springcloud-alibaba-provider")
  13. * //标记当前接口 是一个feign伪装接口,feign 更具接口配置的方法,生成对应的实现类
  14. * 向远程服务发起请求 ----》 将改接口实现 完成 RestTemplate 请求
  15. *
  16. */
  17. @FeignClient(value = "springcloud-alibaba-provider")
  18. public interface FeignService {
  19. @RequestMapping("/getMessage/{msg}") //restFul风格
  20. public String getMessage(@PathVariable("msg") String msg);
  21. @RequestMapping("/say")
  22. public String say(@RequestParam("msg") String msg);
  23. /**
  24. * 更新学生
  25. * @param Student
  26. * @return
  27. */
  28. @RequestMapping("/updateStudent")
  29. public Student updateStudent(@RequestBody Student student);
  30. }

5.创建FeignTestController使用伪装接口进行测试

  1. package com.qf.controller;
  2. import com.qf.entity.Student;
  3. import com.qf.service.FeignService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. @RestController
  8. public class FeignTestController {
  9. @Autowired
  10. private FeignService feignService;
  11. @RequestMapping("/test1")
  12. public String test1(){
  13. // 调用远程 provider 中的 @RequestMapping("/getMessage/{msg}")
  14. return feignService.getMessage("hello BeiJing");
  15. }
  16. @RequestMapping("/test2")
  17. public String test2(){
  18. // 远程调用 @RequestMapping("/say")
  19. // public String say(@RequestParam("msg") String msg)
  20. return feignService.say("hello - java2109");
  21. }
  22. }

启动 两个provider (端口一定不同),再启动Fegin-consumer进行测试

 5.3 实例二(使用feign 远程调用传递对象)

1.创建common工程

 2.创建实体类Student

  1. import java.io.Serializable;
  2. /**
  3. * 创建一个实体类
  4. * 1.get set 方法
  5. * 2.toString()
  6. * 3.实现序列化 序列化作用:1.便于保存对象存入磁盘 2.便于网络间传输
  7. *
  8. * 4.如果创建了 有参构造 ,必须创建无参构造 必须注意
  9. */
  10. public class Student implements Serializable {
  11. private int id;
  12. private String name;
  13. private int age;
  14. private String sex;
  15. private float height;
  16. public Student() {
  17. }
  18. public Student(int id, String name, int age, String sex, float height) {
  19. this.id = id;
  20. this.name = name;
  21. this.age = age;
  22. this.sex = sex;
  23. this.height = height;
  24. }
  25. public int getId() {
  26. return id;
  27. }
  28. public void setId(int id) {
  29. this.id = id;
  30. }
  31. public String getName() {
  32. return name;
  33. }
  34. public void setName(String name) {
  35. this.name = name;
  36. }
  37. public int getAge() {
  38. return age;
  39. }
  40. public void setAge(int age) {
  41. this.age = age;
  42. }
  43. public String getSex() {
  44. return sex;
  45. }
  46. public void setSex(String sex) {
  47. this.sex = sex;
  48. }
  49. public float getHeight() {
  50. return height;
  51. }
  52. public void setHeight(float height) {
  53. this.height = height;
  54. }
  55. @Override
  56. public String toString() {
  57. return "Student{" +
  58. "id=" + id +
  59. ", name='" + name + '\'' +
  60. ", age=" + age +
  61. ", sex='" + sex + '\'' +
  62. ", height=" + height +
  63. '}';
  64. }
  65. }

打成jar包,并存入到本地仓库

 4.在provider中引入依赖

  1. <!-- 引入 公共的依赖 -->
  2. <dependency>
  3. <groupId>com.qfedu</groupId>
  4. <artifactId>springcloud-alibaba-common</artifactId>
  5. <version>1.0-SNAPSHOT</version>
  6. </dependency>

5.在provider 创建接受方法 一定要加 @RequestBody

  1. /**
  2. * 更新学生
  3. * // 普通 的键值对 转对象 updateStudent(Student student),不可以被接受,只能接受json 转对象
  4. *
  5. * Student updateStudent(@RequestBody Student student)
  6. *
  7. * @param Student
  8. * @return
  9. */
  10. @RequestMapping("/updateStudent")
  11. public Student updateStudent(@RequestBody Student student){
  12. // 修改名字
  13. student.setName(student.getName() +" --port:"+port);
  14. System.out.println("服务提供者 更新student = " + student);
  15. return student;
  16. }

6.在feign-consumer 中引入 common

  1. <!-- 引入 公共的依赖 -->
  2. <dependency>
  3. <groupId>com.qfedu</groupId>
  4. <artifactId>springcloud-alibaba-common</artifactId>
  5. <version>1.0-SNAPSHOT</version>
  6. </dependency>

7.在feign-consumer 的 FeignService 中添加

  1. /**
  2. * 更新学生
  3. * @param Student
  4. * @return
  5. */
  6. @RequestMapping("/updateStudent")
  7. public Student updateStudent(@RequestBody Student student);

8.在FeignTestController添加方法

  1. @RequestMapping("/test3")
  2. public Student test3() {
  3. Student student = new Student(100,"xiaoming", 13,"F",170);
  4. return feignService.updateStudent(student);
  5. }

9.测试

先重新启动 provider ,feign-consumer

然后观察 nacos ,再测试

5.4 Feign的容错机制

容错:consumer 调用provider,如果Provider 有异常,消费者也会报错,容错机制就是保证,Provider 有异常,消费依然可以正常的返回兜底数据,客户感觉不到 provider有异常

1.在配置文件中开启容错

  1. #开启 feign 容错机制
  2. feign.hystrix.enabled=true

2.实现容错类

  1. package com.qf.service.impl;
  2. import com.qf.entity.Student;
  3. import com.qf.service.FeignService;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * Feign 伪装接口的容错实现类
  7. * */
  8. @Component //加入到容器中
  9. public class FeignServiceFallBackImpl implements FeignService {
  10. @Override
  11. public String getMessage(String msg) {
  12. return "feign 触发容错 getMessage 返回数据" + msg;
  13. }
  14. @Override
  15. public String say(String msg) {
  16. return "feign 触发容错 say 返回数据" + msg;
  17. }
  18. @Override
  19. public Student updateStudent(Student student) {
  20. student.setName(student.getName()+"----容错返回");
  21. return student;
  22. }
  23. }

3.在FeignService伪装类接口中配置容错策略

  1. package com.qf.service;
  2. import com.qf.entity.Student;
  3. import com.qf.service.impl.FeignServiceFallBackImpl;
  4. import org.springframework.cloud.openfeign.FeignClient;
  5. import org.springframework.web.bind.annotation.PathVariable;
  6. import org.springframework.web.bind.annotation.RequestBody;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RequestParam;
  9. /**
  10. * 伪装 接口
  11. *
  12. * 我们需要向那个一个 服务发起远程调用,就需要将远程的处理器 方法拷贝过来,只剩方法名,没有方法体
  13. * 1.拷贝 provider 中的 处理器方法
  14. * 2.删除方法体
  15. *
  16. * @FeignClient(value = "springcloud-alibaba-provider")
  17. * //标记当前接口 是一个feign伪装接口,feign 更具接口配置的方法,生成对应的实现类
  18. * 向远程服务发起请求 ----》 将改接口实现 完成 RestTemplate 请求
  19. *
  20. * fallback=FeignServiceFallBackImpl.class 配置容错实现类
  21. */
  22. @FeignClient(value = "springcloud-alibaba-provider",fallback= FeignServiceFallBackImpl.class)
  23. public interface FeignService {
  24. @RequestMapping("/getMessage/{msg}") //restFul风格
  25. public String getMessage(@PathVariable("msg") String msg);
  26. @RequestMapping("/say")
  27. public String say(@RequestParam("msg") String msg);
  28. /**
  29. * 更新学生
  30. * @param Student
  31. * @return
  32. */
  33. @RequestMapping("/updateStudent")
  34. public Student updateStudent(@RequestBody Student student);
  35. }

4.进行测试

1.重新启动 feign-consumer 正常返回数据

2.停止provider ,则feign-consumer 返回容错数据

 正常访问,此时的provider是正常状态

 将provider关掉,继续访问:http://localhost:8086/test1

 六、Nacos Config(分布式配置中心)

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是 Spring Cloud Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

1.创建springcloud-alibaba-nacos-fonfig 应用,并引入依赖

  1. <dependencies>
  2. <!--springBoot 相关 -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <!-- spring 的监控模块-->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-actuator</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-test</artifactId>
  15. <scope>test</scope>
  16. </dependency>
  17. <!-- alibaba.cloud 相关-->
  18. <dependency>
  19. <groupId>com.alibaba.cloud</groupId>
  20. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>com.alibaba.cloud</groupId>
  24. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  25. </dependency>
  26. </dependencies>

2.nacos 配置文件

springboot 读取配置文件的顺序

bootstrap.properties ---->bootstrap.yaml ------>application.proerties---->application.yaml

bootstrap.properties

  1. #应用springboot 启动前 先去读取bootstrap.properties ,然后去配置中心拉取对应的配置文件
  2. # 应用名 模块名 注意应用名 不可以使用_ springcloud_alibaba_provider
  3. spring.application.name=springcloud-alibaba-nacos-provider
  4. #配置nacos 服务地址
  5. spring.cloud.nacos.server-addr=localhost:8848
  6. server.port=8086
  7. #暴露所有应用断点,便于监控
  8. management.endpoints.web.exposure.include=*
  9. student.name=xiaoming

3.在nacos 配置中创建 对应配置文件

服务名.properties

 

 4.配置启动类

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  4. @EnableDiscoveryClient
  5. @SpringBootApplication
  6. public class ConfigApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ConfigApplication.class,args);
  9. }
  10. }

 5.读取配置文件内容测试

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class ConfigController {
  8. // 在启动时 获取配置文件一次数据,中间不改变
  9. @Value("${student.name}")
  10. private String studentName;
  11. @Autowired
  12. // ConfigurableEnvironmentConfiguration 实时得到配置中中对应配置文件的数据
  13. private ConfigurableEnvironmentConfiguration configuration;
  14. @RequestMapping("/getStudent")
  15. public String getStudent(){
  16. return "配置文件---studentName:"+studentName +"---与配置中心保持一致的数据:"+configuration.getString("student.name");
  17. }
  18. }

测试

 修改文件内容,得到立即的推送

可以在配置文件加入spring.cloud.nacos.config.refresh.enabled=false禁止自动刷新

七、Nacos Config 多环境的配置

bootstrap.properties  application.properties 默认配置都是任何时候都生效的

我们还可以配置自定义环境,便于开发,但是前提必须是要先激活

自定义的环境有:

        ①开发环境:bootstrap-dev.properties

        ②测试环境:bootstrap-test.properties

多环境的配置有两种:

第一种是在bootstrap.properties中配置,下面是我的bootstrap.properties文件的内容

  1. #应用SpringBoot 启动前,先去读取bootstrap.properties,然后去配置中心拉去对应的配置文件
  2. #应用名 模块名 主要应用名不可以使用_
  3. spring.application.name=springcloud-alibaba-nacos-config
  4. #配置nacos服务地址
  5. spring.cloud.nacos.server-addr=localhost:8848
  6. #配置tomcat端口号
  7. server.port=8087
  8. #暴露所有应用端点,便于监控
  9. management.endpoints.web.exposure.include=*
  10. # 将该文件中配置的student.name注释掉
  11. #student.name=xiaoming
  12. #激活dev环境 让bootstrap-dev.properties生效
  13. spring.cloud.nacos.config.file-extension=properties
  14. spring.profiles.active=dev

创建bootstrap-dev.properties文件

  1. #应用springboot 启动前 先去读取bootstrap.properties,然后去配置中心拉取对应的配置文件
  2. #配置student.name
  3. student.name=xiaoming-dev

先启动nacos,再启动项目,先访问:http://localhost:8848/nacos 查看服务注册上没

然后访问服务:http://localhost:8086/getStudent

在配置中心创建配置文件springcloud-alibaba-nacos-config-dev.properties

 刷新页面:http://localhost:8086/getStudent

修改配置文件的内容,再次发布,再次刷新页面: http://localhost:8086/getStudent

可以看到内容实时在更新

 

第二种方式:懒得测了,感兴趣的可以测测

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/68836
推荐阅读
相关标签
  

闽ICP备14008679号