目录
一、前言
二、学习的内容
一、Nacos的服务注册/发现
1. 导依赖,nacos-discovery
java.lang.AbstractMethodError: org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.cho
2. 在application.yml中声明nacos服务器的ip地址和端口号,以及指定好服务的名称
3. 在启动类上面加上@EnableDiscoverClient
二、Feign的远程调用
1. 导依赖,open-feign
2. 写好声明式接口
3. 在启动类上面指定好声明式接口的位置
三、Nacos的配置中心
1. 导依赖 nacos-cofig
2. 在配置中心中按照需求进行配置,然后在application.yml文件中声明好nacos服务器的地址和服务名称必要时配好其它参数
3. 注意点
四、GeteWay网关
三、完成的进度
四、总结
一、前言
首先得了解微服务的这一套解决方案可以通过哪些组件进行实现,SpringCloud和SpringCloudAlibaba都是为了解决分布式中所出现的一些问题的,那这两者有什么区别呢,实现就是说SpringCloud是Spring官方的,而SpringCloudAlibaba的阿里巴巴公司的,其实SpringCloud有一些组件其实已经停止维护了,比如Eureka,而且许多组件配置起来很繁琐,不方便,并且没有提供可视化界面不易操作,而SpringCloudAlibaba提供的组件呢,步骤简单,配置容易,并且还有可视化界面,容易直接获取到信息。
微服务的组件很多,什么服务注册,配置中心,网关,服务容错(熔断降级),链路的追踪,远程调用,负载均衡等一些微服务组件,今天主要学习的是在微服务中最为基础的几个组件,分别是使用Nacos的服务注册/发现、Nacos的配置中心、Feign的远程调用、GeteWay网关。
二、学习的内容
首先,使用了Alibaba的这些组件,可以在公共类中导入alibaba的dependencies,导入这个的目的就是为了统一的依赖的版本的控制,就是之后使用alibaba的那些组件就不需要显式的写版本号了。当然也可以不写,不写的话就需要我们对其依赖需要标明其版本号。
dependencies依赖如下:
<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>
这个只是一个结构的参考,不但是cloud或者是cloudalibaba或者是boot都可以采用这种方式,注意要标明类型为pom然后scope为import。告诉maven这其实不是真正的依赖,只是为了继承的,为了声明好版本号的。具体的这个版本号你要根据boot的版本还有cloud的版本来选择合适的版本。我的boot版本是2.7.12的版本,cloud的版本是我在创建Boot项目的时候自动为我选择的,但是我使用alibaba的组件的依赖的时候,我是没有声明alibaba的dependencies的,所以我在项目中需要自己为依赖手动的显式指定好版本号,但是呢这个版本号,它比较的只能,通过我最初的boot版本idea可以自动的为我适配好alibaba组件的版本。
所以总结来说的话,对于这个依赖:
你最初使用了SpringBoot的初始化器来创建项目的话,在这里你选择了一个boot的版本号。
1. ok那么恭喜你,如果说你在之后使用面板选择的依赖的时候,那些版本号根本就不需要你去操心了,会自动适配的。就比如说我刚刚选择了OpenFeign的依赖,我并没有指定Cloud的版本,但是在创建好项目之后,查看这个pom文件就会发现,它自动的有cloud的dependencies的依赖来进行版本的控制,如下面所示:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这里啊,我没有在面板中选择有关alibaba的组件,所以啊在pom中也就没有alibaba的dependencies了,一旦我在最开始的时候如果说选择了的话,那么在pom中肯定也会有alibaba的dependencies的来进行版本控制的。
总结来说:就是得了解初始化器选择了依赖之后的一些动作
2. 如果你最开始啥都没选,不是说真的什么都没选,就是说你每选cloud、cloud-alibaba的组件,那么在之后的pom中也就是干干净净的,也就没有相关的dependencies了。那么就比较的难受,以后你导的任何的一个组件,你就需要指定版本号,其实这样就ok,没问题。当然咯你嘞比较懒并且你怕出错,那你就在最开始的时候加上dependencies,来进行的版本控制。就像最开始老师文档中给出的alibaba的denpencies一样,他就是为了要使用alibaba的组件所以一开始就加上了。
所以总总结:
其实嘞,就是两个:1. 你直接导组件依赖需要指定好版本号 2. 你先导入组件对应的总的dependencies,然后再导入组件的依赖,就可以不指定版本号了
然后就是使用boot的初始化器的话,其实它还是采取的首先加上dependencies的方案,只不过是idea可以自动的为你加上,另外如果选择的boot的初始化器创建项目,即使只选择了boot版本,后续选择组件的时候组件的版本号可以自动适配的。
一、Nacos的服务注册/发现
当然使用nacos之前得在本地机器上安装上nacos,然后开启服务。
如果开启的时候出现了报错,可能是安装的路径有中文。如果直接点击startup命令
那么就会出现启动服务之后,打开之后,就闪退了。解决办法是使用命令行进行单机启动
startup.cmd -m standalone命令进行启动
使用ip:端口/nacos就能访问可视化界面
步骤:
1. 导依赖,nacos-discovery
因为服务都是需要注册与发现的,所以这个依赖就写在common公共模块中
<!--nacos 服务注册/发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
<version>2.2.10-RC1</version>
</dependency>
至于为什么要排除ribbon是因为我使用feign远程调用的时候出了问题,出了下面这个报错
java.lang.AbstractMethodError: org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.cho
另外解决这个报错还要导入balance的依赖,这里只要导入就行了,其它不要管
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
2. 在application.yml中声明nacos服务器的ip地址和端口号,以及指定好服务的名称
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
application:
name: gulimall-coupon
3. 在启动类上面加上@EnableDiscoverClient
二、Feign的远程调用
1. 导依赖,open-feign
这个在最初的时候在创建每个服务的时候就选择了,因此就自动导入了
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 写好声明式接口
@FeignClient("gulimall-coupon")
public interface CouponFeign {
@GetMapping("/coupon/coupon/member/coupon")
public R memberCoupon();
}
3. 在启动类上面指定好声明式接口的位置
然后在controller中注入接口对象,就能直接调用了
三、Nacos的配置中心
nacos的配置中心是集中配置的,有很多方式。
大致的步骤:
1. 导依赖 nacos-cofig
<!-- nacos统一配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.10-RC1</version>
</dependency>
2. 在配置中心中按照需求进行配置,然后在application.yml文件中声明好nacos服务器的地址和服务名称必要时配好其它参数
其它参数可以是namespace或者是group等,具体看nacos配置中心中是怎么配的
这里我先简单的说一下几种配置方式:
1. 直接在nacos配置中心中配置一个和服务名同名的配置文件(也就是使用的默认的命名空间)
比如说在nacos配置中心中声明一个member服务的配置
配置了下面的内容:
在类路径下写一个bootstrap.properties文件,这个文件的优先级是高于application.properties文件的,所以只要配置中心中有内容那么一定获取到的是配置中心中的内容。
spring.cloud.nacos.config.server-addr=localhost:8848
spring.application.name=gulimall-member
写一个测试接口
使用@Value注解就能直接获取到配置文件中的值
另外这里使用@RefreshScope注解来来使得更新配置文件时,也可以获取获取到最新值
注意这里不能动态刷新,是没有加bootstrap依赖的缘故:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.5</version>
</dependency>
2. 在nacos配置中心中直接按照环境进行划分(使用自定义的命名空间)
其它什么依赖,还有测试都一样,就是配置中心发生变化,并且在bootstrap.properties文件中加上相应的配置
配置中心中,先在命名空间那里创建上几个命令空间:
然后在配置管理中在不同的命名空间中添加上配置:
然后再bootstrap.properties文件中,增添上namespace就行了
是用的什么样的环境就配置什么命名空间,命名空间的值可以从配置中心获取
然后就能根据不同的环境,获取到不同环境的配置了。
3. 按照服务进行划分,然后再根据环境划分(使用自定义的命名空间 + 使用分组)
就是创建服务名的命名空间,然后在这个空间里面创建不同环境的properties文件(使用组来进行区分)
然后在bootstrap.properties文件中,配好namespace和group就行了。
这就表示使用与微服务同名的命名空间中的test组下的配置文件
4. 对一个服务可以拆解application.yml文件(其实还是第三点只不过现在更细了)
这个简单,就是还是在3的基础上,还是那个命名空间里,选好组,一般就同一个组,然后分别创建好配置文件,比如说数据源的配置文件,MyBatisPlus的配置文件,其它配置文件。就是将原来的application.yml进行拆解。
然后在bootstrap.properties中配置ext-config
spring.cloud.nacos.config.server-addr=localhost:8848
spring.application.name=gulimall-member
spring.cloud.nacos.config.namespace=e43733fe-bb9e-4369-9809-d4030a7fefef
#spring.cloud.nacos.config.group=test
spring.cloud.nacos.config.ext-config[0].data-id=datasource.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=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true
spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true
3. 注意点
注意:除了这种ext配置,其它在配置中心中的配置文件都是和服务名同名的配置文件,这是规则,只有这样,才能找到配置文件,因为你其实在bootstrap.properties文件中是没有直接配置文件名的,而只是配置了一个命名空间,那到底是怎样找到命名空间中的配置文件的,就是使用服务名去找的,因为bootstrap中配置了服务名,因此可以映射到配置文件。
还有就是第三种方式和第四种是在开发中常用的,可以看作是最佳实践。
四、GeteWay网关
对于网关的话,有很多功能,鉴权、限流、路由都能干。网关其实就是进入微服务前的一道大门。
路由应该是网关的比较重要的功能了,我也只学了路由。
下面我就说一下路由:
路由其实就是找方向,把它引导到哪里去的功能,就是起到一个引导的作用。
路由的话大致就是一个路由的地址,还有断言规则以及过滤器大致就可以描述了。
路由地址就是最终去到的目标地址
断言规则就是如何去到目标地址,符合一定的规则才能去到对于的目标地址。
过滤器就是到达目标路径的时候,可以对请求进行过滤,也就是可以往请求中添加一些东西或者啥的,以及响应回来也可以过滤一遍。
就比如说下面这个例子:
当一个网址的url名称的参数,参数值为baidu时,就跳到百度网站
当参数值为jd时间,就跳到京东网站。
这个断言的规则是需要翻阅文档的,这个例子的断言规则就是
- Query=参数名,参数值
于是路由就这样配:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: jd_route
uri: https://www.jd.com
predicates:
- Query=url,jd
然后这个网关本身也是一个服务,所以也得注册到注册中心去。这样才能服务发现其它服务,另外通过注册中心可以查看到其它服务的健康状态,以及进行根据注册中心对各服务信息的获取实现负载均衡,所以说网关的很多功能其实基于注册中心的,所以得把网关注册进去。
注册到注册中心和其它服务注册到注册中心一样就那三步。下面是完整的yml配置:
spring:
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: jd_route
uri: https://www.jd.com
predicates:
- Query=url,jd
application:
name: geteway
三、完成的进度
注册中心、远程调用、配置中心、网关的简单例子都在电脑上面测了一遍。
四、总结
主要是具体几种微服务的组件的实操,知道具体怎样使用。通过实操加深微服务的理解。