SpringCloud快速入门

SpringCloud

一、SpringCloud–Alibaba

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

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

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

在这里插入图片描述

本次演示用的是G版Cloud,所以导入以下版本依赖

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

springboot版本

<version>2.1.8.RELEASE</version>

DependencyManagement和Dependencies

Maven使用dependencyManagement元素来提供了一种管理依赖版本号的方式。

通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement元素。

使用pom.xml中的dependencyManagement元素能让所有在子项目中引用个依赖而不用显式的列出版本量。

Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个
dependencyManagement元素中指定的版本号。

这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改;另外如果某个子项目需要另外的一个版本,只需要声明version就可。

区别
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。

如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom。

如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

二、欢迎来到 Nacos 的世界!

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

Nacos就是注册中心+配置中心的组合,Nacos = Eureka + Config + Bus

能干嘛

  • 替代Eureka做服务注册中心
  • 替代Config做服务配置中心

在这里插入图片描述

据说Nacos在阿里巴巴内部有超过10万的实例运行,已经过了类似双十一等各种大型流量的考验。

三、nacos作为服务注册中心

官网:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md

nacos server下载

访问:https://github.com/alibaba/nacos/releases

安装

  • 本地Java8+Maven环境已经OK先
  • 官网下载Nacos
  • 解压安装包,cmd bin目录,启动startup.cmd

在这里插入图片描述

  • 命令运行成功后直接访问http://localhost:8848/nacos,默认账号密码都是nacos
  • 启动失败:修改startup.cmd MODE 为standalone ,然后切换默认数据库方法下面有,标题是Nacos持久化切换配置
  • 结果页面

在这里插入图片描述

四、Spring Cloud 应用接入 Nacos Discovery

创建两个springboot项目:cloud-nacos-consumer-8001,cloud-nacos-provider-9001

1.首先,修改 pom.xml 文件,引入 Nacos Discovery Starter。

		<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

2.在应用的 /src/main/resources/application.properties 配置文件中配置 Nacos Server 地址

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

3.使用 @EnableDiscoveryClient 注解开启服务注册与发现功能

测试

先启动8848Nacos注册中心

启动8001,9001

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

查看服务管理---->服务列表

五、nacos配置中心

简单理解配置中心的作用就是对配置统一管理,修改配置后应用可以动态感知,而无需重启。

因为在传统项目中,大多都采用静态配置的方式,也就是把配置信息都写在应用内的ymlproperties这类文件中,如果要想修改某个配置,通常要重启应用才可以生效。

但有些场景下,比如我们想要在应用运行时,通过修改某个配置项,实时的控制某一个功能的开闭,频繁的重启应用肯定是不能接受的。

尤其是在微服务架构下,我们的应用服务拆分的粒度很细,少则几十多则上百个服务,每个服务都会有一些自己特有或通用的配置。假如此时要改变通用配置,难道要我挨个改几百个服务配置?很显然这不可能。所以为了解决此类问题配置中心应运而生。

demo

修改8001

1.首先,修改 pom.xml 文件,引入 Nacos Config Starter。

 		<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

2.在应用的 /src/main/resources/bootstrap.properties 配置文件中配置 Nacos Config 元数据

spring.application.name=cloud-nacos-consumer-8001
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

3.修改application.properties,添加以下字段,(之前的配置方式)

shy.user.name=shy
shy.user.age=18

4.添加TestController

@RestController
public class TestController {


    @Value("${shy.user.name}")
    private String name;

    @Value("${shy.user.age}")
    private Integer age;

    @GetMapping("/test")
    public String test(){
        return name+age;
    }
}

5.访问:http://localhost:8001/test

这种配置方式是否有问题?

假设这个应用已经上线了,我们需要修改源代码中的配置,改好之后需要重新将应用打包又发布上去,还需要重新刷新才能看到,这很麻烦,如果当前应用在10台机器同时部署了,就相当于配置修改之后,要给10台机器重新部署一遍。

解决方案:我们可以将配置交给配置中心,如果配置中心一改,那么就可以动态全部修改!

