官方文档:https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html
我们所选用的组件:
SpringCloud Alibaba - Nacos:注册中心(服务发现/注册)
SpringCloud Alibaba - Nacos:配置中心(动态配置管理)
SpringCloud - Ribbon:负载均衡
SpringCloud - Feign:声明式 HTTP 客户端(调用远程服务)
SpringCloud Alibaba - Sentinel:服务容错(限流、降级、熔断)
SpringCloud - Gateway:API 网关(webflux 编程模式)
SpringCloud - Sleuth:调用链监控
SpringCloud Alibaba - Seata:原 Fescar,即分布式事务解决方案
Nacos 使用三步:
由于以后项目的依赖都有SpringCloud Alibaba,所以我们把依赖直接全部加到mall-common中。我们先加入一个版本管理。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>2.2.6.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
引入我们选好的组件的依赖即可。
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
dependencies>
接着去下载nacos-server,用于服务注册和发现。我们去官网下载nacos-server的压缩包。官网地址:https://github.com/alibaba/nacos/releases。下载完以后进入bin目录可以直接运行startup.cmd
,即可启动nacos-server。
运行成功。
如果想要使用nacos-server我们还需要配置nacos的地址。
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
在启动类上加一个注解,表示允许开启服务发现。
package cn.linstudy.coupon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
// 允许服务发现注解
@EnableDiscoveryClient
public class MallCouponApplication {
public static void main(String[] args) {
SpringApplication.run(MallCouponApplication.class, args);
}
}
配置成功后,我们就可以通过http://127.0.0.1:8848/nacos/,访问nacos可视化中心,账号密码都是nacos。
可以发现,服务已经注册上去了,这个服务名称就是我们这行配置的。
spring:
application:
name: mall-coupon
接下来我们依葫芦画瓢把其他服务也注册上去。
大功告成!
Feign 使用三步:
@EnableFeignClients
功能Feign 是一个声明式的 HTTP 客户端,它的目的就是让远程调用更加简单。Feign 提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。 Feign 整合了 Ribbon(负载均衡)和 Hystrix(服务熔断),可以让我们不再需要显式地使用这两个组件。 SpringCloudFeign 在 NetflixFeign 的基础上扩展了对 SpringMVC 注解的支持,在其实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon 自行封装服务调用客户端的开发量。
首先先导入依赖。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
<version>2.2.6.RELEASEversion>
dependency>
其次在启动类上写一个注解,开启openfeign。
package cn.linstudy.coupon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
// 允许服务发现注解
@EnableDiscoveryClient
// 允许远程调用注解
@EnableFeignClients
public class MallCouponApplication {
public static void main(String[] args) {
SpringApplication.run(MallCouponApplication.class, args);
}
}
调用远程服务的步骤:
写一个优惠券的类去测试。
// 测试openfrign
@RequestMapping("test")
public R memberCoupon(){
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("俺是优惠券");
return R.ok().put("coupons", Arrays.asList(couponEntity));
}
我们通过mall-member服务来远程调用mall-coupon服务。CouponFeignService会先去nacos找mall-coupon这个服务,再去找/coupon/coupon/test接口的方法。那么项目启动后,就会去扫描feign下的对应的方法。
package cn.linstudy.member.feign;
import cn.linstudy.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
// 告诉客户端我是远程调用客户端
@FeignClient("mall-coupon")
public interface CouponFeignService {
// 把需要调用的方法签名复制一份即可
@RequestMapping("/coupon/coupon/test")
R memberCoupon();
}
最后在MemberController中写一个测试类即可。
private CouponFeignService couponFeignService;
@RequestMapping("/coupons")
public R getCoupons(){
R r = couponFeignService.memberCoupon();
return R.ok().put("coupons",r.get("coupons"));
}
直接浏览器访问:http://localhost:8000/member/member/coupons
大功告成!
当然Ncacos也可以作为配置中心(好处是修改了配置无需重启项目,把配置交给nocaos统一管理),首先需要引入依赖。直接CV丢到mall-common中。
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
Spring Cloud Alibaba在/src/main/resources
下创建一个bootstrap.properties
来s配置文件中配置 Nacos Config 元数据。来配置两个属性:
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
然后启动nacos,将一些配置全部迁移到nacos中。
将mall-coupon中的配置从yaml转到properties,并添加到nacos配置中,发布即可。
命名空间用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group 或Data ID的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如Buy 或Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如database_url 配置和MQ_topic 配置。
如果我们把所有的配置都写在一个配置文件中,会显得配置文件很臃肿且不好维护,所以我们根据不同的功能来分开写。这个项目我们根据服务来隔离配置,首先先新建一个coupon优惠券命名空间。
接着迁移mybatis-plus相关配置。
将其他相关配置迁移就完成了。
最后需要在bootstrap.properties中配置读取多个配置文件。
#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[0].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true
#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[1].data-id=mybatis-plus.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[1].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[1].refresh=true
#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[2].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[2].refresh=true
启动完发现端口还是配置好的7000且没有报错,目前是成果配置了。
NacosConfigStarter 实现了 org.springframework.cloud.bootstrap.config.PropertySourceLocator
接口,并将优先级设置成了最高。 在 Spring Cloud 应用启动阶段,会主动从 Nacos Server 端获取对应的数据,并将获取到的数据转换成 PropertySource 且注入到 Environment 的 PropertySources 属性中,所以使用@Value 注解也能直接获取 Nacos Server 端配置的内容。
Nacos Config Starter 默认为所有获取数据成功的 Nacos 的配置项添加了监听功能,在监听到服务端配置发生变化时会实时触发 org.springframework.cloud.context.refresh.ContextRefresher
的 refresh 方法。如果需要对 Bean 进行动态刷新,请参照 Spring 和 Spring Cloud 规范。推荐给类添加@RefreshScope 或 @ConfigurationProperties 注解,
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而springcloud gateway作为 SpringCloud 官方推出的第二代网关框架,取代了 Zuul 网关。网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的API,以降低管理成本和安全风险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。Spring Cloud Gateway 旨在提供一种简单而有效的方式来对 API 进行路由,并为他们提供切面,例如:安全性,监控/指标 和弹性等。 官方文档地址: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.3.RELEASE/single/spring-cloud-gateway.html
Spring Cloud Gateway 特点:
我们首先先创建一个网关服务,同时网关服务也是需要交给nacos管理,所以也需要配置nacos相关配置,包括写注解配置和告知网关服务,nacos的地址。
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
spring:
application:
name: mall-gateway
server:
port: 88
在启动类上加一个注解。
package cn.linstudy.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class MallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(MallGatewayApplication.class, args);
}
}
引入依赖后就可以开始测试了。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
启动后会出现这个错误。
因为我们是网关层,不需要数据源相关配置,所以我们直接把他排除掉即可。在启动类上注解里面排除即可。
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
一启动,就会有惊喜!
这里会遇到一个bug,由于gateway与springboot-web会有冲突,我们需要把他排除掉,但是我们不可以在父项目中排除,因为其他的项目还需要用到,所以我们需要在引入mall-common
的地方排除掉springboot-web。
<dependency>
<groupId>cn.linstudygroupId>
<artifactId>mall-commonartifactId>
<version>0.0.1-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
exclusion>
exclusions>
dependency>
大功告成!
在application.yml中可以书写网关规则。
spring:
cloud:
gateway:
routes:
# 路由规则名称
- id: test_route
uri: https://www.baidu.com
# 断言,Query=url表示如果有url这个参数,且url的值等于baidu就跳到这个url
predicates:
- Query=url,baidu
# 路由规则名称
- id: qq_route
uri: https://www.qq.com
# 断言,Query=url表示如果有url这个参数,且url的值等于qq就跳到这个url
predicates:
- Query=url,qq
启动后输入