2021-07-09 18:03:55.812  INFO 27260 --- [           main] b.c.PropertySourceBootstrapConfiguration : 
//定位数据源,NACOS-->cloud-nacos-consumer-8001.properties,配置中心中如果有这个配置文件,本地也会获取到,这个配置默认是当前的模块名+.properties
Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='cloud-nacos-consumer-8001.properties'}]}

在这里插入图片描述

测试:访问http://localhost:8001/test 配置依然生效

但是这样又有问题来了:每次在nacos修改之后只有重启服务才能使配置生效,这样还是有点麻烦

nacos动态刷新配置

想要动态获取配置很简单

只需要配合一个注解

@RefreshScope//刷新配置,使用这个注解可以动态刷新配置,无需重启服务打包发到服务器上

修改代码后需要重启一次服务,使得配置生效。

刷新:http://localhost:8001/test

修改配置的值

刷新

问题:

Nacos在做配置中心的时候,配置数据的交互模式是服务端推过来还是客户端主动拉的?客户端主动拉的

六、nacos命名空间与配置分组

1.命名空间*

问题 - 多环境多项目管理

问题1:

实际开发中,通常一个系统会准备

dev开发环境
test测试环境
prod生产环境。如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?

问题2:

一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境…那怎么对这些微服务配置进行管理呢?

环境隔离

开发,测试,生产:利用命名空间来做环境隔离

在这里插入图片描述

在这里插入图片描述

新建3个命名空间

在prop生产环境创建一个cloud-nacos-consumer-8001.properties

在这里插入图片描述

切换命名空间,修改bootstrap.properties

spring.application.name=cloud-nacos-consumer-8001
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=4823dd9d-8de0-466c-b88b-351d660690be

这里写的是命名空间的uuid。

重启服务,刷新:http://localhost:8001/test

微服务之间互相隔离配置

每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置

克隆配置:

在这里插入图片描述

选中点克隆

在这里插入图片描述

点击克隆即可

不同的微服务,只获取自己命名空间下的配置即可

修改consumer中的配置

在这里插入图片描述

修改之后发布,刷新:http://localhost:8001/test

2.配置集

所有的配置的集合

3.配置集ID*

配置集ID:类似文件名.

Data ID:类似文件名

在这里插入图片描述

4.配置分组*

默认所有的配置集都属于:DEFAULT_GROUP;

可以根据场景自定义组名,eg:1111,618,1212

在这里插入图片描述

修改bootstrap.properties

spring.application.name=cloud-nacos-consumer-8001
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=15d492ad-7b67-4c33-a2bc-f4e2a03dd95f
spring.cloud.nacos.config.group=1111

测试:重启服务,访问:http://localhost:8001/test

项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod

5.同时加载多个配置

随着业务 的不断壮大,微服务肯有很多的配置。我们不会把所有的配置都写在本地的配置文件中,这样配置文件又多又乱,不好维护,我们一般的做法就是拆分出不同的配置文件,比如和数据源有关的配置写在某一个配置文件中,就是说根据功能拆开。

编写application.yml

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: cloud-nacos-consumer-8001

server:
  port: 8001

抽取配置到nacos,

在这里插入图片描述
在这里插入图片描述

抽取完成后,把application.yml中的配置信息都注释掉

编写,bootstrap.properties

spring.application.name=cloud-nacos-consumer-8001
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=15d492ad-7b67-4c33-a2bc-f4e2a03dd95f
#spring.cloud.nacos.config.group=1111

#扩展的配置,是个list,可以写多个
#data-id:文件名
#group:分组
#refresh:是否动态刷新
spring.cloud.nacos.config.ext-config[0].data-id=port.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=spring.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

重启微服务,测试效果

访问:http://localhost:8001/test

观察日志:

Loading nacos data, dataId: 'port.yml', group: 'dev'
Loading nacos data, dataId: 'spring.yml', group: 'dev'
Loading nacos data, dataId: 'cloud-nacos-consumer-8001.properties', group: 'DEFAULT_GROUP'
Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='cloud-nacos-consumer-8001.properties'}, NacosPropertySource {name='spring.yml'}, NacosPropertySource {name='port.yml'}]}

项目上线后,会把所有的配置抽取到配置中心中。

6.总结

/**
 * 1、如何使用Nacos作为配置中心统一管理配置
 *
 * 1)、引入依赖,
 *         <dependency>
 *             <groupId>com.alibaba.cloud</groupId>
 *             <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 *         </dependency>
 * 2)、创建一个bootstrap.properties。
 *      spring.application.name=cloud-nacos-consumer-8001
 *      spring.cloud.nacos.config.server-addr=127.0.0.1:8848
 * 3)、需要给配置中心默认添加一个叫 数据集(Data Id)cloud-nacos-consumer-8001.properties。默认规则,应用名.properties
 * 4)、给 应用名.properties 添加任何配置
 * 5)、动态获取配置。
 *      @RefreshScope:动态获取并刷新配置
 *      @Value("${配置项的名}"):获取到配置。
 *      如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置。
 *
 * 2、细节
 *  1)、命名空间:配置隔离;
 *      默认:public(保留空间);默认新增的所有配置都在public空间。
 *      1、开发,测试,生产:利用命名空间来做环境隔离。
 *         注意:在bootstrap.properties;配置上,需要使用哪个命名空间下的配置,
 *         spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
 *      2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
 *
 *  2)、配置集:所有的配置的集合
 *
 *  3)、配置集ID:类似文件名。
 *      Data ID:类似文件名
 *
 *  4)、配置分组:
 *      默认所有的配置集都属于:DEFAULT_GROUP;
 *      1111,618,1212
 *
 * 项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod
 *
 * 3、同时加载多个配置集
 * 1)、微服务任何配置信息,任何配置文件都可以放在配置中心中
 * 2)、只需要在bootstrap.properties说明加载配置中心中哪些配置文件即可
 * 3)、@Value,@ConfigurationProperties。。。
 * 以前SpringBoot任何方法从配置文件中获取值,都能使用。
 * 配置中心有的优先使用配置中心中的,
 *
 *
 */

七、Nacos集群和持久化配置

官网:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL的存储。

Nacos支持三种部署模式

单机模式-用于测试和单机试用。
集群模式-用于生产环境,确保高可用。
多集群模式-用于多数据中心场景。

Windows

cmd startup.cmd或者双击startup.cmd文件

单机模式支持mysql

在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力。

Nacos持久化切换配置

Nacos默认自带的是嵌入式数据库derby,nacos的pom.xml中可以看出。

derby到mysql切换配置步骤:新建数据库nacos

  • MySQL中运行SQL文件,找到nacos-server-1.1.4\nacos\conf录下nacos-mysql.sql文件。
  • nacos-server-1.1.4\nacos\conf目录下找到application.properties,添加以下配置(按需修改对应值)。

在这里插入图片描述

再以单机模式启动nacos,nacos所有写嵌入式数据库的数据都写到了mysql。

启动Nacos,可以看到是个全新的空记录界面,以前是记录进derby。

八、Nacos之Linux版本安装!!!

预计需要,1个Nginx+3个nacos注册中心+1个mysql

请确保是在环境中安装使用:
64 bit OS Linux/Unix/Mac,推荐使用Linux系统。
64 bit JDK 1.8+
Maven 3.2.x+
3个或3个以上Nacos节点才能构成集群。

Nacos下载Linux版,地址:https://github.com/alibaba/nacos/releases/

配置

1.把下好的包托进xftp中,注意拖进opt文件夹下~

2.解压 : tar -zxvf nacos-server-2.0.0-ALPHA.1.tar.gz

3.ll 查看,opt文件夹下出现nacos文件夹

4.cp -r nacos /mynacos/

5.切换到nacos目录:cd nacos/

6.切换到当前目录的bin目录:cd bin

Nacos集群配置

集群配置步骤(重点)

1.Linux服务器上mysql数据库配置

SQL脚本在哪里 - 目录nacos/conf/nacos-mysql.sql

在这里插入图片描述

自己Linux机器上的Mysql数据库上运行

执行:vim nacos-mysql.sql

在这里插入图片描述

双击会话,再新会话中连接数据库

新建数据库:create database nacos_config

本地MySQL连接远程服务器MySQL,连接上之后找到这个sql文件运行即可

2.application.properties配置

回到前面的窗口,查看conf文件夹下内容。

复制一份application.properties :cp application.properties application.properties.init

修改:vim application.properties

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
#改成你自己的数据库和账号密码

:wq退出

3.Linux服务器上nacos的集群配置cluster.conf

复制一份cluster.conf.example:cp cluster.conf.example cluster.conf

修改:vim cluster.conf

在这里插入图片描述

这里我是有自己的服务器的,所以这里我写的是自己的公网ip~

改完之后,保存退出

4.编辑Nacos的启动脚本startup.sh,使它能够接受不同的启动端口

/mynacos/nacos/bin目录下有startup.sh

平时单机版的启动,都是./startup.sh即可

但是,集群启动,我们希望可以类似其它软件的shell命令,传递不同的端口号启动不同的nacos实例。
命令: ./startup.sh -p 3333表示启动端口号为3333的nacos服务器实例,和上一步的cluster.conf配置的一致。

在这里插入图片描述

复制一份startup.sh:cp startup.sh startup.sh.bk,就是备份保个底,以后要改哪个,先备份一下,以免改坏

vim startup.sh

在这里插入图片描述

这里自带的p不是port,我给他改了

拉到最下面,照着改:

在这里插入图片描述

执行方式 - startup.sh - p 端口号

5.Nginx的配置,由它作为负载均衡器

在这里插入图片描述

修改nginx.conf: vim nginx.conf

在这里插入图片描述

这里server中除了这几行一个都不要留,因为她有默认的匹配规则,有的优先级比你配的"/"高,导致你通过nginx访问nacos 的时候访问不到。这是我磕过的绊子。

6.截止到此处,1个Nginx+3个nacos注册中心+1个mysql

启动Nacos

./startup.sh -p 3333/4444/5555

在这里插入图片描述

这里我的服务器内存不够了,只能启动一台,T_T

用命令:netstat -ntlp查看端口占用情况,内存不够的话真实启动了一台~

查看nacos进程启动数:

ps -ef | grep nacos | grep -v grep | wc -l

在这里插入图片描述

启动nginx

切换到nginx目录下

在这里插入图片描述

./nginx -c /usr/local/nginx/conf/nginx.conf

在这里插入图片描述

ps -ef|grep nginx

测试

测试通过nginx,访问nacos - http://1.117.74.89:2222/nacos/#/login

登录成功~

新建一个配置测试

在这里插入图片描述

新建后,可在linux服务器的mysql新插入一条记录

查询config_info表

在这里插入图片描述

让微服务cloudalibaba-provider-payment9002启动注册进nacos集群 - 修改配置文件

在这里插入图片描述

九、Nacos与其他注册中心特性对比

在这里插入图片描述

Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

  • C在分布式系统中的所有数据备份,在同一时刻是否同样的值(等同于所有节点访问同一份最新的数据副本)
  • A在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(在分布式系统中,部分节点宕机依旧不影响系统整体的运行)
  • 分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做-出选择。

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。

Nacos支持AP和CP模式的切换

官方推荐使用A,即AP,保证其高可用

何时选择使用何种模式?

—般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。

如果需要在服务级别编辑或者存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

切换命令:

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP

Nacos服务发现实例模型

在这里插入图片描述

十、Nacos原理

推与拉模型

客户端与配置中心的数据交互方式其实无非就两种,要么推push,要么拉pull

推模型

客户端与服务端建立TCP长连接(长连接指建立SOCKET连接后不管是否使用都保持连接),当服务端配置数据有变动,立刻通过建立的长连接将数据推送给客户端。

优势:长链接的优点是实时性,一旦数据变动,立即推送变更数据给客户端,而且对于客户端而言,这种方式更为简单,只建立连接接收数据,并不需要关心是否有数据变更这类逻辑的处理。

弊端:长连接可能会因为网络问题,导致不可用,也就是俗称的假死。连接状态正常,但实际上已无法通信,所以要有的心跳机制KeepAlive来保证连接的可用性,才可以保证配置数据的成功推送。

拉模型

客户端主动的向服务端发请求拉配置数据,常见的方式就是轮询,比如每3s向服务端请求一次配置数据。

轮询的优点是实现比较简单。但弊端也显而易见,轮询无法保证数据的实时性,什么时候请求?间隔多长时间请求一次?都是不得不考虑的问题,而且轮询方式对服务端还会产生不小的压力。

长轮询

开篇我们就给出了答案,nacos采用的是客户端主动拉pull模型,应用长轮询(Long Polling)的方式来获取配置数据。

短轮询

不管服务端配置数据是否有变化,不停的发起请求获取配置,比如支付场景中前端JS轮询订单支付状态。

这样的坏处显而易见,由于配置数据并不会频繁变更,若是一直发请求,势必会对服务端造成很大压力。还会造成推送数据的延迟,比如:每10s请求一次配置,如果在第11s时配置更新了,那么推送将会延迟9s,等待下一次请求。

为了解决短轮询的问题,有了长轮询方案。

长轮询

长轮询可不是什么新技术,它不过是由服务端控制响应客户端请求的返回时间,来减少客户端无效请求的一种优化手段,其实对于客户端来说与短轮询的使用并没有本质上的区别。

客户端发起请求后,服务端不会立即返回请求结果,而是将请求挂起等待一段时间,如果此段时间内服务端数据变更,立即响应客户端请求,若是一直无变化则等到指定的超时时间后响应请求,客户端重新发起长链接。

在这里插入图片描述

OpenFeign服务调用

Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的。
Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

LB负载均衡(Load Balance)

集中式LB

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;

进程内LB

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。

Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

/**
 * 1、想要远程调用别的服务
 * 1)、引入open-feign
 * 2)、编写一个接口,告诉SpringCloud这个接口需要调用远程服务
 *   1、声明接口的每一个方法都是调用哪个远程服务的那个请求
 * 3)、开启远程调用功能
 */

远程调用接口一般放在feign包下

1)、引入open-feign

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

2)、在cloud-nacos-provider-9001编写controller

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProdController {

    @GetMapping("/testFeign/{name}")
    public String test(@PathVariable String name){

        return "用户:"+name+"调用了商品服务";
    }
}

3)、编写一个接口,告诉SpringCloud这个接口需要调用远程服务,声明接口的每一个方法都是调用哪个远程服务的那个请求

package com.xinzhi.cloudnacosconsumer8001.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

@FeignClient("cloud-nacos-provider-9001")
public interface TestFeign {
    @GetMapping("/testFeign/{name}")
    public String test(@PathVariable String name);
}

4)、开启远程调用功能,主启动类添加

@EnableFeignClients(basePackages = "com.xinzhi.cloudnacosconsumer8001.feign")

扫描feign包下的所有远程接口

5)、controller

import com.xinzhi.cloudnacosconsumer8001.feign.TestFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class TestController {

    @Autowired
    TestFeign feign;

    @Value("${shy.user.name}")
    private String name;

    @Value("${shy.user.age}")
    private Integer age;


    @GetMapping("/test")
    public String test(){
        return name+age;
    }

    @GetMapping("/feign")
    public String testFeign(){
        return feign.test("xinzhi");
    }
}

原理

通过 @EnableFeignCleints 触发 Spring 应用程序对 classpath 中 @FeignClient 修饰类的扫描

解析到 @FeignClient 修饰类后, Feign 框架通过扩展 Spring Bean Deifinition 的注册逻辑, 最终注册一个 FeignClientFacotoryBean 进入 Spring 容器

Spring 容器在初始化其他用到 @FeignClient 接口的类时, 获得的是 FeignClientFacotryBean 产生的一个代理对象 Proxy.

基于 java 原生的动态代理机制, 针对 Proxy 的调用, 都会被统一转发给 Feign 框架所定义的一个InvocationHandler , 由该 Handler 完成后续的 HTTP 转换, 发送, 接收, 翻译HTTP响应的工作

在这里插入图片描述

Sentinel详解及使用
gateway详解及使用
ribbon详解及原理


版权声明:本文为CSDN_SHY原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。